vue2 vs vue3 插槽
2021-11-29 本文已影响0人
微笑的弧度_c50f
前言:插槽的使用其实是很简单,你只需要明白两点:
1.插槽是使用在子组件中的。
2.插槽是为了将父组件中的子组件模板数据正常显示
vue2.0的插槽
话不多说直接上案例:
<div id="app">
<div class="father">
<h3>这里是父组件</h3>
<child>
<span>我是插槽插入的内容</span>
</child>
</div>
</div>
<template id="child">
<div class="child">
<h3>这里是子组件</h3>
<slot></slot>
</div>
</template>
<script>
var vm = new Vue({
el: '#app',
data: {},
components: {
child: {
template: '#child'
}
}
});
</script>
上面的代码所展示的效果就是你会发现在 <h3>这里是子组件</h3>
会多一行 <span>我是插槽插入的内容</span>
如果你在子组件里面不写 <slot></slot>
的话你会发现你无论在父组件里面写多少标签都不会被渲染到子标签中。
<font color=red>这就是传说中的插槽了,怎么样是不是很简单?</font>
上面的案例是匿名插槽,下面我们来看一下 “具名插槽”
<div id="app">
<div class="father">
<h3>这里是父组件</h3>
<child>
<span slot="demo1">菜单1</span>
<span>菜单2</span>
<span slot="demo3">菜单3</span>
</child>
</div>
</div>
<template id="child">
<div class="child">
<h3>这里是子组件</h3>
<slot></slot>
<slot name="demo3"><slot>
</div>
</template>
<script>
var vm = new Vue({
el: '#app',
data: {},
components: {
child: {
template: '#child'
}
}
});
</script>
具名插槽其实就是在父组件中添加一个 slot='自定义名字' 的属性,
然后在子组件中的<slot><slot> 里面添加 <name='自定义名字' 即可
如果父组件中有一部分没有添加 slot 属性,则此处就是默认的插槽,在子组件中的<slot></slot> 直接就是使用的父组件的默认插槽部分
作用域插槽
父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译。
不过,我们可以在父组件中使用slot-scope 特性从子组件获取数据
前提是需要在子组件中使用:data=data 先传递data 的数据
<div id="app">
<div class="father">
<h3>这里是父组件</h3>
<child>
<div slot-scope="user">
{{user.data}}
</div>
</child>
</div>
</div>
<script>
Vue.component('child', {
template:'' +
'<div class="child">\n' +
' <h3>这里是子组件</h3>\n' +
' <slot :data="data"></slot>\n' +
' </div>',
data: function () {
return {
data: ['zhangsan', 'lisi', 'wanwu', 'zhaoliu', 'tianqi', 'xiaoba']
}
}
});
var vm = new Vue({
el: '#app',
});
</script>
页面显示的结果如下:
这里是父组件
这里是子组件
['zhangsan', 'lisi', 'wanwu', 'zhaoliu', 'tianqi', 'xiaoba']
vue3.0中插槽的使用
匿名插槽用法不变
下面我们来看一下具名插槽的写法
// 子组件
<div class="hello">
我是一个封装的组件
<slot name="num"></slot>
</div>
// 父组件
<HelloWorld v-model="masg" v-slot:num>
<div>我是插槽插入的</div>
</HelloWorld>
// 父组件的另外一个写法
<HelloWorld v-model="masg">
<template v-slot:num>
<div>我是插槽插入的</div>
</template>
</HelloWorld>
Vue3(其实从2.6开始)中引入了一个新的指令 v-slot,用来表示具名插槽和默认插槽。
在 v2.5 之后屏蔽了 slot-scope,
v-slot引入使其插槽更接近指令化。
下面我们来看一下作用域插槽的用法
// 子组件
<div class="hello">
我是一个封装的组件
<slot :num="num"></slot>
</div>
<script>
import { ref } from 'vue';
export default {
name: 'HelloWorld',
props: {
// msg: String,
modelValue: String
},
setup(prop,context){
const num = ref(10);
return { num }
}
}
</script>
// 父组件
<HelloWorld>
<template v-slot="{num}">
<div>{{num}}</div>
</template>
</HelloWorld>
// 也可以改成下面的写法
<HelloWorld v-slot="{num}">
<div>{{num}}</div>
</HelloWorld>
和 v-bind和v-on相似,缩写只有在存在参数时才生效,这就意味着v-slot没有参数时不能使用#=,对于默认插槽,可以使用#default来代替v-slot
// 上面我们写过具名插槽可以这么写
<HelloWorld v-model="masg">
<template #num>
<div>我是插槽插入的</div>
</template>
</HelloWorld>
// 或者如上面的作用域插槽也可以改成下面的写法
<HelloWorld>
<template #default="{num}">
<div>{{num}}</div>
</template>
</HelloWorld>