本篇資料來於官方文檔:app
http://cn.vuejs.org/guide/components.html#u4F7F_u7528_Slot__u5206_u53D1_u5185_u5BB9
ide
本文是在官方文檔的基礎上,更加細緻的說明,代碼更多更全。ui
簡單來講,更適合新手閱讀this
(二十八)Slot分發內容spa
①概述:
簡單來講,假如父組件須要在子組件內放一些DOM,那麼這些DOM是顯示、不顯示、在哪一個地方顯示、如何顯示,就是slot分發負責的活。.net
②默認狀況下
父組件在子組件內套的內容,是不顯示的。code
例如代碼:component
- <div id="app">
- <children>
- <span>12345</span>
-
- </children>
- </div>
- <script>
- var vm = new Vue({
- el: '#app',
- components: {
- children: { //這個無返回值,不會繼續派發
- template: "<button>爲了明確做用範圍,因此使用button標籤</button>"
- }
- }
- });
- </script>
顯示內容是一個button按鈕,不包含span標籤裏面的內容;
③單個slot
簡單來講,只使用這個標籤的話,能夠將父組件放在子組件的內容,放到想讓他顯示的地方。
- <div id="app">
- <children>
- <span>12345</span>
-
- </children>
- </div>
- <script>
- var vm = new Vue({
- el: '#app',
- components: {
- children: { //這個無返回值,不會繼續派發
- template: "<button><slot></slot>爲了明確做用範圍,因此使用button標籤</button>"
- }
- }
- });
- </script>
例如這樣寫的話,結果是:
<button><span>12345</span>爲了明確做用範圍,因此使用button標籤</button>
即父組件放在子組件裏的內容,插到了子組件的<slot></slot>位置;
注意,即便有多個標籤,會一塊兒被插入,至關於用父組件放在子組件裏的標籤,替換了<slot></slot>這個標籤。
④具名slot
將放在子組件裏的不一樣html標籤放在不一樣的位置
父組件在要分發的標籤裏添加 slot=」name名」 屬性
子組件在對應分發的位置的slot標籤裏,添加name=」name名」 屬性,
而後就會將對應的標籤放在對應的位置了。
示例代碼:
- <div id="app">
- <children>
- <span slot="first">12345</span>
- <span slot="second">56789</span>
-
- </children>
- </div>
- <script>
- var vm = new Vue({
- el: '#app',
- components: {
- children: { //這個無返回值,不會繼續派發
- template: "<button><slot name='first'></slot>爲了明確做用範圍,<slot name='second'></slot>因此使用button標籤</button>"
- }
- }
- });
- </script>
顯示結果爲:(爲了方便查看,已手動調整換行)
<button>
<span slot="first">12345</span>
爲了明確做用範圍,
<span slot="second">56789</span>
因此使用button標籤
</button>
⑤分發內容的做用域:
被分發的內容的做用域,根據其所在模板決定,例如,以上標籤,其在父組件的模板中(雖然其被子組件的children標籤所包括,但因爲他不在子組件的template屬性中,所以不屬於子組件),則受父組件所控制。
示例代碼:
- <div id="app">
- <children>
- <span slot="first" @click="tobeknow">12345</span>
- <span slot="second">56789</span>
-
- </children>
- </div>
- <script>
- var vm = new Vue({
- el: '#app',
- methods: {
- tobeknow: function () {
- console.log("It is the parent's method");
- }
- },
- components: {
- children: { //這個無返回值,不會繼續派發
- template: "<button><slot name='first'></slot>爲了明確做用範圍,<slot name='second'></slot>因此使用button標籤</button>"
- }
- }
- });
- </script>
當點擊文字12345的區域時(而不是按鈕所有),會觸發父組件的tobeknow方法。
可是點擊其餘區域時則沒有影響。
官方教程是這麼說的:
父組件模板的內容在父組件做用域內編譯;子組件模板的內容在子組件做用域內編譯
⑥當沒有分發內容時的提示:
假如父組件沒有在子組件中放置有標籤,或者是父組件在子組件中放置標籤,但有slot屬性,而子組件中沒有該slot屬性的標籤。
那麼,子組件的slot標籤,將不會起到任何做用。
除非,該slot標籤內有內容,那麼在無分發內容的時候,會顯示該slot標籤內的內容。
如示例代碼:
- <div id="app">
- <children>
- <span slot="first">【12345】</span>
-
- </children>
- </div>
- <script>
- var vm = new Vue({
- el: '#app',
- components: {
- children: { //這個無返回值,不會繼續派發
- template: "<div><slot name='first'><button>【若是沒有內容則顯示我1】</button></slot>爲了明確做用範圍,<slot name='last'><button>【若是沒有內容則顯示我2】</button></slot>因此使用button標籤</div>"
- }
- }
- });
- </script>
說明:
【1】name=’first’的slot標籤被父組件對應的標籤所替換(slot標籤內部的內容被捨棄);
【2】name=’last’的slot標籤,由於沒有對應的內容,則顯示該slot標籤內部的內容。
⑦假如想控制子組件根標籤的屬性
【1】首先,因爲模板標籤是屬於父組件的,所以,將子組件的指令綁定在模板標籤裏,是不能夠的(由於他歸屬於父組件);
【2】假如須要經過父組件控制子組件是否顯示(例如v-if或者v-show),那麼這個指令顯然是屬於父組件的(例如放在父組件的data下面)。能夠將標籤寫在子組件的模板上。
如代碼:
- <div id="app">
- <button @click="toshow">點擊讓子組件顯示</button>
- <children v-if="abc">
- </children>
- </div>
- <script>
- var vm = new Vue({
- el: '#app',
- data: {
- abc: false
- },
- methods: {
- toshow: function () {
- this.abc = !this.abc;
- }
- },
- components: {
- children: { //這個無返回值,不會繼續派發
- template: "<div>這裏是子組件</div>"
- }
- }
- });
- </script>
說明:
經過父組件(點擊按鈕,切換v-if指令的值)控制子組件是否顯示。
【3】假如須要經過子組件,控制子組件是否顯示(好比讓他隱藏),那麼這個指令顯然是屬於子組件的(會將值放在子組件的data屬性下),那麼就不能像上面這麼寫,而是必須放置在子組件的根標籤中。
- <div id="app">
- <button @click="toshow">點擊讓子組件顯示</button>
- <children>
- <span slot="first">【12345】</span>
-
- </children>
- </div>
- <script>
- var vm = new Vue({
- el: '#app',
- methods: {
- toshow: function () {
- this.$children[0].tohidden = true;
- }
- },
- components: {
- children: { //這個無返回值,不會繼續派發
- template: "<div v-if='tohidden' @click='tohide'>這裏是子組件</div>",
- data: function () {
- return {
- tohidden: true
- }
- },
- methods: {
- tohide: function () {
- this.tohidden = !this.tohidden;
- }
- }
- }
- }
- });
- </script>
說明:
點擊子組件會讓子組件消失;
點擊父組件的按鈕,經過更改子組件的tohidden屬性,讓子組件從新顯示。
子組件的指令綁定在子組件的模板之中(如此才能調用);