Vue中的插槽slot解析

slot解析:

slot:

在Vue中,slot也也叫做插槽,顧名思義,這是爲了要擴展一些內容,也就是爲了給未來元素使用,而採用的一種方法。
像html一樣,我們常常需要給組件傳遞一些內容,但是在Vue的組件中,組件內部直接展示的內容將不會被執行解析

<div id="app">
    <One>
        <span>123</span>
    </One>
</div>

在這段代碼中,one組件中的span將不會被渲染,但是如果我們想要將span以及內容渲染出來,這時我們就需要藉助slot來做了。
我們只需要在one組件的模板中,加入一個<slot></slot>標籤,此時one組件中的內容(也就是span)就會被替換到模板中slot標籤的位置進行渲染。

<div id="app">
        <One>
            <span>123</span>
        </One>
    </div>
    <template id="one">
        <div>
            <p>aaa</p>
            <slot></slot>
        </div>
    </template>

此時的span標籤在p標籤下方正常渲染,但這樣做,解決不了所有的問題,如果我們在組件內部需要渲染的結構是分開的,並且中間還要穿插一部分的模板內容,此時單單的一個slot標籤就很難解決問題了。

<div id="app">
    <Hello>
      <header>
        頭部
      </header>
      <footer>
        底部
      </footer>
    </Hello>
  </div>

  <template id="hello">
    <div>
      <h3> 這裏是hello組件 </h3>
      <slot></slot>
    </div>
  </template>

我們想要達到的效果是頭部在上方展示,h3標籤在中間展示,底部在下方展示。俗話說,一個解決不了的問題,那就用兩個,這裏也是同樣的,我們一個slot標籤無法分別表示兩塊結構,那麼我們就用兩個slot標籤,但是新的問題又來了,瀏覽器怎麼知道哪個slot標籤對應哪塊的結構呢?所以,我們就需要給slot標籤起一個名字,並給對應的結構綁定對應名字的slot屬性。像這樣:

<div id="app">
    <Hello>
      <header slot = "header">
        頭部
      </header>
      <footer>
        底部
      </footer>
    </Hello>
  </div>

  <template id="hello">
    <div>
      <slot name = "header"></slot>
      <h3> 這裏是hello組件 </h3>
      <slot></slot>
    </div>
  </template>

像上面這種給slot起名字的用法,我們叫做具名插槽,但是不論是什麼插槽,我們如果想把組件內定義的數據傳遞到頁面展示,仍然無法做到。
於是,我們又需要一個方法,將在定義組件的數據傳遞到頁面結構中去,並渲染出來。這種方法叫做作用域插槽;
那我們的做法是,先在slot標籤上綁定一個自定義的屬性,將要傳遞的數據賦值給該屬性。此時,在組件使用時,只需要給對應需要渲染的元素添加一個slot-scope來接收就可以了。

注意:
1、slot-scope的屬性值是自定義的,該屬性值是一個對象,如果在模板中的slot標籤中綁定了自定義屬性A,那麼我們打印slot-scope的屬性值的結果就是 {A:“傳遞的數據”}。如果在模板中的slot標籤沒有綁定自定義屬性,那麼打印slot-scope的屬性值的結果就是一個空對象{}。
2、slot標籤在綁定自定義屬性時,屬性值必須爲組件內定義的數據(也可以是computed中的方法,結果爲方法的返回值,但methods中的方法不行),否則就會報錯;
3、slot標籤允許綁定多個自定義屬性,用來分別傳遞不同的數據。例如,slot標籤綁定了自定義屬性A,B兩個屬性,那麼在接收時,打印出的slot-scope屬性值的結果就是{A:“數據1”,B:“數據2”}

下面我們看一下例子

 <div id="app">
        <One>
            <span>123</span>
            <div slot="abc" slot-scope="date">{{date}}</div>
        </One>
    </div>
    <template id="one">
        <div>
         //自定義屬性的名字可以自定義,但是屬性值一定是組件中定義的數據(也可以是計算屬性)
            <slot name="abc" :a="msg" :b="msg"></slot>
            <p>aaa</p>
            <slot></slot>
        </div>
    </template>
    <script src="https://cdn.bootcss.com/vue/2.6.10/vue.js"></script>
    <script>

        Vue.component('One',{
            template:"#one",
            data(){
                return {
                    msg:"信息"
                }
            }
        })

        new Vue({
            el:"#app"
        })

此時我們看到結果是

{"a":"信息","b","信息"}

不過我們剛剛看到的所有內容,在Vue中已經被廢棄了,不過,在一些公司的祖傳代碼中,你或許仍然可以看到這些代碼的影子,所以,瞭解這些內容也許對你有一定的幫助。

但是既然Vue的官方已經廢棄了這些方法,我們也就不在執着於多麼精通它,我們現在就來看一下,Vue提出的新的替代方案。
新的方案是提出了一個v-slot指令,他是將slot組建身上的數據傳遞給綁定的未來元素,這樣一看或許你還在雲裏霧裏,不知所云。那麼我們來詳細的介紹一下v-slot的用法,或許你就有更深的瞭解;

v-slot在某些方面與已經被廢棄的solt與solt-scope有些相似,我們仍然按照剛纔的順序介紹v-slot指令;

在插槽方面,並沒有變化,我們仍然是使用slot標籤來完成渲染組件內的結構;
但是這裏有一點不同:之前我們可以在組件內渲染任意標籤,但是現在,我們只能用<template></template>標籤將需要渲染的結構包裹,否則將無法解析;而且在渲染時template是不會被渲染的;
在新的指令中,我們還是要通過name屬性來對應每個需要渲染的結構;但是在template標籤接收時會有一些變化,我們在接收時要用 v-slot:名字 來接收這個名字;
這裏還有一點需要關注,如果在組件內出現沒有被template包裹的結構,那麼默認是template的一部分,也就是說需要渲染到對應slot標籤位置的;
其他方面的用法大體相似,所以這裏只寫一個案列來描述v-slot指令的用法:

<div id="app">
        <One>
            <template v-slot:nihao="a">
                <div>1</div>
            </template>
            <template v-slot:nihao="sy">{{sy}}</template>
        </One>
    </div>
    <template id="one">
        <div>
            <slot name="nihao" :a="msg" :b="abc"></slot>
            <p>aaa</p>
            
        </div>
    </template>

以上就是Vue中slot的基本用法了,感謝閱讀;
如果發現有錯誤請指出,謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章