携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,[携手创作,共同成长,8月更文活动奖品大升级!| 掘金·日新计划 - 掘金 (juejin.cn))
vue插槽
1、什么是插槽
插槽就是vue为组件封装者提供的,允许开发者在封装组件时把不确定的,有特殊要求的部分定义为插槽(),就相当于我们想要插入内容的占位符。
2、我们要清楚插槽使用的场景
在我们实际开发的过程中,插槽一般在设计组件的时候用到,当我们发现几个页面大部分结构相同,只有局部的地方不一样,那么就可以设计一个基础组件,不一样的地方就需要用到插槽。
3、插槽的几种类型(具体的使用方法,以及使用场景在下面会有详细介绍)
- 匿名插槽
- 具名插槽
- 作用域插槽
4、匿名插槽使用方式及其相关介绍
又名默认插槽,当slot没有指定name属性值的时候一个默认显示插槽,一个组件内只有有一个默认插槽。
在这里我们创建一个组件,名字就叫Chid.vue,里面就是一个简单的a标签,进行页面的跳转。
<template>
<div>
<a :href="url"> //a标签的href属性里面的值是父组件传递过来的
掘金
</a>
</div>
</template>
<script>
export default {
props:['url']
}
</script>
<style scoped>
</style>
这里是我们的主页面,引入组件Chid,components进行注册然后就可以直接使用
<template>
<div>
<h1>插槽</h1>
<Child url="https://juejin.cn/"></Child>
</div>
</template>
<script>
import Child from "../components/Chid.vue";
export default {
components:{
Child
},
data() {
return {
}
},
}
</script>
当然到这里页面功能是已经实现的,但是我们想要改变a标签里面的文字内容,这个有几种方式:1.直接改变组件里面的文字内容(这种方式是不优雅的,有违背创建组件的初衷) 2.就是在定义一个属性通过父组件传递文字内容(这种方式对简单的组件是可行的) 3. 就是通过插槽的方式去实现(今天主要介绍这一种)
如何实现:
在我们的组件a标签里面不直接写内容了,而是通过标签充当一个占位符的作用,接收父组件的值进行渲染
组件Chid.vue
<template>
<div>
<a :href="url"> //a标签的href属性里面的值是父组件传递过来的
<slot></slot> //插槽的位置,在开始标签和结束标签之间
</a>
</div>
</template>
<script>
export default {
props:['url']
}
</script>
<style scoped>
</style>
//主页面里面
<template>
<div>
<h1>插槽</h1>
<Child url="https://juejin.cn/"> //这里在组件开始标签和结束标签之间写入插槽所需要的内容
掘金
</Child>
</div>
</template>
<script>
import Child from "../components/Chid.vue";
export default {
components:{
Child
},
data() {
return {
}
},
}
</script>
5、具名插槽使用方式及其相关介绍
具名插槽,即具有名字的插槽,在默认插槽基础上指定插槽的名字(name = " "),是通过标签里面name属性进行一一对应的,父组件指明放入子组件的哪个插槽,具体的看下面的代码示例
这是组件Chid
<template>
<div>
<slot name="title"></slot> //这个就是一个具名插槽,其中里面的name属性值就是对应父组件里面slot属性的
<slot></slot> //这个没有name属性,就是匿名插槽,当然他也是去对应父组件里面对应的内容
<slot name="content"></slot>
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
</style>
这是主页面---------------------------------------------------------------------------------
<template>
<div>
<Child>
<div slot="title"> //这里slot="title"就对应组件里面name="title"
<h2>我是一个大标题</h2>
</div>
<div>
掘金沸点,一起摸鱼
</div>
<div slot="content">
<p>我是文章的内容部分</p>
</div>
//当然我们这里需要注意在vue2.6.0+的版本里面写法是稍微有点不同
<template v-slot:title> //用的是指令加上参数的方式来写,也不能直接写在div标签上,要写在template标签里面
<h2>我是一个大标题</h2>
</template>
</Child>
</div>
</template>
<script>
import Child from "../components/Chid.vue";
export default {
components:{
Child
},
}
</script>
6、作用域插槽使用方式及其相关介绍
一句话来说明就是延伸了子组件的作用域,组件有编译作用域---父级模板里的所有内容都是在父级作用域中编译的,子模板里的所有内容都是在子作用域中编译的。
简单看个例子
定义一个子组件,
在这个子组件里面携带数据的是slot,子组件里面携带数据,父组件里面接受数据
<template>
<div>
<a :href="url">
<slot :user="user"></slot> //:user="user"就是插槽所携带的数据
</a>
</div>
</template>
<script>
export default {
props:['url'],
data() {
return {
user:{
name:'摸鱼吧',
age:18
}
}
},
}
</script>
<style scoped>
</style>
这是父组件里面的代码
在父组件中通过slot-scope来接受子组件提供参数
这是错误的示范:
<template>
<div>
<h1>插槽</h1>
<Child url="https://juejin.cn/">
以{{user.name}}的身份去访问链接 //这里注意在父组件里面直接调用子组件里面的数据是报错的
</Child>
</div>
//正确的方式应该是-----------------------------------------------------------------------------------
<div>
<h1>插槽</h1>
<Child url="https://juejin.cn/">
<template slot-scope="{ user }"> //这里使用了解构赋值,这样就可以正常的访问子组件里面的数据
以{{user.name}}的身份去访问链接
</template>
</Child>
</div>
</template>
<script>
import Child from "../components/Chid.vue";
export default {
components:{
Child
},
data() {
return {
name:'摸鱼者'
}
},
}
</script>
\