iT邦幫忙

0

Vue 的this跟 js 的this有什麼不同?為什麼能直接存取屬性? componentInstance(元件實例)

  • 分享至 

  • xImage
  •  

在Vue中,this可以「直接讀取」內層的屬性,原因是因為Vue會在背後自動生成componentInstance,這方式讓使用者可以簡潔性的呼叫(少打字)。

話說這個componentInstance 是誰?

componentInstance(元件實例) 的來源

這個 componentInstance(元件實例) 是在 Vue 內部,當執行 .mount() 之後,Vue 框架根據你的元件選項(data(), methods, etc.)自動創建出來的一個複雜 JavaScript 物件,是一個元件的藍圖。當Vue準備渲染你的元件時,它會讀取這些藍圖,並在記憶體中建構出一個包含所有狀態和方法的實際運行時對象,這就是 componentInstance。

componentInstance 的 扁平化結構構

定義元件data() { return { message: 'hi' } }。
Vue 內部創建的componentInstance,
componentInstance.message = 'hi'。

定義元件methods: { update() { ... } }
Vue 內部創建的componentInstance,
componentInstance.update = function() { ... }

Vue 在創建這個實例時,做了一件很重要的事:它將 data、methods 等選項中的屬性,提升並直接掛載到了 componentInstance 的頂層。這就是 this 為什麼能直接存取 message 的原因。而componentInstance 是由 Vue 框架在執行階段創建出來的。這個實例將你定義在 data 裡面的屬性message直接拉到最頂層。將你定義在 methods 裡面的方法update直接拉到最頂層。

範例


<div id="counter">
</div>



const Counter = Vue.createApp({

  data() {

    return {

      number: 0 

    }

  },

  methods: {

    addOne() {

      this.number++; 

    }

  }

}).mount("#counter")
</script>

當你寫這段程式碼之後,這時候Vue內部大概會做這樣的操作。
建立一個componentInstance物件。
在物件componentInstance裡面,新增一個屬性number=0、新增一個函式addOne(){this.number++},強制把addOne(){}裡的this設定為componentInstance。
而這時候Counter常數就是一個根組件,也等同於componentInstance。

呼叫方式

依照上面範例,如果要執行addOne()。輸入Counter.addOne才是正確的。如果輸入Counter.data.addOne,則會出現錯誤。
因為Vue系統跑完後,並不是把data屬性整個刪除,而是將data()函式回傳物件裡面的屬性(例如 number)和 methods 裡面的函式(例如 addOne),都提升(或稱代理)到 Counter 物件(即元件實例)的最外層。
number 屬性:直接成為 Counter.number。
addOne 方法:直接成為 Counter.addOne。
也就是Vue在內部創建了一個扁平化的元件實例結構。
而data不能使用則是因為,data 和 methods 這兩個選項在元件實例化後,並沒有被保持為一個可供外部直接存取的 Counter.data 或 Counter.methods 物件。Vue 只是在內部使用它們來建構 Counter 實例。

但在實際的程式碼中,componentInstance並不是一個你可以直接使用的 JavaScript 變數名稱。

componentInstance 是一個概念性名稱,或者說是 Vue 內部原始碼中用來指代這個物件的變數名稱。它只存在於 Vue 框架的內部作用域。
對於外部的使用者程式碼來說,Vue 框架將這個實例物件回傳給你,你用 Counter 這個變數名來儲存和指稱它。

在上個程式碼範例,執行console.log(Counter.number);畫面會出現0。執行console.log(componentInstance.number);會出錯ReferenceError: componentInstance is not defined。


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言