vue---slot,slot-scoped,以及2.6版本以後插槽的用法

slot 插槽 ,是用在組件中,向組件分發內容。它的內容能夠包含任何模板代碼,包括HTML。html

vue 在 2.6.0 中,具名插槽和做用域插槽引入了一個新的統一的語法 (即 v-slot 指令)。它取代了 slot 和 slot-scope 這兩個目前已被廢棄但未被移除且仍有用的特性。可是將會在vue 3 中,被廢棄的這兩個,不會被支持即無效vue

在 2.6.0以前,插槽的用法:ide

1. 匿名插槽。函數

以 .vue 這種單文件模塊爲例ui

//建立 testSlot.vue組件
<template>
    <div>
     //slot裏面也能夠設置內容,這個能夠設置不傳內容時,slot有個默認值替換 <slot>這裏面是slot的默認值</slot> <h3>子組件頁面</h3> </div> </template> <script> export default { props:[], data:function(){ return {} } } </script> <style> </style>
//引用testSlot組件
<template>
    <div>
        <h1>引用testSlot組件的頁面</h1>
        <testSlot>
            {{msg}}
        </testSlot>
    </div>
</template>

<script>
    import testSlot from '../components/testSlot'
    
    export default{
        data () {
            return {
         msg:'這是動態傳入的slot的內容'
       } }, components:{ testSlot } }
</script> <style> </style>

 結果:spa

注意事項:code

1) 匿名的方式,就是指把在引用組件的時候,裏面傳的內容所有一塊兒傳送到組件頁面中 <slot></slot> 所在的位置component

2) 只要組件中有 <slot></slot> ,而且無論有多少個,都會所有渲染爲傳過來的內容htm

3) <slot></slot>裏面也能夠設置內容,這個內容是保證引入組件的時候,有個默認值。固然,<slot></slot>裏面不設置內容也能夠,這樣只是沒有默認值,是不會報錯的對象

4) 傳遞的內容,也能夠是動態的,如同上面同樣。可是要注意的是,這個內容不能是 引用組件的時候組件上的內容,要注意做用域。能夠查看官網 插槽編譯做用域

5) 若是傳遞的內容沒有slot 來接收,那麼,傳遞的內容就會被拋棄掉,不會起做用。

5) 那這個時候,若是我想某個 <slot></slot> 傳指定的 內容呢?那這個時候就須要具名插槽了。

 

 2. 具名插槽,就是給插槽指定名稱,而後 一 一對應

//引入組件的頁面
<testSlot>
     <template slot='header'>
        <p>------------header----------------</p>
        <h3>這是header1的內容</h3>
        <p>這是header2的內容</p>
    </template>
    
    <template slot='footer'>
        <p>------------footer----------------</p>
        <h3>這是footer1的內容</h3>
        <p>這是footer2的內容</p>
    </template>
        
    <p>-----------default-----------------</p>
    <p>這是default剩下的內容1</p>
    <p>這是default剩下的內容2</p>
</testSlot>
//組件當前頁面
<slot>---默認內容---</slot>
<h3>slot組件頁面</h3>
<slot name='header'>---header的默認內容---</slot>
<slot name='footer'>---footer的默認內容---</slot>

結果:

注意事項:

1) 引入組件的頁面,若是是多個內容,需要用template 包裹起來,而且添加 slot 屬性和 自定義值 。

2) slot 的值  須要和 組件中 <slot  name='xxx'></slot>  name的值相對應。

3) 若是剩下的內容沒有包裹起來並制定值的話,那麼這些內容會被渲染到 組件中 全部的  <slot></slot> 所在的位置

4) 若是 slot 設置爲default 和 name 設置爲default,那就和沒設置slot與name是同樣的。

5) 和vue 2.6.0 之後的具名插槽相比 template上的 slot='xxx' 只須要 改爲 v-slot : xxx 就好了,等號改爲了冒號,而且值沒有引號,帶引號反而會報錯。

6) 具名插槽只須要  name值 與  slot的值  對應 ,插槽的順序是沒有關係的。

 

3. slot-scope 做用域插槽。

這個的做用,主要就是當向組件發送的內容須要和組件的props屬性的內容有聯繫時,才使用這個做用域插槽。簡單點來講就是:能夠使用 子組件的數據 和 父組件傳過來的props的值

//引入組件的頁面
<template>
    <div>
        <!--這裏向組件傳入props-->
        <slotScope :message='msg'>
            <!--這裏的thing是隨便取的名稱,不與任何地方對應-->
            <div slot='sayWhat' slot-scope='thing'>說了:{{thing.said}}</div>
            <!--這裏的val也是隨便取的名稱,不與任何地方對應-->
            <template slot='listbox' slot-scope='val'>
                <p>{{val.send.text}}</p>
            </template>
        </slotScope>
    </div>
</template>

<script>
    import slotScope from '../components/slotScope'
    
    export default{
        data () {
            return {
               msg: '這是動態傳入的slot的內容',
           }
        },
        components:{slotScope }
    }
</script>

<style>
</style>
//組件頁面
<template>
    <div>
        <!--這裏最重要的是 :send=value,send也是能夠隨便取的,表示要傳過去的值-->
        <slot name='listbox' v-for='value in list' :send='value'></slot>
        <!--這裏最重要的是 :said='message',said也是能夠隨便取的,表示要傳過去的值-->
        <slot name='sayWhat' :said='message'></slot>
        
        <ul>
            <li v-for='item in list' :key='item.id'>{{item.text}}</li>
        </ul>
    </div>
</template>

<script>
    export default {
        props:['message'],
        data:function(){
            return {
              list:[{
              "id":10,
              "text":"蘋果"
          },{
              "id":20,
              "text":"香蕉"
          },{
              "id":30,
              "text":"梨"
          },{
              "id":40,
              "text":"芒果"
          }]
          }
        }
    }
</script>

<style>
</style>

 結果:

注意事項:

1) 做用域插槽主要是  使用子組件的任何數據  來達到自定義顯示內容的目的

2) 做用域插槽最最最最最重要的一步,便是在<slot></slot> 上綁定數據 ,若是沒有綁定數據,則父組件收到的,只是一個空對象{ }

3) 做用域插槽中 <slot></slot> 上綁定數據,能夠是寫死的,也能夠是動態綁定的。若是是動態綁定的,則也須要 v-bind:xxx

4) 做用域插槽中 <slot></slot> 上綁定的數據 也能夠一個定義好的有返回值的 mthods 方法。好比我定義了 <slot  what='say()'></slot> ,而後say方法爲: say:function(){  return  '我說了' } 。最後獲得的結果就是  "我說了",固然,動態綁定必定要加 v-bind:xxx。

5) 當 <slot></slot> 綁定上數據以後,引用組件的地方 中  發送的內容就能經過 slot-scope 來獲取。獲取到的內容,就是一個對象,好比 <slot name='sayWhat' said='message'></slot>   我這裏綁定  said='message' 以後, 那邊接收到的就是 { said:"xxxx"} 一個對象。

6) slot-scope 能夠接收任何有效的能夠出如今函數定義的參數位置上的 JavaScript 表達式。

 

vue 2.6.0以後   v-slot  只能用在 組件component 或者 template 上 ,用在 divp 這種標籤上是會報錯的

1. 具名插槽的變化

<testSlot>
    <!--2.6.0之前的寫法-->
    <template  slot='header'>
        <p>------------header----------------</p>
        <h3>這是header1的內容</h3>
        <p>這是header2的內容</p>
    </template>

<!--2.6.0以後的寫法--> <template v-slot:header> <p>------------header----------------</p> <h3>這是header1的內容</h3> <p>這是header2的內容</p> </template> </testSlot> 

1) slot=' xxx '  改爲了  v-slot : xxx  而且冒號後面這個名稱不能打引號

2) 組件頁面中slot的內容沒有變化

3) 2.6.0 以後  具名插槽 v-slot:header  能夠縮寫爲 #header  ,必須是有參數才能這樣寫!!! # = "xxx "  這樣是不行的   #default = 'xxx' 這樣才能夠

 

2. 做用域插槽的變化

<slotScope :message='msg'>
    <!--2.6.0以前的寫法-->
    <div slot='sayWhat' slot-scope='thing'>說了:{{thing.said}}</div>
    
    <template slot='listbox' slot-scope='value'>
        <p>{{value.send.text}}</p>
    </template>

    <!--2.6.0以前的寫法,不能單獨用在html標籤上-->
    <template v-slot:sayWhat='thing'>
      <div>說了:{{thing.said}}</div>
    </template>
    <template v-slot:listbox='value'>
        <p>{{value.send.text}}</p>
    </template>
</slotScope>

1) 兩個屬性合併成了一個  v-slot : 插槽名稱 = ' 傳過來的值 ' 。

2) 組件頁面中slot的內容沒有變化

3) v-slot 不能用在 html 標籤上

4) 若是是默認插槽 能夠寫成  v-slot='xxx'。

5) 還增長了  能夠解構插槽props 和 設置默認值的內容,具體的能夠查看官網 解構插槽

 

3. 新增的還有 動態插槽名

什麼是動態插槽名?大體就是動態指令參數也能夠用在v-slot上,這個就要涉及到2.6.0新增的  動態參數

<template v-slot:[attrContent]='msg'>
    xxx
</template>

這個 attrContent  會被做爲一個 JavaScript 表達式進行動態求值,求得的值將會做爲最終的參數來使用。 好比這裏attrContent 最終的值爲 default  則渲染出來的結果 就是 v-slot:default='msg' 。

注意:

1) 單獨在 [ ] 方括號中也可使用表達式,可是不能存在引號和空格

2) 固然 這個動態的值  能夠經過 方法計算屬性,或者 data數據 裏面的內容。重要的是這個動態的值 是 引用組件的 做用域。簡單點說就是父級組件的做用域。

例如,上面 v-slot:sayWhat='thing'  能夠寫成:

1) v-slot:[first+sec]='thing'    注意 加號兩邊不能留空格

2) v-slot:[attr]='thing'

3) v-slot:[attrs]='thing'

4) v-slot:[getattr()]='thing'

export default{
    data () {
        return {
            msg: '這是動態傳入的slot的內容',
            attr:'sayWhat',
            first:'say',
            sec:'What',
        }
    },
    components:{ slotScope },
    computed:{
        attrs:function(){
            return 'sayWhat'
        }
    },
    methods:{
        getattr(){
            return 'sayWhat'
        }
    }
}        

 

到此,插槽的內容就介紹完畢了。^_^ Y 

相關文章
相關標籤/搜索