<div id="app">{{ name }}</div>
let vm = new Vue({
el: '#app',
data: {
name: 'aka allen'
}
})
el
,當我們不提供的時候,就必須呼叫 vm.$mount(el)
讓生命週期繼續往下走判斷是否有 template
,el
的部分就是 '#app'
或者自己下的其他名稱。let vm = new Vue({
template: `
<div id="replace">
<span> {{ name }} </span>
</div>
`,
data: {
name: 'aka allen'
}
})
再往下看生命週期,有 template
就會將他丟進 render
函式編譯,沒有 template
,就會抓元素的 outerHTML
來做為 template
編譯並渲染掛載,隨後回到我們平常使用 Vue 的方式。
vm.$mount(el)
( el 選擇器的部分自行替換成可辨識的 id or class 啥的 ) 就會看見內容被渲染了,並且可以發現若你有提供 template,裡面的內容是直接被替換掉的。以下是小範例,請自行琢磨。https://codepen.io/fiftybillionHuang/pen/NWNvJKV
隨便準備一份 HTML 來引入 Vue,或者隨便編輯器,其實我都直接 CodePen 啦。
引入 Vue 後,使用 Vue.component
物件來對組件做全域註冊,注意註冊的動作必須在new Vue
之前完成,沒這麼做,如果是使用開發版 Vue,會顯示 unknown custom element: <name-generator> - did you register the component correctly?
的錯誤訊息。
以下是全域組件的註冊方法,直接寫 Vue.component('',{})
就是在註冊了,必須傳入組件命名及 {}
形式的設定。
template
的部分使用了字符串模板,便於直接撰寫 HTML,而內容則是需要一個 div.class='rootDiv'
來做為根元素包覆,class 的名字是我隨便取的,只是用來表達根而已,什麼都不寫也可以,如果沒有最外層的 div
( 或其他標籤名稱也可 ) 而只有單單的 {{ name }}
將會顯示不出內容。若使用開發版 Vue,會有 Component template requires a root element
的錯誤訊息,切記,根元素只能有一個。
這邊我習慣可以在加上個 name 屬性。
Vue.component('name-generator', {
name: 'NameGenerator',
template: `
<div class='rootDiv'>
{{ name }}
</div>
`,
data () {
return {
name: 'aka allen'
}
}
});
// 全域組件註冊完接著才是 Vue 實例
new Vue ...
請注意,new Vue()
實例的 data 可以直接指定為一個物件,或函式返回的物件(沒有強制規定),但組件的部分則被明確規定為需要指定為 函式返回物件 的方式,請參考官網詳解 — #組件數據(必要) ,或者可參考這裡 ,經我自己實測, 如果把組件內的 data 直接寫成物件,貌似是過不了的樣子。另外,我們的 30 天組件命名將使用官網風格指南 。
<name-generator></name-generator>
components
,若是沒正確地將其丟進,也會出現類似 did you register the component correctly?
的錯誤訊息 ...let nameGeneratorHeHe = {
name: 'NameGeneratorHeHe',
template: `
<div>
{{ name }}
</div>
`,
data () {
return {
name: 'hehe'
}
}
}
new Vue({
el: '#app',
data: {
title: '鐵人賽第一天 - 組件'
},
components: {
nameGeneratorHeHe
}
});
<name-generator-he-he></name-generator-he-he>
script
部分完整的程式碼長這樣:<script>
Vue.component('name-generator', {
name: 'NameGenerator',
template: `
<div class='rootDiv'>
{{ name }}
</div>
`,
data() {
return {
name: 'aka allen'
}
}
});
let nameGeneratorHeHe = {
name: 'NameGeneratorHeHe',
template: `
<div>
{{ name }}
</div>
`,
data() {
return {
name: 'hehe'
}
}
};
new Vue({
el: '#app',
data: {
title: '鐵人賽第一天 - 組件'
},
components: {
nameGeneratorHeHe
}
});
</script>
<div id="app">
<header>{{ title }}</header>
<name-generator></name-generator>
<name-generator-he-he></name-generator-he-he>
</div>
重要 : 全域註冊的組件,仔細觀察他寫法是 Vue.component ... ,我們不去推敲源碼,但是邊依照我們對原生 JS 物件的認識,這可能是代表整個 Vue 類別被添加了這個組件的內容,因此在往後創造的所有 Vue 實例以及單文件組件 ( .vue 檔案 ) 都可以存取到這個組件,而相對的查看局部組件的寫法,是寫在某個 Vue 實例的 components 屬性中,因此在這個 Vue 實例以外範圍,是沒有辦法存取到此局部組件的,這點有機會的話在實作一個原生 JS 的例子給大家參考這個概念。
照這樣的概念我們可以知道,若是不常用的組件,通常就是作成局部的,而常用的再做成全域,比如每個頁面可能都需要某種相同的客製化按鈕,那這時你就可以使用全域註冊,就像我們的公用 CSS Class 一樣概念。
let a = 5;
let obj = {
a
};
console.log(obj.a) // 印出 5
// 因為ES2015定義物件成員的名稱和值若都是相同的,就可以只寫變數名稱,所以組件的寫法也可以學上面
let nameGeneratorHeHe = ......
new Vue({
el: '#app',
data: {
title: '鐵人賽第一天 - 組件'
},
components: {
// nameGeneratorHeHe: nameGeneratorHeHe
nameGeneratorHeHe
}
});
components: {
'get-a-name': nameGeneratorHeHe
}
<get-a-name></get-a-name>
https://codepen.io/fiftybillionHuang/pen/RwagEqp
這裡跟大家報告一下我目前的感受,目前為止覺得怪怪的,不知道到底是要程式碼多一些,還是中文敘述多一些,感覺怎麼做都怪怪的哈哈。預計是希望用大約 3~4 篇 ( 包含今天這篇,應該吧,搞不好越講越多 XD ) 的篇幅, 可以把 Prop + Slot + Event 的特性過一遍,外加帶大家逛一下 BootstrapVue 的部分並完成一些小功能,下一篇寫組件 Prop,感謝今日收看。
沒事也可以逛逛我們其他團隊成員的文章啦 ~~
eien_zheng: 前端小嘍嘍的Golang學習旅程_The journey of learning Golang 系列
PollyPO技術: 前端設計轉前端工程師-JS踩坑雜記 30 天 系列