日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

詳解vue 組件注冊

瀏覽:183日期:2022-10-24 15:56:53

一、了解組件注冊的兩種方式

1.1 全局組件的注冊方法

//main.js import Vue from ’vue’ import App from ’./App’ import router from ’./router’ Vue.config.productionTip = false let Hello = { name: ’hello’, template: ’這是全局組件hello’ } Vue.component(’hello’, Hello) new Vue({ el: ’#app’, router, components: { App }, template: ’’ })

上面我們就通過Vue.component()注冊了一個全局組件hello,接下來分析源碼實現的時候也是基于這個例子來進行的。

1.2 局部組件的注冊

<template> <div id='app'> <img src='http://m.b3g6.com/bcjs/assets/logo.png'> <HelloWorld/> </div></template><script>import HelloWorld from ’./components/HelloWorld.vue’export default { name: ’App’, components:{ HelloWorld }}</script>

像這樣就注冊了一個HelloWorld的局部組件。

二、全局組件注冊的源碼

1.Vue初始化的時候,會調用initGlobalAPI()

//【代碼塊1】//代碼所在文件:src/core/global-api/index.jsexport function initGlobalAPI(Vue: GlobalAPI){ //...省略其他無關代碼 initAssetRegisters(Vue) //這個方法就是用于組件注冊的方法}

2.在initAssetRegisters()方法中執行組件的定義

//【代碼塊2】//代碼所在文件:src/core/global-api/assets.jsexport function initAssetRegister(Vue){ ASSET_TYPES.forEach(type=>{ //ASSET_TYPES包括component、directive、filter Vue[type] = function(id, definition){ //...一些條件判斷 if(type === ’component’ && isPlainObject(definition)){definition.name = definition.name || id definition = this.options._base.extend(definition) //將definition轉換為一個繼承于Vue的構造函數 } //...其他類型的處理 this.options[type+’s’][id] = definition //將這個構造函數掛載到Vue.options.components上 return definition } })}

此時,我們可以單步調試一下我們上面的例子,來看一下definition一開始是什么,以及執行掛載后Vue.options變成了什么樣子:

a.definition: 其實傳入的時候就是我們一開始定義的全局組件的具體內容

詳解vue 組件注冊

b.Vue.options: 可以看到我們定義的全局組件hello已經存在在Vue.options.components上了

詳解vue 組件注冊

3.實例化組件的時候,代碼會執行到Vue.prototype._init()上面

//【代碼塊3】//代碼所在文件:src/core/instance/init.jsVue.prototype._init = function(options){ //..省略其他無關代碼 if(options && options._isComponent){ //組件 initInternalComponent(vm, options) }else{ //非組件 vm.$options = mergeOptions( resolveConstructorOptions(vm.constructor), options||{}, vm ) }}

這里將自己定義的組件的options與Vue.options做了一個合并,并且賦值給了vm.$options,而通過【代碼塊2】我們可以知道全局組件的構造函數已經被放在了Vue.options.components上,所以經過這一步,vm.$options.components上面也有了全局組件的構造函數。所以現在在任意組件都能拿到全局組件,因為任何組件初始化的時候都會執行這個合并。

我們可以通過單步調試上面的例子看一下現在的vm.$options上面有些什么

詳解vue 組件注冊

4.在創建vnode的過程中,會執行_createElement方法

//【代碼塊4】//代碼所在文件:src/core/vdom/create-element.jsexport function _createElement(context, tag, data, children, normalization){ if(typeof tag === ’string’){ //... if(config.isReservedTag(tag)){ //...保留的html標簽 }else if(isDef(Ctor = resolveAsset(context.$options, ’component’, tag))){ //已經注冊過的全局組件 vnode = createComponent(Ctor, data, context, children, tag) }else{ //不是內置標簽也不是已經注冊過的組件,就創建一個全新的vnode vnode = new VNode(tag, data, children,undefined, undefined, context ) } }}

上面代碼中有一個比較重要的方法resolveAsset(),用于判斷在context.$options.compononts(即vm.$options.components)上面是否能找到這個組件的構造函數,如果能找到,返回這個構造函數,(具體方法見【代碼塊5】)根據【代碼塊3】我們可以知道如果這個組件是全局注冊的組件,那么我們就可以得到這個構造函數,并進入這個else if判斷,通過createComponent()得到vnode。

5.上面四步已經實現了整個流程,現在補充看一下resolveAsset()

//【代碼塊5】//代碼所在文件:src/core/utils/options.jsexport function resolveAsset(options, type, id, warnMissing){ //options即上面調用的時候傳入的context.$options, //由【代碼塊3】,vm.$options是由我們自定義的options以及Vue上的options合并而來的 //type現在是components const assets = options[type] // check local registration variations first if (hasOwn(assets, id)) return assets[id] const camelizedId = camelize(id) if (hasOwn(assets, camelizedId)) return assets[camelizedId] const PascalCaseId = capitalize(camelizedId) if (hasOwn(assets, PascalCaseId)) return assets[PascalCaseId] // fallback to prototype chain const res = assets[id] || assets[camelizedId] || assets[PascalCaseId] if (process.env.NODE_ENV !== ’production’ && warnMissing && !res) { warn( ’Failed to resolve ’ + type.slice(0, -1) + ’: ’ + id, options ) } return res }

先通過 const assets = options[type] 拿到 assets,然后再嘗試拿 assets[id],這里有個順序,先直接使用 id 拿,如果不存在,則把 id 變成駝峰的形式再拿,如果仍然不存在則在駝峰的基礎上把首字母再變成大寫的形式再拿,如果仍然拿不到則報錯。這樣說明了我們在使用 Vue.component(id, definition) 全局注冊組件的時候,id 可以是連字符、駝峰或首字母大寫的形式。

三、局部組件的注冊

1.extend()

組件在執行render()的時候,會執行createComponent函數,在這個函數里面會執行extend()函數生成一個構造函數,也是在這個extend()函數中,執行了一個options的合并

//【代碼塊5】//代碼所在文件:src/core/global-api/extend.jsVue.entend = function(extendOptions){ //... Sub.options = mergeOptions( Super.options, //Vue的options extendOptions //定義組件的那個對象 ) //...}

可以看出這里是將自己傳入的options(即定義組件的那個對象)與Vue.options合并,然后放到Sub.options上,同時,因為Sub.options上面合并了Vue的options,所以組件里面也可以拿到全局注冊的組件。

2.組件初始化

//【代碼塊6(同代碼塊3)】//代碼所在文件:src/core/instance/init.jsVue.prototype._init = function(options){ //.. if(options && options._isComponent){ initInternalComponent(vm, options) }else{ vm.$options = mergeOptions( resolveConstructorOptions(vm.constructor), options||{}, vm ) }}

組件初始化的過程中會進入if判斷語句,執行initInternalComponent()

3.initInternalComponent()

//【代碼塊7】//代碼所在文件:src/core/instance/init.jsexport function initInternalComponent (vm: Component, options: InternalComponentOptions) { const opts = vm.$options = Object.create(vm.constructor.options) //vm.constructor即為Sub,在代碼塊5中,我們已經將局部組件放在了Sub.options上 //所以這里將局部組件的構造函數放在了vm.$options上 //這樣在執行【代碼塊4】的時候同樣也能通過resolveAsset得到局部注冊組件的構造函數 const parentVnode = options._parentVnode opts.parent = options.parent opts._parentVnode = parentVnode //將componentOptions里面的別的屬性賦值給opts const vnodeComponentOptions = parentVnode.componentOptions opts.propsData = vnodeComponentOptions.propsData opts._parentListeners = vnodeComponentOptions.listeners opts._renderChildren = vnodeComponentOptions.children opts._componentTag = vnodeComponentOptions.tag if (options.render) { opts.render = options.render opts.staticRenderFns = options.staticRenderFns }}

四、總結

由于全局注冊的組件是將組件的構造函數擴展到了Vue.options.components上,而組件在初始化的時候都會將自身options與Vue.options合并,擴展到當前組件的vm.$options.components下,所以全局組件能在任意組件被使用。而局部注冊的組件是將組件的構造函數擴展到了當前組件的vm.$options.components下,所以只能在當前組件使用。

以上就是詳解vue 組件注冊的詳細內容,更多關于vue 組件注冊的資料請關注好吧啦網其它相關文章!

標簽: Vue
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
久久不卡日韩美女| 日本视频一区二区| 91精品xxx在线观看| 日韩国产在线一| 欧美日韩国产观看视频| 福利一区视频| 日韩高清在线不卡| 视频福利一区| 亚洲精品网址| 国产精东传媒成人av电影| 国产精品一区亚洲| 欧美www视频在线观看| 99久久久久国产精品| 亚洲欧美不卡| 国产精品一区二区99| 国产欧洲在线| 中文不卡在线| 国产一区二区三区视频在线| 国产资源在线观看入口av| 不卡一区2区| 日韩中文字幕一区二区高清99| 国产精品毛片aⅴ一区二区三区| 成人精品视频| 在线一区免费观看| 国产传媒在线观看| 免费日韩成人| 午夜久久美女| 国产精品啊啊啊| 国产一区亚洲| 国产毛片精品久久| 日本高清不卡一区二区三区视频| 久久av一区二区三区| 卡一卡二国产精品| 99精品视频精品精品视频| 日韩精品一区第一页| 国产精品igao视频网网址不卡日韩| 香蕉成人av| 日韩精品a在线观看91| 黄在线观看免费网站ktv| 蜜桃av一区二区| 美女福利一区二区三区| 亚洲欧洲专区| 久久激情中文| 国产三级一区| 亚洲欧洲一区二区天堂久久| 日韩黄色大片| 精品丝袜在线| 免费的成人av| 蜜臀av国产精品久久久久| 美女久久一区| 国产一区二区三区不卡视频网站 | 日韩精品一区第一页| 国产精品17p| 视频一区免费在线观看| 成人在线丰满少妇av| 日韩精品三级| 日韩视频一区二区三区在线播放免费观看| 欧美激情视频一区二区三区免费 | 美女av一区| 久久精品国产99久久| 久久精品午夜| 18国产精品| 综合一区av| 不卡在线一区二区| 欧美男人天堂| 日本va欧美va精品发布| 欧美日韩国产传媒| 不卡专区在线| 精品国产中文字幕第一页| 一区二区精品| 国产一级一区二区| 99视频精品全国免费| 不卡专区在线| 精品三级av在线导航| 国产日韩中文在线中文字幕| 综合欧美精品| 亚洲人妖在线| 视频在线观看91| 一区二区自拍| 欧美精品激情| 日韩电影免费在线观看| 国产精品久久久久久妇女 | 久久精品国产网站| 视频在线在亚洲| 午夜亚洲精品| 亚洲欧洲午夜| 一本色道久久精品| 亚洲二区三区不卡| 亚洲精品一区二区在线看| 91精品国产调教在线观看| 欧美精品高清| 精品久久不卡| 成人片免费看| 136国产福利精品导航网址| 999久久久精品国产| 婷婷综合五月| 快she精品国产999| 亚洲人成网站在线在线观看| 日本一区二区三区中文字幕| 在线看片日韩| 欧美视频二区| 麻豆一区二区三区| 精品视频高潮| 日韩成人亚洲| 欧美亚洲福利| 日韩区欧美区| 亚洲综合不卡| 免费在线观看成人| 亚洲精品综合| 国产乱码精品一区二区三区四区 | 黄色成人91| 亚洲美女91| 国产精品igao视频网网址不卡日韩 | 久久精品三级| 日韩电影免费网址| 欧美日韩国产一区二区三区不卡| 亚洲综合三区| 欧美日一区二区三区在线观看国产免| 麻豆视频一区二区| 蜜桃av.网站在线观看| 欧美粗暴jizz性欧美20| 日韩一区精品视频| 国产极品模特精品一二| 日韩精品首页| 亚洲激情av| 精品视频国内| 亚洲成人精选| 久久精品国产亚洲夜色av网站 | 国产在线|日韩| 国产精品一区二区三区av麻| 国产精品久久久久av电视剧| 成人羞羞视频在线看网址| 久久中文字幕二区| 欧美日韩1区2区3区| 在线免费观看亚洲| 国产女人18毛片水真多18精品| 激情久久一区二区| 不卡中文一二三区| 免费人成在线不卡| 久久三级毛片| 免费视频久久| 国产成人精品一区二区三区在线| 红桃视频亚洲| 久久精品国产99国产| 91久久久精品国产| 国产精品一区二区三区www| 激情偷拍久久| 国产精品久av福利在线观看| 欧美日韩精品一区二区视频| 日韩精品免费观看视频| 亚洲精品福利电影| 日韩高清不卡在线| 久久久久网站| 国产精品久久久免费| 美女网站一区| 韩国女主播一区二区三区| 亚洲精品护士| 婷婷久久一区| caoporn视频在线| 国产亚洲观看| 久久亚洲精品伦理| 在线中文字幕播放| 水蜜桃久久夜色精品一区的特点 | 日本视频在线一区| 欧美jjzz| 国产精品99精品一区二区三区∴| 蜜桃视频欧美| 精品视频国内| 日本欧美韩国一区三区| 狠狠色综合网| 青草国产精品久久久久久| 国产精品久久久久77777丨| 免费黄色成人| 国产a久久精品一区二区三区| 91精品久久久久久久久久不卡| 久久黄色影视| 亚洲激情精品| 免费毛片在线不卡| 久久激情网站| 欧美一区三区| 福利精品在线| av在线日韩| 国产v日韩v欧美v| 999精品在线| 日韩一区二区三区四区五区| 午夜国产欧美理论在线播放| 久久精品二区三区| 国产精品激情电影| 国产偷自视频区视频一区二区| 亚洲视频www| 亚洲精品无吗| 国产精品av久久久久久麻豆网| 日韩精品中文字幕吗一区二区| 婷婷久久免费视频| 亚洲一区av| 亚洲欧美高清| 一区二区电影在线观看| 日韩欧美另类一区二区| 日本成人精品| 蜜桃视频第一区免费观看|