尤川豪   ·  3年前
445 貼文  ·  275 留言

Vue 的 component 是怎麼直接使用 custom element 來執行的?

比方這樣定義 component

// Define a new component called button-counter
Vue.component('button-counter', {
  data: function () {
    return {
      count: 0
    }
  },
  template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})

綁定好作用空間之後

new Vue({ el: '#components-demo' })

便可直接這樣寫 html

<div id="components-demo">
  <button-counter></button-counter>
</div>

背後原理是?

https://developer.mozilla.org/zh-CN/docs/Web/Web_Components/Using_custom_elements

https://developers.google.com/web/fundamentals/web-components/customelements?hl=zh-tw

https://developers.google.com/web/fundamentals/web-components/shadowdom?hl=zh-tw

最好的說明應該是官方的這個文件:

https://vuejs.org/v2/guide/#Relation-to-Custom-Elements


大概看了一下 custom element 應該是 web 標準協定了吧

內容真的很酷 javascript 的 object property 可以跟 html element attribute 互相對應

property 的改變 也會自動去更新 attribute

然後 attribute 的改變也有相關的 reaction callbacks 可以監聽使用

超酷的!


另外應該會用到 ES6 get set syntax 我也是第一次聽說,還有這種東西呀!

不過這好像只是 ES5 Object.defineProperty 的 syntax sugar 而已 哈哈

https://stackoverflow.com/questions/38960384/what-is-alternative-before-es6-of-getter-method-existing-in-es6


Shadow DOM

web component 的 shadow DOM 重點是 Self-Contained 讓 css 那些不要跟其他元素混在一起。

這跟 React 說的 virtual DOM 不一樣,那個主要是為了 render 前可以自行做 diff 演算法,更有效率,不要搞混了。

  • Isolated DOM
  • Scoped CSS
  • Composition
  • Simplifies CSS

With shadow DOM, you create a scoped DOM tree that's attached to the element, but separate from its actual children. This scoped subtree is called a shadow tree. The element it's attached to is its shadow host

The <slot> Element

Shadow DOM composes different DOM trees together using the <slot> element. Slots are placeholders inside your component that users can fill with their own markup. By defining one or more slots, you invite outside markup to render in your component's shadow DOM. Essentially, you're saying "Render the user's markup over here".

這個超酷的欸. 平常 slots 是按照順序依序填入 shadow DOM tree 吧。但如果有用 name 屬性,就會按照 name 填入 named slots 囉。


Vue 大概就是用了以上技術吧。不過 <example-component> 最後 render 完應該會出現在最後的 Flattened DOM tree 裡面,不過 Vue 是沒有出現的,不知道為什麼?

最後 render 完也沒看到 <slot> 元素出現,不知道為什麼?

算了,都用了 Vue 就先當作,Vue 提供的抽象化,後面原理先不管囉~

  分享   共 2,543 次點閱
按了喜歡:
共有 0 則留言
還沒有人留言。歡迎分享您的觀點、或是疑問。
您的留言
尤川豪
445 貼文  ·  275 留言

Devs.tw 是讓工程師寫筆記、網誌的平台。隨手紀錄、寫作,方便日後搜尋!

歡迎您一起加入寫作與分享的行列!

查看所有文章