vue3插槽具名插槽作用域插槽-足够入门了!
Posted 星月前端
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue3插槽具名插槽作用域插槽-足够入门了!相关的知识,希望对你有一定的参考价值。
vue3 插槽
前言
这篇文章介绍vue组件的插槽!包括:插槽概念,具名插槽,作用域插槽等等,看完不会你打我。哈哈哈,开玩笑的,不多说,上刺刀!!
1. 概念
插槽(Slot)是vue为组件的封装者提供的能力。允许开发者在封装组件时,把不确定的、希望由用户指定的部分定义为插槽。
举个栗子:
eg组件好比小霸王游戏机,插槽就是游戏机的插口,看用户插什么卡,就在屏幕(预留的位置)上显示出对应的游戏(内容)。
我们不能把一个游戏机就固定一个游戏,有了插槽,这就一个(游戏机)组件,可以玩(显示出)不同的游戏(用户自定义的内容)。概念不太容易理解,直接上图:
2. 插槽的基本使用
- 在Left里面加一个slot标签
<template>
<div class="left-container">
<h3>Left 组件</h3>
<!-- 声明一个插槽区域 -->
<!-- vue 官方规定:每一个 slot 插槽,都要有一个 name 名称 -->
<!-- 如果省略了 slot 的 name 属性,则有一个默认名称叫做 default -->
<slot name="default"></slot>
<!-- 如果在slot里面放内容,那么用户在没有指定内容的时候就默认显示这里的内容,当用户指定内容的时候又会把这个替换了 -->
</div>
</template>
2 .在app根组件使用子组件里面直接放内容即可
<template>
<div class="app-container">
<h1>App 根组件</h1>
<hr />
<div class="box">
<!-- 渲染 Left 组件和 Right 组件 -->
<Left>
<!-- 默认情况下,在使用组件的时候,提供的内容都会被填充到名字为 default 的插槽之中 -->
<p>我是插槽里面用户自定义的内容</p>
</Left>
</div>
</div>
</template>
<!-- 插到指定位置使用方法如下 -->
<div class="box" style="display: none;">
<!-- 渲染 Left 组件和 Right 组件 -->
<Left>
<!-- 默认情况下,在使用组件的时候,提供的内容都会被填充到名字为 default 的插槽之中 -->
<!-- 1. 如果要把内容填充到指定名称的插槽中,需要使用 v-slot: 这个指令 -->
<!-- 2. v-slot: 后面要跟上插槽的名字 -->
<!-- 3. v-slot: 指令不能直接用在元素身上,必须用在 template 标签上 -->
<!-- 4. template 这个标签,它是一个虚拟的标签,只起到包裹性质的作用,但是,不会被渲染为任何实质性的 html 元素 -->
<!-- 5. v-slot: 指令的简写形式是 # -->
<template #default>
<p>这是在 Left 组件的内容区域,声明的 p 标签</p>
</template>
</Left>
</div>
3.这时候插槽的内容就会显示出来啦:
3. 具名插槽(带有name的插槽)
具名插槽以及作用域插槽的基本用法
eg:这里以一个栗子来讲解:
1.子组件 Article.vue 的代码:
<template>
<div class="article-container">
<h3 v-color="'red'">Article 组件</h3>
<!-- 文章的标题 -->
<div class="header-box">
<slot name="title"></slot>
</div>
<!-- 文章的内容 -->
<div class="content-box">
<!-- 在封装组件时,为预留的 <slot> 提供属性对应的值,这种用法,叫做 “作用域插槽” -->
<slot name="content" msg="hello vue.js" :user="userinfo"></slot>
</div>
<!-- 文章的作者 -->
<div class="footer-box">
<slot name="author"></slot>
</div>
</div>
</template>
<script>
export default
// 首字母要大写
name: 'Article',
data()
return
// 用户的信息对象
userinfo:
name: 'zs',
age: 20
</script>
<style lang="less" scoped>
.article-container
> div
min-height: 150px;
.header-box
background-color: pink;
.content-box
background-color: lightblue;
.footer-box
background-color: lightsalmon;
</style>
2.App.vue代码:
<template>
<div class="app-container">
<h1 v-color="color">App 根组件</h1>
<p v-color="'red'">测试</p>
<button @click="color = 'green'">改变 color 的颜色值</button>
<hr />
<Article>
<template #title>
<h3>星月看大海</h3>
</template>
<template #content=" msg, user ">
<div>
<p>啊,大海,全是水。</p>
<p>啊,蜈蚣,全是腿。</p>
<p>啊,辣椒,净辣嘴。</p>
<p> msg </p>
<p> user.name </p>
</div>
</template>
<template #author>
<div>作者:星月</div>
</template>
</Article>
</div>
</template>
<script>
import Left from '@/components/Left.vue'
import Article from '@/components/Article.vue'
export default
data()
return
color: 'blue'
,
components:
Left,
Article
,
// 私有自定义指令的节点
directives:
// 定义名为 color 的指令,指向一个配置对象
/* color:
// 当指令第一次被绑定到元素上的时候,会立即触发 bind 函数
// 形参中的 el 表示当前指令所绑定到的那个 DOM 对象
bind(el, binding)
console.log('触发了 v-color 的 bind 函数')
el.style.color = binding.value
,
// 在 DOM 更新的时候,会触发 update 函数
update(el, binding)
console.log('触发了 v-color 的 update 函数')
el.style.color = binding.value
*/
color(el, binding)
el.style.color = binding.value
</script>
<style lang="less">
.app-container
padding: 1px 20px 20px;
background-color: #efefef;
.box
display: flex;
</style>
这样就把用户在app自定义的内容通过具名插槽的方式来显示出来了。
栗子运行截图来了:
4. 作用域插槽
在封装组件的过程中,可以为预留的 < slot> 插槽绑定 props 数据,这种带有 props 数据的 < slot> 叫做“作用域插槽”。可以在父组件中传参来显示子组件绑定的数据,示例代码如下:
<!-- app.vue中使用自定义组件 -->
<my-test>
<template #default=" msg, info ">
<p> msg </p>
<p> info.address </p>
</template>
</my-test>
<!-- 子组件中预留的 < slot> 插槽绑定 props 数据 -->
<template>
<div>
<h3>这是 TEST 组件</h3>
<slot :info="infomation" :msg="message"></slot>
</div>
</template>
<script>
export default
name: 'MyTest',
data()
return
// 信息数据
infomation:
phone: '152xxxx6666',
address: '云南昆明',
,
message: 'abc'
,
</script>
4.1 解构作用域插槽的 Prop
作用域插槽对外提供的数据对象,可以使用解构赋值简化数据的接收过程。示例代码如下:
<!-- 使用自定义组件 -->
<my-test>
<!-- 解构 msg, info ,这样在使用的时候就不用去scope.info,或者scope.msg 了。 -->
<template #default=" msg, info ">
<p> msg </p>
<p> info.address </p>
</template>
</my-test>
4.2 声明以及使用作用域插槽
在封装 MyTable 组件的过程中,可以通过作用域插槽把表格每一行的数据传递给组件的使用者。在使用 MyTable 组件时,自定义单元格的渲染方式,并接收作用域插槽对外提供的数据。示例代码如下:
<!-- 在app中使用这个组件,以及传递参数 -->
<my-table>
<template #default=" user ">
<td> user.id </td>
<td> user.name </td>
<td>
<input type="checkbox" :checked="user.state" />
</td>
</template>
</my-table>
<!-- 自定义的作用域插槽组件 -->
<template>
<table class="table table-bordered table-striped table-dark table-hover">
<!-- 表头区域 -->
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>State</th>
</tr>
</thead>
<!-- 表格主体区域 -->
<tbody>
<!-- 循环渲染表格数据 -->
<tr v-for="item in list" :key="item.id">
<slot :user="item"></slot>
</tr>
</tbody>
</table>
</template>
<script>
export default
name: 'MyTable',
data()
return
// 列表的数据
list: [
id: 1, name: '张三', state: true ,
id: 2, name: '李四', state: false ,
id: 3, name: '赵六', state: false ,
],
,
</script>
<style lang="less" scoped></style>
写在最后
✨个人笔记博客✨
星月前端博客
http://blog.yhxweb.top/
✨原创不易,还希望各位大佬支持一下
👍 点赞,你的认可是我创作的动力!
⭐️ 收藏,你的青睐是我努力的方向!
✏️评论,你的意见是我进步的财富!
Vue2.0—默认插槽具名插槽作用域插槽(二十四)
【Vue2.0】—默认插槽、具名插槽、作用域插槽(二十四)
默认插槽、具名插槽
Cateory.vue文件
<template>
<div class="cateory">
<h3>title分类</h3>
<!-- 定义一个插槽,等着组件的使用者进行填充 -->
<slot name="center"> 我是一个默认值,当使用者没有传递具体结构的时候,我就会显示1</slot>
<slot name="bottom"> 我是一个默认值,当使用者没有传递具体结构的时候,我就会显示2</slot>
</div>
</template>
<script>
export default
name: 'Cateory',
props: ['title'],
</script>
<style>
.cateory
background-color: skyblue;
width: 200px;
height: 300px;
float: left;
.cateory:nth-child(2)
margin: 0 50px;
h3
text-align: center;
background-color: orange;
ul li
list-style-type: none;
</style>
App.vue文件
<template>
<div class="container">
<Cateory title="美食">
<img slot="center"
src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.zcool.cn%2Fcommunity%2F01bddd5e26a262a801216518af424f.jpg%402o.jpg&refer=http%3A%2F%2Fimg.zcool.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1640156153&t=2c7b79467b177bea9e440f6639767be5"
alt="">
<a slot="bottom" href="#">点我可以跳转</a>
</Cateory>
<Cateory title="游戏">
<ul slot="center">
<li v-for="(g,index) in games" :key="index">g</li>
</ul>
<!-- 注意:只有遇到template时,才可以使用v-slot这种写法 -->
<template v-slot:bottom>
<div class="footer">
<a href="#"> 一起来玩王者吗</a></p>
<a href="#"> 一起来玩LOL吗</a></p>
<a href="#"> 一起来玩吃鸡吗</a></p>
</div>
</template>
</Cateory>
<Cateory title="电影" :listData="films">
<img slot="center" class="cake"
src="http://gimg2.baidu.com/image_search/src=http%3A%2F%2Fup.enterdesk.com%2Fedpic_360_360%2F69%2F17%2Ff2%2F6917f22462051746bd24feb853631904.jpg&refer=http%3A%2F%2Fup.enterdesk.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1640156853&t=d9e20e3e8709b53daba8f576454a1826"
alt="">
<a slot="bottom" href="#">小黑的日常生活</a>
</Cateory>
</div>
</template>
<script>
import Cateory from './components/Cateory.vue'
export default
name: 'App',
components:
Cateory
,
data()
return
food: ['火锅', '小龙虾', '牛排'],
games: ['王者荣耀', 'LOL', '吃鸡'],
films: ['《门锁》', '《最好的我们》', '《新年好》']
</script>
<style lang="css">
img,
.cake
width: 200px;
height: 200px;
</style>
作用域插槽
理解:数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定,(games数据在Category组件中使用,但使用数据所遍历出来的结构由APP组件决定)
Cateory.vue文件
App.vue文件
以上是关于vue3插槽具名插槽作用域插槽-足够入门了!的主要内容,如果未能解决你的问题,请参考以下文章