默认插槽
有时为一个插槽设置具体的备用 (也就是默认的) 内容是很有用的,它只会在没有提供内容的时候被渲染。
<template>
<div>
<ui-input>
<!-- 在这里写了内容、插槽里面的默认内容就不显示了 -->
test
</ui-input>
</div>
</template>
<script>
import uiInput from '@/views/ccomponents/input'
export default {
components:{
uiInput
},
setup() {
},
}
</script>
uiInput.vue
<template>
<div class="ui-input">
<input type="text" placeholder="请输入内容" />
<button>
<!-- 定义插槽内的默认内容 -->
<slot>提交</slot>
</button>
</div>
</template>
<script>
export default {
setup() {},
};
</script>
<style scoped lang="less">
.ui-input {
input {
padding: 10px 15px;
border-radius: 5px;
}
button {
margin: 10px;
padding: 5px 10px;
}
}
</style>
-
默认内容
-
用户定义的
-
当组件内部有两个插槽的时候,父组件定义插槽内容就会同时渲染这两个插槽、此时就需要
具名插槽
了。
<template>
<div class="ui-input">
<button>
<slot>头部</slot>
</button>
<input type="text" placeholder="请输入内容" />
<button>
<!-- 定义插槽内的默认内容 -->
<slot>提交</slot>
</button>
</div>
</template>
<div>
<ui-input>
test
</ui-input>
</div>
2. 具名插槽
如果在封装组件时需要预留多个插槽节点、则需要为每个
<slot>
插槽指定具体的name
名称、带有具体名称的插槽叫做具名插槽
。没起名字的有隐含的名字叫做default
<div class="ui-input">
<button>
<slot name="header">头部</slot>
</button>
<input type="text" placeholder="请输入内容" />
<button>
<slot name="footer">提交</slot>
</button>
<button>
<slot></slot>
</button>
</div>
跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符
#
。
例如v-slot:header
可以被重写为#header
<div>
<ui-input>
<!-- 具名插槽 v-slot:header可使用#header-->
<template v-slot:header>头部</template>
<template #footer>尾部</template>
<!-- 默认插槽 -->
<!-- <template #default>测试</template> -->
测试
</ui-input>
</div>
3. 作用域插槽
插槽可以访问子组件中的内容、可以自定义内容。
<template>
<div class="list" v-for="(el) in list" :key="el.id">
<div class="item-list">
<slot :item="el">
<div class="id">{{el.id}}</div>
<div class="value">{{el.value}}</div>
</slot>
</div>
</div>
</template>
<script>
export default {
props:{
list:{
type:Array,
default:()=>[]
}
},
setup() {},
};
</script>
<style scoped lang="less">
.list{
.item-list{
padding: 5px 0;
border: solid 1px #999;
font-size: 20px;
display: flex;
justify-content: space-between;
div{
width: 100%;
text-align: center;
}
.id{
border-right: #999 solid 1px;
}
}
}
</style>
</style>
父组件
<table-list :list="data"></table-list>
const data=reactive([{id:'1',value:'Maria'},{id:'2',value:'Susan'},{id:'3',value:'Sam'}])
初始样式
使用作用域插槽
接收的值scope
可以随便定义、也可以解构scope
<table-list :list="data">
<template #default="scope">
<div>{{scope.item.id}}</div>
<div style="color:red">{{scope.item.value}}</div>
</template>
</table-list>
但是样式变了……
如果想样式不变、单独修改某个插槽内容可以这样写、为每一个字段提供一个插槽。
<div class="list" v-for="el in list" :key="el.id">
<div class="item-list">
<!-- <slot :item="el">
<div class="id">{{ el.id }}</div>
<div class="value">{{ el.value }}</div>
</slot> -->
<div class="id">
<slot name="id" :value="el.id">{{ el.id }}</slot>
</div>
<div class="value">
<slot name="value" :value="el.value">{{ el.value }}</slot>
</div>
</div>
</div>
<table-list :list="data">
<template #value="scope">
<span style="color:pink;"> {{ scope.value }}</span>
</template>
</table-list>