插槽存在的意义
我们知道,在vue中,引入的子组件标签中间是不允许写内容的。为了解决这个问题,官方引入了插槽(slot)的概念。
例如:
打印结果:
一、什么是插槽?
插槽,其实就相当于占位符。它在组件中给你的HTML模板占了一个位置,让你来传入一些东西。插槽又分为匿名插槽、具名插槽以及作用域插槽。
你可能不太明白,为什么我要给子组件中传入HTML,而不直接写在子组件中呢?答案是这样的。你可以想象一个场景,你有五个页面,这五个页面中只有一个区域的内容不一样,你会怎么去写这五个页面呢?复制粘贴是一种办法,但在vue中,插槽(slot)是更好的做法。
注:父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
二、插槽的三大类
1.匿名插槽
在父组件中的代码如下(示例):
<template>
<div class="home">
我是Home父组件
<hello-world>
<h1>我是helloworld中的匿名插槽呀</h1>
</hello-world>
</div>
</template>
<script>
import HelloWorld from "@/components/LoginHead.vue";
export default {
name: "home",
components: {
HelloWorld,
},
data() {
return {
someThing: {
name: "小苏",
age: 21,
},
name: "苏苏",
};
},
};
</script>
子组件代码如下:
<template>
<div class="hello">
Helloworld组件
<!-- 匿名插槽 -->
<div class="slotTxt">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
data() {
return {
user: {
name: "小小苏",
age: 18,
},
};
},
};
</script>
<style scoped lang="scss">
.hello {
width: 100%;
height: 700px;
background: #ccc;
margin-top: 50px;
.slotTxt {
width: 500px;
height: 200px;
margin: 30px auto;
background: red;
}
.slotTxt2 {
width: 500px;
height: 200px;
margin: 30px auto;
background: green;
}
.slotTxt3 {
width: 500px;
height: 200px;
margin: 30px auto;
background: teal;
}
}
</style>
结果如下:
2.具名插槽
代码如下(示例):
父组件的代码
<template>
<div class="home">
我是Home父组件
<hello-world>
<template v-slot:slotBottem>
<h2>我是helloworld中的具名插槽呀</h2>
<h1>{{ name }}</h1>
</template>
</hello-world>
</div>
</template>
子组件代码如下:
<template>
<div class="hello">
Helloworld组件
<!-- 具名插槽 -->
<div class="slotTxt2">
<slot name="slotBottem"></slot>
</div>
</div>
</template>
结果如下:
3.作用域插槽
父组件代码如下:
<template>
<div class="home">
我是Home父组件
<hello-world>
<template v-slot:default="slotProps">
<h1>{{ slotProps.users.name }}</h1>
<h1>{{ slotProps.users.age }}</h1>
</template>
</hello-world>
</div>
</template>
子组件代码如下:
<template>
<div class="hello">
Helloworld组件
<!-- 作用域插槽 -->
<div class="slotTxt3">
<slot v-bind:users="user"></slot>
</div>
</div>
</template>
结果如下:
4.具名插槽与作用域插槽联合使用
父组件代码如下:
<template>
<div class="home">
我是Home父组件
<hello-world>
<!-- 具名插槽与作用域插槽联合使用 -->
<template v-slot:xiaosu="slotProps">
<h1>{{ slotProps.users.name }}</h1>
<h1>{{ slotProps.users.age }}</h1>
</template>
</hello-world>
</div>
</template>
子组件代码如下:
<template>
<div class="hello">
Helloworld组件
<!-- 具名插槽与作用域插槽联合使用 -->
<div class="slotTxt3">
<slot name="xiaosu" v-bind:users="user"></slot>
</div>
</div>
</template>
结果如下:将插槽放在固定的位置,并且使用子组件的值
三、插槽的缩写
v-slot:与v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:header 可以被重写为 #header:
然而,和其它指令一样,该缩写只在其有参数的时候才可用。这意味着以下语法是无效的
<!-- 这样会触发一个警告 -->
<hello-world #="{ user }">
{{ user.firstName }}
</hello-world>
如果你希望使用缩写的话,你必须始终以明确插槽名取而代之:
<hello-world #default="{ user }">
{{ user.firstName }}
</hello-world>
参考文档:
https://blog.csdn.net/Oralinge/article/details/103896320