插槽含義:就是引入子組件后,在插入子組件元素中添加信息或者標簽,使得子組件的指定位置插入信息或者標簽
插槽有三種:默認插槽、具名插槽、作用域插槽,由於vue2.6.0后對插槽進行修改,但是兼容2.6.0前的版本,博文中只說明2.6.0后的插槽,vue3.0后面會去除2.60前的版本兼容
一、默認插槽
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>默認插槽</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> {{message}} <tode-item>這是一個默認插槽<h3>這是標簽h3</h3></tode-item> </div> </body> <script type="text/javascript">
//子組件 Vue.component('tode-item', { template: `<div> <slot>這里面是slot的默認值</slot>//當引入組件的地方沒有寫插槽內容,將顯示子組件插槽中默認的值,如果沒有默認值也沒用寫插槽內容,則插槽內容為空。 </div>` }); var app = new Vue({ el: "#app", data: { message: 'hello world!' } }); </script> </html>
二、具名插槽: 子組件中有多個插槽,通過給插槽指定名稱方式實現一 一對應。
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>具名插槽</title> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <div id="app"> 這是2.60版本后使用v-slot引入插槽名稱 <my-component> <template v-slot:first>nihao</template> <template v-slot:last>hi</template> </my-component> <!-- 這是具名插槽縮寫方案 v-slot:縮寫為 # --> <my-component> <template #first>nihao</template> <template #last>hi</template> </my-component> </div> </body> <script type="text/javascript"> Vue.component('my-component',{ template: ` <div> <h4>這是第一個具名插槽</h4> <slot name='first'></slot> <h4>這是第二個具名插槽</h4> <slot name='ast'></slot> </div>` }) let app = new Vue({ el: "#app", data: { } }) </script> </html>
三、作用域插槽:把子組件data中的數據或者子組件props中的數據傳到父組件的插槽中使用
1) 兩個屬性合並成了一個 v-slot : 插槽名稱 = ' 傳過來的值 ' 。
2) 組件頁面中slot的內容沒有變化 。
3) v-slot 不能用在 html 標簽上 。
4) 如果是默認插槽 可以寫成 v-slot='xxx'。
5) 還增加了 可以解構插槽props 和 設置默認值的內容,具體的可以查看官網 解構插槽
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>作用域插槽</title> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script> <!-- <script type="text/javascript" src="vue.js"></script> --> </head> <body> <div id="app"> <my-component :message='msg'> <!--這里的val也是隨便取的名稱,不與任何地方對應--> <template v-slot:listbox='val'> <p>{{val.send.text}}</p> </template> <!--這里的thing是隨便取的名稱,不與任何地方對應--> <div slot='sayWhat' slot-scope='thing'>這是2.60版本前的寫法:{{thing.said}}</div> <!-- 注意作用域插槽最好用於子組件的slot是批量循環的情況,子組件的slot是非批量循環的情況下無效,子組件中slot我們這樣想:如果只是傳一個值,有沒有必要使用插槽?直接在子組件中寫就行了,何必多次一舉。 --> <!-- 這是無效的寫法 <div v-slot:sayWhat='thing'>說了:{{thing.said}}</div> --> <!-- 這是無效的寫法 <template v-slot:sayWhat='thing'> {{thing.said}} </template> --> </my-component> </div> </body> <script type="text/javascript"> Vue.component('my-component',{ template: ` <div> <slot name='listbox' v-for='value in list' :send='value'></slot> <slot name='sayWhat' :said='message'></slot> </div> `, props:['message'], data(){ return { list:[ { "id":10, "text":"蘋果" },{ "id":20, "text":"香蕉" },{ "id":30, "text":"梨" },{ "id":40, "text":"芒果" }, ] } } }) let app = new Vue({ el: "#app", data: { msg: '這是動態傳入的slot的內容', } }) </script> </html>
4. 新增的還有 動態插槽名
什么是動態插槽名?大致就是動態指令參數也可以用在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' } } }
參考:https://www.cnblogs.com/zjjDaily/p/10518546.html