插槽含義:就是引入子組件后,在插入子組件元素中添加信息或者標簽,使得子組件的指定位置插入信息或者標簽
插槽有三種:默認插槽、具名插槽、作用域插槽,由於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
