本文為轉(zhuǎn)載,原文:Vue學(xué)習(xí)筆記入門(mén)篇——組件雜項(xiàng)
動(dòng)態(tài)組件
通過(guò)使用保留的 <'component'> 元素互墓,動(dòng)態(tài)地綁定到它的 is 特性,我們讓多個(gè)組件可以使用同一個(gè)掛載點(diǎn),并動(dòng)態(tài)切換:
<div id="app">
<component :is="currentView"></component>
</div>
var home = {
template:'<p>this is home</p>'
}
var posts = {
template:'<p>this is posts</p>'
}
var archive = {
template:'<p>this is archive</p>'
}
var app = new Vue({
el:'#app',
data:{
currentView:'home'
},
components:{
home:home,
posts:posts,
archive:archive
}
})
運(yùn)行結(jié)果:
在控制臺(tái)中修改app.currentView的值愕撰,界面會(huì)動(dòng)態(tài)發(fā)生改變。
如果把切換出去的組件保留在內(nèi)存中醋寝,可以保留它的狀態(tài)或避免重新渲染搞挣。為此可以添加一個(gè) keep-alive 指令參數(shù):
<keep-alive>
<component :is="currentView">
<!-- 非活動(dòng)組件將被緩存! -->
</component>
</keep-alive>
編寫(xiě)可復(fù)用組件
在編寫(xiě)組件時(shí)音羞,記住是否要復(fù)用組件有好處囱桨。一次性組件跟其它組件緊密耦合沒(méi)關(guān)系,但是可復(fù)用組件應(yīng)當(dāng)定義一個(gè)清晰的公開(kāi)接口嗅绰。
Vue 組件的 API 來(lái)自三部分 - props, events 和 slots :
Props 允許外部環(huán)境傳遞數(shù)據(jù)給組件
Events 允許從外部環(huán)境在組件內(nèi)觸發(fā)副作用
Slots 允許外部環(huán)境將額外的內(nèi)容組合在組件中
子組件索引
盡管有 props 和 events舍肠,但是有時(shí)仍然需要在 JavaScript 中直接訪(fǎng)問(wèn)子組件搀继。為此可以使用 ref 為子組件指定一個(gè)索引 ID。例如:
<div id="parent">
<user-profile ref="profile"></user-profile>
</div>
var parent = new Vue({ el: '#parent' })
// 訪(fǎng)問(wèn)子組件
var child = parent.$refs.profile
當(dāng) ref 和 v-for 一起使用時(shí)翠语,ref 是一個(gè)數(shù)組叽躯,包含相應(yīng)的子組件。
$refs 只在組件渲染完成后才填充肌括,并且它是非響應(yīng)式的点骑。它僅僅作為一個(gè)直接訪(fǎng)問(wèn)子組件的應(yīng)急方案——應(yīng)當(dāng)避免在模版或計(jì)算屬性中使用 $refs。
組件命名約定
當(dāng)注冊(cè)組件 (或者 props) 時(shí)谍夭,可以使用 kebab-case黑滴,camelCase,或 PascalCase紧索。
在 HTML 模版中跷跪,請(qǐng)使用 kebab-case 形式。
當(dāng)使用字符串模式時(shí)齐板,可以不受 HTML 的 case-insensitive 限制吵瞻。
components: {
'kebab-cased-component': { /* ... */ },
camelCasedComponent: { /* ... */ },
PascalCasedComponent: { /* ... */ }
}
如果組件未經(jīng) slot 元素傳遞內(nèi)容,你甚至可以在組件名后使用 / 使其自閉合.
<my-component/>
當(dāng)然甘磨,這只在字符串模版中有效橡羞。因?yàn)樽蚤]的自定義元素是無(wú)效的 HTML,瀏覽器原生的解析器也無(wú)法識(shí)別它济舆。
遞歸組件
組件在它的模板內(nèi)可以遞歸地調(diào)用自己卿泽,不過(guò),只有當(dāng)它有 name 選項(xiàng)時(shí)才可以:
name: 'unique-name-of-my-component'
當(dāng)你利用Vue.component全局注冊(cè)了一個(gè)組件, 全局的ID作為組件的 name 選項(xiàng)滋觉,被自動(dòng)設(shè)置.
Vue.component('unique-name-of-my-component', {
// ...
})
如果你不謹(jǐn)慎, 遞歸組件可能導(dǎo)致死循環(huán):
name: 'stack-overflow',
template: '<div><stack-overflow></stack-overflow></div>'
上面組件會(huì)導(dǎo)致一個(gè)錯(cuò)誤“max stack size exceeded”签夭,所以要確保遞歸調(diào)用有終止條件 (比如遞歸調(diào)用時(shí)使用 v-if 并讓他最終返回 false )。
內(nèi)聯(lián)模板
如果子組件有 inline-template 特性椎侠,組件將把它的內(nèi)容當(dāng)作它的模板第租,而不是把它當(dāng)作分發(fā)內(nèi)容。這讓模板更靈活我纪。
<div id="app">
<my-component inline-template>
<div>
<p>These are compiled as the component's own template.</p>
<p>Not parent's transclusion content.</p>
</div>
</my-component>
</div>
Vue.component('my-component',{
})
new Vue({
el:'#app'
})
運(yùn)行結(jié)果:
但是 inline-template 讓模板的作用域難以理解慎宾。最佳實(shí)踐是使用 template 選項(xiàng)在組件內(nèi)定義模板或者在 .vue 文件中使用 template 元素。
x-Templates
另一種定義模版的方式是在 JavaScript 標(biāo)簽里使用 text/x-template 類(lèi)型浅悉,并且指定一個(gè) id趟据。例如:
<script type="text/x-template" id="hello-world-template">
<p>Hello hello hello</p>
</script>
Vue.component('hello-world', {
template: '#hello-world-template'
})
這在有很多模版或者小的應(yīng)用中有用,否則應(yīng)該避免使用术健,因?yàn)樗鼘⒛0婧徒M件的其他定義隔離了汹碱。
對(duì)低開(kāi)銷(xiāo)的靜態(tài)組件使用 v-once
盡管在 Vue 中渲染 HTML 很快,不過(guò)當(dāng)組件中包含大量靜態(tài)內(nèi)容時(shí)荞估,可以考慮使用 v-once 將渲染結(jié)果緩存起來(lái)咳促,就像這樣:
Vue.component('terms-of-service', {
template: '\
<div v-once>\
<h1>Terms of Service</h1>\
... a lot of static content ...\
</div>\
'
})
其他
還有一些異步組件色难,和遞歸組件暫時(shí)先不介紹,等以后學(xué)習(xí)到webpack時(shí)在說(shuō)這個(gè)問(wèn)題等缀。
完
本文為原創(chuàng)枷莉,轉(zhuǎn)載請(qǐng)注明出處。
上一節(jié):Vue學(xué)習(xí)筆記入門(mén)篇——組件的內(nèi)容分發(fā)(slot)
返回目錄
下一節(jié):Vue學(xué)習(xí)筆記進(jìn)階篇——單元素過(guò)度