Vue提供了一種內容分發技術,可將父組件中的內容傳遞給子組件的模板,實現方式參照了Web組件規範草案。spa
Vue內置了一個<slot>元素,能做爲插槽(slot)存在,而插槽內可包含文本、HTML片斷、組件等。如下面的btn組件爲例,其模板中包含一個<slot>元素,在DOM中爲btn組件添加了文本內容。code
<btn>提交</btn> <script> Vue.component("btn", { template: '<button><slot></slot></button>' }); </script>
渲染出的<button>元素會包含「提交」,即插槽被替換成了分發的內容,以下所示。component
<button>提交</button>
在插槽中容許添加默認的內容(即爲<slot>元素附加內容,以下所示),當父組件沒有傳遞內容時,它們就會被渲染。對象
Vue.component("btn", { template: '<button><slot>提交</slot></button>' });
具名插槽是指包含名稱的插槽,即指定了name特性的<slot>元素。當組件的模板中須要多個插槽時,就得經過名稱來加以區分。例若有一個page組件,包含三個<slot>元素,其中有兩個聲明瞭name特性,以下所示。blog
Vue.component("page", {
template: `<div>
<header><slot name="header"></slot></header>
<section><slot></slot></section>
<footer><slot name="footer"></slot></footer>
</div>`
});
若是要向具名插槽傳遞內容,那麼能夠在<template>元素上使用v-slot指令,並讓插槽名稱成爲它的參數,以下所示。ip
<page> <template v-slot:header> <h1>頭部</h1> </template> <p>內容</p> <template v-slot:footer> <h1>尾部</h1> </template> </page>
渲染出的DOM結構以下所示,分發的內容替換了對應的插槽。作用域
<div> <header> <h1>頭部</h1> </header> <section> <p>內容</p> </section> <footer> <h1>尾部</h1> </footer> </div>
全部沒有被包裹在帶v-slot指令的<template>元素中的內容(例如上面的<p>元素),都會傳遞給沒有名稱的插槽(即默認插槽)。io
注意,一個不帶name特性的<slot>元素,其實也有名稱,叫default。在v-slot指令中,也能夠對其進行指定,以下所示。編譯
<template v-slot:default> <p>內容</p> </template>
v-slot指令不只支持動態參數,還容許特殊的縮寫,即將參數前的v-slot:替換成#號,以下所示。function
<template v-slot:[obj.header]></template> <template #header></template>
在講解做用域插槽以前,須要要先了解一下編譯做用域。
1)編譯做用域
父組件模板中的內容都是在父級做用域中編譯的,而子組件模板中的內容都是在子級做用域中編譯的,即兩級做用域中的數據沒法相互訪問。下面以btn組件爲例,它的模板中包含一個插槽,並在數據對象中聲明瞭一個txt屬性。
Vue.component("btn", { data: function() { return { txt:"提交" }; }, template: '<button><slot></slot></button>' });
在爲btn組件提供插值形式的內容時,以下代碼所示,因爲當前做用域不存在txt屬性,所以會拋出錯誤。
<btn>{{txt}}</btn>
2)做用域插槽
這是一種特殊的插槽,其內容可訪問子組件中的數據,即把模板傳給插槽而不是渲染好的內容。仍是以btn組件爲例,與以前不一樣的是,爲<slot>元素自定義了一個txt特性,併爲其綁定數據對象的txt屬性,以下所示。
Vue.component("btn", { data: function() { return { txt:"提交" }; }, template: '<button><slot :txt="txt"></slot></button>' });
在使用btn組件時,須要爲v-slot指令傳遞一個變量,名稱可自定義(例如slots),其值是由插槽上的自定義特性所組成的對象。
<btn> <template v-slot:default="slots"> {{slots.txt}} </template> </btn>
當只提供了默認插槽時,可將v-slot指令轉移到組件上,而且可省略default名稱,以下所示。
<btn v-slot="slots"> {{slots.txt}} </btn>
注意,縮寫形式的默認插槽不能與具名插槽混用,由於這樣會致使做用域不明確。
<btn v-slot="slots"> {{slots.txt}} <template v-slot:custom></template> </btn>