iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 22
1
Modern Web

勇者鬥Vue龍系列 第 22

Vue.js Core 30天屠龍記(第22天): 組件註冊

組件有兩個方式可以註冊: 全域註冊及區域註冊。

全域註冊是直接在 Vue 物件中註冊組件,在整個 Vue.js 應用程式中都可以使用這個組件。

而區域註冊是在各個實體中的選項物件設定,這樣的設定方式只有這個實體才可以使用這個組件。

全域註冊

在註冊全域組件時要給予兩個參數: 組件名稱選項物件:

Vue.component('component-a', {
  // options
  template: `
    <div>a</div>
  `
});

這樣一來我們就可以之後的任何實體中使用這個組件:

var vm = new Vue({
  el: '#app'
});
<div id="app">
  <component-a></component-a>
</div>

不只是 new Vue 實體可以使用,連其他組件也可以使用:

Vue.component('component-a-copy', {
  template: `
    <component-a></component-a>
  `
});

區域註冊

全域註冊有個缺點: 不管有沒有使用到這個組件,只要使用全域註冊就一定會載入,因此使用全域註冊會將原本不需要的組件也載入進來,拖慢載入的時間。

所以針對某些特定實體設計的組件就可以用區域註冊的方式,註冊在需要它的組件中。

區域註冊會是一個選項物件:

const componentC = {
  // options
  template: `
    <div>c</div>
  `
};

這個物件可以由 components 這個選項物件屬性載入實體內:

var vm = new Vue({
  el: '#app',
  components: {
    'component-c': componentC
  }
});

除了 new Vue 實體外,也可以在組件中使用:

Vue.component('component-d', {
  components: {
    'component-c': componentC
  },
  template: `
    <component-c></component-c>
  `
});

componentskey 值是這個組件的名稱,而 value 值就是組件的選項物件

全域跟區域註冊的差別

這樣就完成註冊了,我們建立兩個實體看看這兩種註冊方法的差別:

Vue.component('component-a', {
  template: `
    <div>a</div>
  `
});

const componentC = {
  template: `
    <div>c</div>
  `
};

var vm = new Vue({
  el: '#app',
  components: {
    'component-c': componentC
  }
});

var vm2 = new Vue({
  el: '#app2'
});

我們有 vmvm2 兩個實體, 而使用的組件有 aca 是全域組件,而 c 是區域組件,只有 vm 有註冊 c 組件。

現在我們在頁面上配置 appapp2 ,兩個都載入 ac 組件:

<h2>app</h2>
<div id="app">
  <component-a></component-a>
  <component-c></component-c>
</div>
<h2>app2</h2>
<div id="app2">
  <component-a></component-a>
  <component-c></component-c>
</div>

結果如下:

https://ithelp.ithome.com.tw/upload/images/20181106/20107789Lv6YtfEu9a.png

可以看到因為 app2 沒有載入 c 區域組件,所以它不知道如何渲染 c 組件,就照原樣放在 HTML 上。

a 組件因為是全域組件,所以在任何的實體上都可以使用。

組件命名

組件的名稱需要依照 W3C 的客製標籤名稱(全部小寫並且需要包含連字符號( - ))來命名,避免發生衝突。

使用 kebab-case 命名

剛剛的例子都是使用 kebab-case 命名:

Vue.component('component-a', {  // kebab-case
  template: `
    <div>a</div>
  `
});

...

var vm = new Vue({
  el: '#app',
  components: {
    'component-c': componentC   // kebab-case
  }
});

kebab-case 會是全小寫,並且在字與字之間用連字符號( - )串聯。

使用 PascalCase

Vue.component('ComponentB', {   // PascalCase
  template: `
    <div>b</div>
  `
});

var vm = new Vue({
  el: '#app',
  components: {
    ComponentC: componentC  // PascalCase
  }
});

PascalCase 的字首大寫,並且每個字開頭都大寫。

ES2015+ 中可以把 componentC: componentC 改為 componentC ,這樣的設定方是代表 keyvalue 都是設定 componentC 的意思。

PascalCase 的名稱在 DOM 中使用只能轉換為 kebab-case 使用:

<div id="app">
  <component-b></component-b>
  <component-c></component-c>
</div>

DEMO

結語

本文介紹了組件的兩種註冊方式: 全域區域,以及兩種命名方式: kebab-casePascalCase

參考資料


上一篇
Vue.js Core 30天屠龍記(第21天): 組件間的資料傳輸
下一篇
Vue.js Core 30天屠龍記(第23天): `props` 屬性
系列文
勇者鬥Vue龍32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
0
oneword416
iT邦新手 5 級 ‧ 2019-01-21 16:09:08

嗨,請問關於使用PascalCase的範例是否有誤,字首應該為大寫?

已經更正文章了,謝謝大大的提醒。

0
tacodrem
iT邦新手 5 級 ‧ 2019-04-22 14:41:18

您好, 最近在練習Vue的時候看到此篇文章, 卻發現Vue-cli建出來的sample project裡面的code跟這篇有些不符合?

cli建出來後, 即使是PascalCase命名方式的component也可以直接使用PascalCase在DOM中渲染
https://ithelp.ithome.com.tw/upload/images/20190422/20109947NAFiBX7ydd.png

想問一下不知道這是不是Vue後來才更新的功能?

我的Vue-cli版本是3.5.3, 看package.json裡面寫的vue版本是2.6.10^

謝謝

由於 HTML 是不分大小寫的,因此在原生的 HTML 中不能使用 PascalCase 命名。

但在 SFC 及 String template 中會經過 Vue.js 做相關的處理,所以是可以使用 PascalCase 命名的。

這裡的範例有使用到 DOM Template ,為求統一,所以一律使用 kebab-case 做 template 中的引入元件的方式。

其實 Vue.js 官方的 Style Guide 是建議在專案的 Template 中使用 PascalCase 的,詳細資料請參考連結 ,因此專案級別的 Template 中要引用元件還是使用 PascalCase 吧。

tacodrem iT邦新手 5 級 ‧ 2019-04-23 09:11:34 檢舉

喔喔~!!
瞭解, 感謝回答!!

我要留言

立即登入留言