先定义一个父组件todo-list,和子组件
<!-- 父组件-->
<template>
<div>
<ul>
<slot>当父组件不填充内容时候,展示这行文字</slot>
</ul>
</div>
</template>
<script>
export default {
name: 'todo-list'
}
</script>
<!-- 子组件-->
<template>
<div>
<li>
<slot name="id-slot"></slot>
<span v-if="!del">{{title}} </span>
<span v-if="del" style="text-decoration: line-through">{{title}} </span>
<slot name="time-slot"></slot>
<slot name="scope-slot" :scopeValue="value"></slot>
<button v-if="!del" @click="handleClick">删除</button>
</li>
</div>
</template>
<script>
export default {
name: 'todo-item',
props: {
// 接受参数类型,默认值
title: String,
del: {
type: Boolean,
default: false
}
},
data() {
return {
value: '已学习'
}
},
methods: {
handleClick() {
// 阻止冒泡,或者在click事件上加.stop修饰符
// e.stopPropagation()
this.$emit('delete', this.title)
}
}
}
</script>
引用组件
<template>
<div id="app">
<todo-list class="todo-list">
<todo-item v-for="item in list" :key="item.id" :title="item.title" :del="item.del">
<!-- 这里是vue2.5以下的版本写法 -->
<span slot="id-slot">{{item.id}}.</span>
<!-- vue2.6及以上版本 -->
<template v-slot:time-slot>
<span>{{item.time}}</span>
</template>
<!-- 作用域插槽可以将插槽中的值拿到父级页面中 -->
<template v-slot:scope-slot="{scopeValue}">
<span>作用域插槽:{{scopeValue}}</span>
</template>
</todo-item>
</todo-list>
</div>
</template>
<script>
import todoList from './components/TodoList.vue'
import todoItem from './components/TodoItem.vue'
export default {
name: 'App',
components: {
todoList,
todoItem
},
data() {
return {
message: 'Hello World',
list: [
{
title: '课程1',
del: false,
id: 1,
time: '2021-03-26'
},
{
title: '课程2',
del: true,
id: 2,
time: '2021-03-27'
}
]
}
},
methods: {
handleDelete(){
console.log("点击删除")
}
}
}
</script>
插槽用作内容分发,默认可以展示组件中slot的内容,若父级传入插槽内容将其覆盖
分为 匿名插槽、具名插槽和作用域插槽。
匿名插槽:<slot></slot>
具名插槽:在子组件中用name属性定义插槽名称,父级用slot
属性调用,或者添加<template v-slot:slot-name>...</template>
,在template标签里边写如要展示的内容。这是vue 2.5之前和2.6之后的两种写法。
作用域插槽:在子组件插槽中定义一个属性scopeValue,在父级获取value的值
<!-- 子组件 -->
<slot name="item-slot" :scopeValue="value"></slot>
<!-- 父级 -->
<template v-slot:item-slot="{scopeValue}">
<span>{{scopeValue}}</span>
</template>
总结:插槽传递复杂内容的方式,模版中无法传递复杂属性,用slot传递