电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

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

詳解vue 組件注冊

瀏覽:97日期: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://www.hdgsjgj.cn/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
相關文章:
主站蜘蛛池模板: 智能垃圾箱|垃圾房|垃圾分类亭|垃圾分类箱专业生产厂家定做-宿迁市传宇环保设备有限公司 | 汽车整车综合环境舱_军标砂尘_盐雾试验室试验箱-无锡苏南试验设备有限公司 | 不干胶标签-不干胶贴纸-不干胶标签定制-不干胶标签印刷厂-弗雷曼纸业(苏州)有限公司 | 2025黄道吉日查询、吉时查询、老黄历查询平台- 黄道吉日查询网 | 深圳标识制作公司-标识标牌厂家-深圳广告标识制作-玟璟广告-深圳市玟璟广告有限公司 | 氢氧化钾厂家直销批发-济南金昊化工有限公司 | 紫外可见光分光度计-紫外分光度计-分光光度仪-屹谱仪器制造(上海)有限公司 | 冰晶石|碱性嫩黄闪蒸干燥机-有机垃圾烘干设备-草酸钙盘式干燥机-常州市宝康干燥 | 筛分机|振动筛分机|气流筛分机|筛分机厂家-新乡市大汉振动机械有限公司 | 篮球架_乒乓球台_足球门_校园_竞技体育器材_厂家_价格-沧州浩然体育器材有限公司 | 水厂污泥地磅|污泥处理地磅厂家|地磅无人值守称重系统升级改造|地磅自动称重系统维修-河南成辉电子科技有限公司 | 首页 - 张店继勇软件开发工作室 兰州UPS电源,兰州山特UPS-兰州万胜商贸 | 招商帮-一站式网络营销服务|搜索营销推广|信息流推广|短视视频营销推广|互联网整合营销|网络推广代运营|招商帮企业招商好帮手 | 清水混凝土修复_混凝土色差修复剂_混凝土色差调整剂_清水混凝土色差修复_河南天工 | 玻璃钢型材-玻璃钢风管-玻璃钢管道,生产厂家-[江苏欧升玻璃钢制造有限公司] | 合肥卓创建筑装饰,专业办公室装饰、商业空间装修与设计。 | 申江储气罐厂家,储气罐批发价格,储气罐规格-上海申江压力容器有限公司(厂) | TPE塑胶原料-PPA|杜邦pom工程塑料、PPSU|PCTG材料、PC/PBT价格-悦诚塑胶 | 制氮设备_PSA制氮机_激光切割制氮机_氮气机生产厂家-苏州西斯气体设备有限公司 | 石磨面粉机|石磨面粉机械|石磨面粉机组|石磨面粉成套设备-河南成立粮油机械有限公司 | 自进式锚杆-自钻式中空注浆锚杆-洛阳恒诺锚固锚杆生产厂家 | 仿真茅草_人造茅草瓦价格_仿真茅草厂家_仿真茅草供应-深圳市科佰工贸有限公司 | 首页_中夏易经起名网| 上海平衡机-单面卧式动平衡机-万向节动平衡机-圈带动平衡机厂家-上海申岢动平衡机制造有限公司 | 模具硅橡胶,人体硅胶,移印硅胶浆厂家-宏图硅胶科技 | 领先的大模型技术与应用公司-中关村科金| 粘度计NDJ-5S,粘度计NDJ-8S,越平水分测定仪-上海右一仪器有限公司 | 成都竞价托管_抖音代运营_网站建设_成都SEM外包-成都智网创联网络科技有限公司 | 知名电动蝶阀,电动球阀,气动蝶阀,气动球阀生产厂家|价格透明-【固菲阀门官网】 | 影合社-影视人的内容合作平台 | 【甲方装饰】合肥工装公司-合肥装修设计公司,专业从事安徽办公室、店面、售楼部、餐饮店、厂房装修设计服务 | 编织人生 - 权威手工编织网站,编织爱好者学习毛衣编织的门户网站,织毛衣就上编织人生网-编织人生 | 合肥废气治理设备_安徽除尘设备_工业废气处理设备厂家-盈凯环保 合肥防火门窗/隔断_合肥防火卷帘门厂家_安徽耐火窗_良万消防设备有限公司 | 点焊机-缝焊机-闪光对焊机-电阻焊设备生产厂家-上海骏腾发智能设备有限公司 | 沈阳庭院景观设计_私家花园_别墅庭院设计_阳台楼顶花园设计施工公司-【沈阳现代时园艺景观工程有限公司】 | 整车VOC采样环境舱-甲醛VOC预处理舱-多舱法VOC检测环境仓-上海科绿特科技仪器有限公司 | 时代北利离心机,实验室离心机,医用离心机,低速离心机DT5-2,美国SKC采样泵-上海京工实业有限公司 工业电炉,台车式电炉_厂家-淄博申华工业电炉有限公司 | 生物风-销售载体,基因,质粒,ATCC细胞,ATCC菌株等,欢迎购买-百风生物 | 中医治疗皮肤病_潍坊银康医院「山东」重症皮肤病救治平台 | 打包钢带,铁皮打包带,烤蓝打包带-高密市金和金属制品厂 | LED太阳能中国结|发光红灯笼|灯杆造型灯|节日灯|太阳能灯笼|LED路灯杆装饰造型灯-北京中海轩光电 |