本文為轉載,原文:Vue學習筆記入門篇——組件雜項
動態組件
通過使用保留的 <'component'> 元素,動態地綁定到它的 is 特性,我們讓多個組件可以使用同一個掛載點,并動態切換:
<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
}
})
運行結果:
在控制臺中修改app.currentView的值,界面會動態發生改變。
如果把切換出去的組件保留在內存中,可以保留它的狀態或避免重新渲染。為此可以添加一個 keep-alive 指令參數:
<keep-alive>
<component :is="currentView">
<!-- 非活動組件將被緩存! -->
</component>
</keep-alive>
編寫可復用組件
在編寫組件時,記住是否要復用組件有好處。一次性組件跟其它組件緊密耦合沒關系,但是可復用組件應當定義一個清晰的公開接口。
Vue 組件的 API 來自三部分 - props, events 和 slots :
Props 允許外部環境傳遞數據給組件
Events 允許從外部環境在組件內觸發副作用
Slots 允許外部環境將額外的內容組合在組件中
子組件索引
盡管有 props 和 events,但是有時仍然需要在 JavaScript 中直接訪問子組件。為此可以使用 ref 為子組件指定一個索引 ID。例如:
<div id="parent">
<user-profile ref="profile"></user-profile>
</div>
var parent = new Vue({ el: '#parent' })
// 訪問子組件
var child = parent.$refs.profile
當 ref 和 v-for 一起使用時,ref 是一個數組,包含相應的子組件。
$refs 只在組件渲染完成后才填充,并且它是非響應式的。它僅僅作為一個直接訪問子組件的應急方案——應當避免在模版或計算屬性中使用 $refs。
組件命名約定
當注冊組件 (或者 props) 時,可以使用 kebab-case,camelCase,或 PascalCase。
在 HTML 模版中,請使用 kebab-case 形式。
當使用字符串模式時,可以不受 HTML 的 case-insensitive 限制。
components: {
'kebab-cased-component': { /* ... */ },
camelCasedComponent: { /* ... */ },
PascalCasedComponent: { /* ... */ }
}
如果組件未經 slot 元素傳遞內容,你甚至可以在組件名后使用 / 使其自閉合.
<my-component/>
當然,這只在字符串模版中有效。因為自閉的自定義元素是無效的 HTML,瀏覽器原生的解析器也無法識別它。
遞歸組件
組件在它的模板內可以遞歸地調用自己,不過,只有當它有 name 選項時才可以:
name: 'unique-name-of-my-component'
當你利用Vue.component全局注冊了一個組件, 全局的ID作為組件的 name 選項,被自動設置.
Vue.component('unique-name-of-my-component', {
// ...
})
如果你不謹慎, 遞歸組件可能導致死循環:
name: 'stack-overflow',
template: '<div><stack-overflow></stack-overflow></div>'
上面組件會導致一個錯誤“max stack size exceeded”,所以要確保遞歸調用有終止條件 (比如遞歸調用時使用 v-if 并讓他最終返回 false )。
內聯模板
如果子組件有 inline-template 特性,組件將把它的內容當作它的模板,而不是把它當作分發內容。這讓模板更靈活。
<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'
})
運行結果:
但是 inline-template 讓模板的作用域難以理解。最佳實踐是使用 template 選項在組件內定義模板或者在 .vue 文件中使用 template 元素。
x-Templates
另一種定義模版的方式是在 JavaScript 標簽里使用 text/x-template 類型,并且指定一個 id。例如:
<script type="text/x-template" id="hello-world-template">
<p>Hello hello hello</p>
</script>
Vue.component('hello-world', {
template: '#hello-world-template'
})
這在有很多模版或者小的應用中有用,否則應該避免使用,因為它將模版和組件的其他定義隔離了。
對低開銷的靜態組件使用 v-once
盡管在 Vue 中渲染 HTML 很快,不過當組件中包含大量靜態內容時,可以考慮使用 v-once 將渲染結果緩存起來,就像這樣:
Vue.component('terms-of-service', {
template: '\
<div v-once>\
<h1>Terms of Service</h1>\
... a lot of static content ...\
</div>\
'
})
其他
還有一些異步組件,和遞歸組件暫時先不介紹,等以后學習到webpack時在說這個問題。
完
本文為原創,轉載請注明出處。
上一節:Vue學習筆記入門篇——組件的內容分發(slot)
返回目錄
下一節:Vue學習筆記進階篇——單元素過度