vue封装背景知识小插曲之插槽slot的用法
- 一 什么是插槽slot,都可以干啥?
- 二 常见的插槽用法
一 什么是插槽slot,都可以干啥?
直白点说就是子组件使用
<slot>
先占了个地方,然后当父组件使用子组件的时候,在对应地方写上自己需求的代码即可,达到了子组件中部分代码的复用。
// 举个例子
//子组件中
<template>
<div class='child'>
// 此处子组件部分代码省略
<slot></slot>
</div>
</template>
// 父组件中使用子组件
<template>
<div>
<Child>
<div> 八八八八 <div>
</Child>
</div>
</template>
// 父组件中使用子组件
<template>
<div>
<Child>
<el-table> <el-table>
</Child>
</div>
</template>
// 父组件中使用子组件
<template>
<div>
<Child>
<el-select> <el-select>
</Child>
</div>
</template>
// 从上面例子可以看出,在父组件中,预留插槽的位置可以放任何东西,达到了子组件中部分代码复用的效果
二 常见的插槽用法
一 插槽的默认值
:我们定义插槽的时候,可以在子组件的插槽上放默认值,如果父组件中传值了,那么使用传的值,如果没有传值,则使用默认值
// 子组件中 定义插槽,并写上默认值
<button type="submit">
<slot>
提交<!-- 默认内容 -->
</slot>
</button>
// 父组件没有给插槽提供内容的时候
<SubmitButton />
<!-- 这个时候按钮的名字是 提交 -->
// 父组件给插槽提供内容
<SubmitButton> 保存 </SubmitButton>
<!-- 这个时候按钮的名字是 保存 -->
具名插槽
:有名字的插槽,可以精准的将代码插到子组件相应的位置
// 子组件 BaseLayout
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
// 父组件
<BaseLayout>
<template v-slot:header>
<!-- header 插槽的内容放这里 -->
</template>
<template v-slot:default>
<!-- main 插槽的内容放这里 -->
</template>
<template v-slot:footer>
<!-- footer 插槽的内容放这里 -->
</template>
</BaseLayout>
// 在父组件中,v-slot 有对应的简写: #,也就是说代码可以写成如下模样
<BaseLayout>
<template #header>
<!-- header 插槽的内容放这里 -->
</template>
<template #default>
<!-- main 插槽的内容放这里 -->
</template>
<template #footer>
<!-- footer 插槽的内容放这里 -->
</template>
</BaseLayout>
作用域插槽
:可以让父组件使用插槽时的内容能够访问子组件中的数据
// 参考: https://blog.csdn.net/qq_44858608/article/details/124736943
// 这篇文章写的很详细,我们提炼一下
// 如何通过作用域插槽让父组件能访问到子组件的内容?我们先看普通的情况
// 子组件 ---------Category
<template>
<div class="category">
<ul>
<li v-for="(g,index) in games" :key="index">{{g}}</li>
</ul>
</div>
</template>
<script>
export default {
name:'Category',
props:['title'],
data() {
return {
games:['红色警戒','穿越火线','劲舞团','超级玛丽'],
}
},
}
</script>
// 父组件
// 这个时候,当使用了子组件<Category>后,子组件的内容会被渲染出来,如下图
<template>
<div class="container">
<Category title="游戏"></Category>
</div>
</template>
<script>
import Category from './components/Category'
export default {
name:'App',
components:{ Category },
}
</script>
// 那作用域插槽怎么用?(如何通过作用域插槽让父组件能访问到子组件的内容)
// 子组件,绑定了数据,目的是为了传给父组件
<template>
<div class="category">
<slot :games="games" msg="hello">我是默认的一些内容</slot>
</div>
</template>
<script>
export default {
name:'Category',
props:['title'],
data() {
return {
games:['红色警戒','穿越火线','劲舞团','超级玛丽'],
}
},
}
</script>
// 父组件
// 接收到数据,并使用数据
<template>
<div class="container">
<Category title="游戏">
<template scope="atguigu">
<ul>
<li v-for="(g,index) in atguigu.games" :key="index">{{g}}</li>
</ul>
</template>
</Category>
</div>
</template>
<script>
import Category from './components/Category'
export default {
name:'App',
components:{ Category },
}
</script>
// 既然插槽作用域,能够让父组件拿到子组件插槽中的作用,但是我们可以直接写,那他存在的意义是什么呢?
// 我们可以拿到子组件给我们的数据,然后在父组件自由发挥样式,数据有了,样式可以自由发挥很多种。用于展示不用的样式效果。
// 沿用上面的子组件
// 父组件
<template>
<div class="container">
<Category title="游戏">
<template scope="atguigu">
<ul>
<li v-for="(g,index) in atguigu.games" :key="index">{{g}}</li>
</ul>
</template>
</Category>
<Category title="游戏">
<template scope="{games}">
<ol>
<li style="color:red" v-for="(g,index) in games" :key="index">{{g}}</li>
</ol>
</template>
</Category>
<Category title="游戏">
<template slot-scope="{games}">
<h4 v-for="(g,index) in games" :key="index">{{g}}</h4>
</template>
</Category>
</div>
</template>
<script>
import Category from './components/Category'
export default {
name:'App',
components:{ Category },
}
</script>