Vue進階之元件(二)
阿新 • • 發佈:2019-02-12
什麼是slot
官網API的說法是:
在使用元件時,常常要像這樣組合它們:
<app>
<app-header></app-header>
<app-footer></app-footer>
</app>注意兩點:
元件不知道它的掛載點會有什麼內容。掛載點的內容是由的父元件決定的。
元件很可能有它自己的模版。
為了讓元件可以組合,我們需要一種方式來混合父元件的內容與子元件自己的模板。這個過程被稱為 內容分發 (或 “transclusion” 如果你熟悉 Angular)。Vue.js 實現了一個內容分發 API ,參照了當前 Web元件規範草案,使用特殊的 元素作為原始內容的插槽。
先上一個demo
<div id="app">
<my-component>
<h1>Hello Vue.js!</h1>
</my-component>
<my-component></my-component>
</div>
<template id="myComponent">
<div class="content">
<h2> This is Component</h2>
<slot>如果沒有分發內容,則顯示slot中的內容</slot>
<p>Say Something....</p>
</div>
</template>
Vue.component('my-component', {
template: '#myComponent'
})
new Vue({
el: '#app'
})
這個模板中有兩個component
<my-component >
<h1>Hello Vue.js!</h1>
</my-component>
<my-component></my-component>
第一個中間寫了一行 h1
第二個中間沒有寫。
我們來看看執行結果:
也就是說,如果中間不寫分發內容的話,就會顯示slot中的內容(第二個component)。
用官方點的話來說,slot就是一個插槽。感覺只要component中寫了東西,就不會顯示slot了
就是插在component中,但是顯示在什麼地方呢?
具名的slot
下面這行程式碼在template中聲明瞭具名的插槽。
<template id="dialog-template">
<div class="dialogs">
<div class="dialog" v-bind:class="{ 'dialog-active': show }">
<div class="dialog-content">
<div class="close rotate">
<span class="iconfont icon-close" @click="close"></span>
</div>
<!-- 具名的插槽 -->
<slot name="header"></slot>
<slot name="body"></slot>
<slot name="footer"></slot>
</div>
</div>
<div class="dialog-overlay"></div>
</div>
</template>
完整程式碼,以及js
<div id="app">
<modal-dialog v-bind:show.sync="show">
<!-- 具名插槽的使用 header-->
<header class="dialog-header" slot="header">
<h1 class="dialog-title">提示資訊</h1>
</header>
<!-- 具名插槽的使用 body-->
<div class="dialog-body" slot="body">
<p>你想在對話方塊中放什麼內容都可以!</p>
<p>你可以放一段文字,也可以放一些表單,或者是一些圖片。</p>
</div>
<!-- 具名插槽的使用 footer-->
<footer class="dialog-footer" slot="footer">
<button class="btn" @click="closeDialog">關閉</button>
</footer>
</modal-dialog>
<button class="btn btn-open" @click="openDialog">開啟對話方塊</button>
</div>
<template id="dialog-template">
<div class="dialogs">
<div class="dialog" v-bind:class="{ 'dialog-active': show }">
<div class="dialog-content">
<div class="close rotate">
<span class="iconfont icon-close" @click="close"></span>
</div>
<!-- 具名的插槽 -->
<slot name="header"></slot>
<slot name="body"></slot>
<slot name="footer"></slot>
</div>
</div>
<div class="dialog-overlay"></div>
</div>
</template>
</body>
Vue.component('modal-dialog', {
template: '#dialog-template',
props: ['show'],
methods: {
close: function() {
this.show = false
}
}
})
new Vue({
el: '#app',
data: {
show: false
},
methods: {
openDialog: function() {
this.show = true
},
closeDialog: function() {
this.show = false
}
}
})
首先說一下:
v-bind:show.sync="show"
<js>
openDialog: function() {
this.show = true
},
closeDialog: function() {
this.show = false
}
是為了繫結對話方塊的顯示與否,只是不知道為什麼要用v-bind:show.sync,非同步模式?
最後總結
感覺slot很適合用來作為頁面的佈局,導航頭、內容、尾部導航。