vue-插槽使用
一. 概述项目开发中想封装一个好用的列表组件,思考到怎么在一个组件中实现不同的样式和细微差别呢,想到了vue插槽功能符合我的预想。遇到了一个问题入坑了
一. 概述
项目开发中想封装一个好用的列表组件,思考到怎么在一个组件中实现不同的样式和细微差别呢,想到了vue插槽功能符合我的预想。
注意:遇到了一个问题入坑了?,按照官方文档说明写的例子,还报错,倒腾了一天,各种百度都没有解决。突然想到可能跟vue版本有关,本地项目vue版本2.5.16,看的官方文档插槽的教程是2.6.0以上新写法。血的教训还是要仔细看文档,及时升级一下项目。下面笔记基于vue版本2.6.0以上的语法。
二. 注意事项
- 如果在子组件中不定义分发内容的出口slot,即使在使用子组件时候,里面书写内容了也会被抛弃。
// app.vue
<template>
<section>
<my-list>
<h2>定制内容</h2> // 这部分内容会被抛弃
</my-list>
</section>
</template>
<script>
export default {
components: {
myList: {
template: '<div>子组件</div>' //这里没有定义slot出口
}
},
}
</script>
三. 编译作用域
使用场景:在插槽中能使用父容器里数据,但是不能使用子组件里的作用域(数据)。
注意:父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
//app.vue
<template>
<section>
<my-list>
<h2>{{title}}</h2>
</my-list>
</section>
</template>
// app.vue
<script>
export default {
components: {
myList: {
template: '<div>子组件<slot></slot></div>'
}
},
data() {
return {
title: '父作用域的变量',
}
}
}
</script>
四.后备内容,俗称默认内容
使用场景:一般我们操作按钮button,会根据不同情况显示不同内容,在我们没有设置状态的希望会给出一个默认文本。
用法:想给插槽设置一个默认值,只有当没有分发内容时候被渲染。
//app.vue
<template>
<section>
<my-list></my-list>
</section>
</template>
<script>
export default {
components: {
myList: {
template: '<div>子组件<slot>默认文本</slot></div>'
}
},
data() {
return {
title: '父作用域的变量',
}
}
}
</script>
五.具名插槽
使用场景:一个模版需要多个插槽。
用法: 元素有一个特殊的特性:name。这个特性可以用来定义额外的插槽。一个不带 name 的 出口会带有隐含的名字“default”。
//app.vue
<template>
<section>
<my-list>
<template v-slot:header>name:header具名插槽</template>
<div>内容被放到默认插槽中</div>
</my-list>
</section>
</template>
<script>
export default {
components: {
myList: {
template:
`<div>
<slot name="header"></slot>
<slot></slot>
</div>`
}
},
}
</script>
六. 作用域插槽
使用场景:想要插槽内的内容访问子组件中才有的数据。
用法:绑定在 元素上的特性被称为插槽 prop。现在在父级作用域中,我们可以给 v-slot 带一个值来定义我们提供的插槽 prop 的名字
// table.vue
<template>
<section>
<div class="header">
<slot name="pageHeader" v-bind:info="title">
默认头部
</slot>
</div>
<div class="main">
<slot name="main"></slot>
</div>
<div class="footer">
<slot name="pageFooter">
默认底部
</slot>
</div>
</section>
</template>
<script>
export default {
data () {
return {
title: '子组件表格头部'
}
}
}
</script>
<style lang="scss" scoped>
.header{
color: #35abdd;
text-align: center;
padding: 10px;
}
.table{
padding: 10px;
border: 1px solid #c1baba;
.table-item{
display: flex;
flex-direction: row;
justify-content: space-around;
border-bottom: 1px solid #c1baba;
span {
display: block;
text-align: center;
padding: 10px;
}
}
}
.footer{
margin-top: 20px;
text-align: center;
padding: 10px;
color: #a8b6bc;
}
</style>
// app.vue
<template>
<div class="home">
<div class="body">
<my-table>
<template #pageHeader="propsData">
----定制头部----
<div>{{propsData.info}}</div>
</template>
<template #main>
<ul class="table">
<li
class="table-item"
v-for="(item,index) of peopleArr"
:key="index +'peo'">
<span>{{item.name}}</span>
<span>{{item.age}}</span>
</li>
</ul>
</template>
</my-table>
</div>
</div>
</template>
<script>
// @ is an alias to /src
import myTable from '@/components/table.vue'
export default {
name: 'home',
components: {
myTable,
},
data () {
return {
peopleArr: [
{ name: '徐开心', age: 13 },
{ name: '大韩', age: 6 },
{ name: '民国', age: 6 },
{ name: '万岁', age: 6 }
]
}
},
}
</script>
七. 具名插槽的缩写
使用场景:命令只有在有参数的时候才可以用缩写语法。#=“user”这种写法非法。正确写法:#default=“user”。
用法:v-slot:替换为字符 #,v-slot:header,可以写成 #header
更多推荐
所有评论(0)