插槽含义:就是引入子组件后,在插入子组件元素中添加信息或者标签,使得子组件的指定位置插入信息或者标签
插槽有三种:默认插槽、具名插槽、作用域插槽,由于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: `
这里面是slot的默认值 //当引入组件的地方没有写插槽内容,将显示子组件插槽中默认的值,如果没有默认值也没用写插槽内容,则插槽内容为空。
`
});
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: `
这是第一个具名插槽
这是第二个具名插槽
`
})
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/[email protected]"></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: `
`,
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>
<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'
}
}
}