Vue原始碼學習(十八):實現元件註冊(一)Vue.component()和Vue.extend()

養肥胖虎發表於2023-12-09

好傢伙,

 

0.完整程式碼已開源

https://github.com/Fattiger4399/analytic-vue.git

 

1.思路

1.1.什麼是元件化?

 

Vue 元件化是指將複雜的應用程式拆分成多個獨立的、可複用的元件,這些元件可以實現特定的功能或區域性功能。
元件化有助於提高開發效率、方便重複使用、簡化除錯步驟、提升專案可維護性,並便於多人協同開發。

 

以下是 Vue 元件化的好處:

 

程式碼複用,模組化,提高可維護性,便於 debug,適應性,提升效能(區域性更新),有利於團隊協

 

總之,Vue 元件化有助於提高開發效率、降低維護成本、提高應用程式效能,並便於團隊協作。它是 Vue 框架的核心概念,也是 Vue 應用開發的關鍵優勢之一。

 

 

1.2.在專案中元件化的使用

vue中使用元件的方式無非兩種,全域性元件與區域性元件

let vm = new Vue({
            el: "#app",
            data: {
                firstName: 'pang',
                lastName: 'hu'
            },
            component: {
                'my-button': {
                    template: `<button>區域性按鈕</button>`
                }
            }
        })
        Vue.component('my-button', {
            template: `<button>全域性按鈕</button>`
        })

本篇涉及Vue.component()和Vue.extend()

1. Vue.component:
   - 用於建立可複用的、獨立的、一次性(單例)的元件。
   - 建立的元件例項之間互不干擾,各自擁有獨立的例項狀態。
   - 無法繼承父元件的屬性和方法。

2. Vue.extend():
   - 用於建立可複用的、獨立的、多次使用的(原型鏈繼承)元件。
   - 建立的元件例項之間可以透過原型鏈繼承父元件的屬性和方法。
   - 相當於建立了一個新的元件類,可以理解為對父元件的擴充套件。

 

來vue的官網看一看

 

 

2.程式碼實現

global-api/index.js

Vue.component = function (id, componentDef) {
    componentDef.name = componentDef.name || id
    console.log(componentDef)

    console.log(this)
    componentDef = this.extend(componentDef) //返回一個例項
    console.log(componentDef)

    this.options.components[id] = componentDef
    console.log(this.options)
  }
Vue.extend = function (options) {
    let spuer = this
    const Sub = function vuecomponet(opts) { //opts 子元件的例項
      //
      //初始化
      this._init(opts)
    }
    //屬性如何處理??
    //子元件繼承父元件中的屬性Vue 類的繼承
    Sub.prototype = Object.create(spuer.prototype)
    //問題 子元件中this的執行
    Sub.prototype.constructor = Sub
    //重點,將父元件的屬性與子元件的屬性合併到一起
    Sub.options = mergeOptions(this.options, options)
    console.log(Sub.options)
    return Sub
  }

 

問題一:

此處為什麼要執行

Sub.prototype.constructor = Sub

答:

在 JavaScript 中,每個物件都有一個內部屬性 constructor,該屬性指向建立該物件的建構函式。

通常情況下,每個物件的 constructor 屬性都指向它自身對應的建構函式。

在 Vue 中,透過 Vue.extend 方法建立的子元件建構函式,它們的原型物件(Sub.prototype)預設情況下並沒有正確的 constructor 屬性,即 constructor 指向的是 Vue 而不是子元件自身。

這樣的話,在使用 new 運算子來建立子元件例項時,實際上會呼叫父元件的建構函式,導致建立子元件例項失敗。

因此,在這段程式碼中,使用 Sub.prototype.constructor = Sub 將子元件的 constructor 屬性設定為子元件自身,用於正確地設定子元件的建構函式。

這樣,在使用 new 運算子來建立子元件例項時,就可以正確地使用子元件的建構函式來建立例項了。

 

 

3.實現效果

 

 

相關文章