昆明网络营销服务公司优化深圳seo
文章目录
- 插槽
- 默认插槽(Default Slot)
- 具名插槽(Named Slot)
- 作用域插槽(Scoped Slot)
- 案例
插槽
- 插槽 API
- Vue 的插槽(Slot)是实现组件内容分发的一种机制,允许父组件向子组件传递自定义的内容。传什么内容,子组件就渲染什么样的内容,对组件添加属性更灵活(通过组件属性也是没有办法传递html标签的)。所以插槽是一种传递复杂内容的一种方式,通过属性是无法传递的,所以设计了插槽API.
- v-slot 指令自 Vue 2.6.0 起被引入,提供更好的支持 slot 和 slot-scope attribute 的 API 替代方案
- 如果组件中的 template 中没有包含一个
<slot>
元素,则该组件起始标签和结束标签之间的任何内容都会被抛弃。 - 插槽内可以包含任何模板代码。
- 一个不带 name 的
<slot>
出口会带有隐含的名字“default”
。
默认插槽(Default Slot)
是最简单的插槽形式,用于在子组件中预留一个位置,供父组件插入内容。子组件中通过 <slot></slot>
定义插槽位置
<!-- 子组件 ChildComponent.vue -->
<template><div class="child"><slot>默认内容</slot></div>
</template><!-- 父组件 ParentComponent.vue -->
<template><ChildComponent><p>这是父组件传递的内容</p></ChildComponent>
</template>
具名插槽(Named Slot)
- 当需要多个插槽时,可以通过 name 属性区分不同的插槽,
- 子组件中通过
<slot name="插槽名称"></slot>
定义具名插槽。 - 父组件通过
<template v-slot:插槽名称>
绑定内容
<!-- 子组件 ChildComponent.vue -->
<template><div class="child"><slot name="header">默认头部内容</slot><slot>默认主体内容</slot><slot name="footer">默认底部内容</slot></div>
</template><!-- 父组件 ParentComponent.vue -->
<template><ChildComponent><template v-slot:header><h1>这是头部内容</h1></template><p>这是主体内容</p><template v-slot:footer><p>这是底部内容</p></template></ChildComponent>
</template>
作用域插槽(Scoped Slot)
- 作用域插槽允许子组件向父组件传递数据,并让父组件决定如何渲染这些数据。
- 子组件通过 标签的 v-bind 属性传递数据。
- 父组件通过 v-slot 接收并使用这些数据。
<!-- 子组件 ChildComponent.vue -->
<template><div class="child"><slot :user="user" :message="message"></slot></div>
</template><script>
export default {data() {return {user: { name: '张三', age: 25 },message: '欢迎来到 Vue 插槽世界!'};}
};
</script><!-- 父组件 ParentComponent.vue -->
<template><ChildComponent v-slot="{ user, message }"><p>用户名:{{ user.name }}</p><p>年龄:{{ user.age }}</p><p>{{ message }}</p></ChildComponent>
</template>
案例
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head><body>
<div id="app">{{message}} {{message + message}}<div :id="message"></div><todo-list><!--todo-list 组件中不设置 slot 标签时, vue 是不知道标签 todo-item 挂在 标签 todo-list 下的在 todo-list 组件中, 添加一个 slot 标签时,就可以由开发者自定义一些渲染内容了--><todo-item @delete="handleDelete" v-for="item in list" :title="item.title" :del="item.del"><!--插槽本质上是一个函数,在组件 todo-item 中 通过 slot 标签调用了这个函数,并给这个函数传递了一个参数,也就是 value 值子组件可以传递给父组件内容的插槽叫做作用域插槽--><template v-slot:pre-icon="{value}"><span v-if="value>0.5" style="color: red">红色图标 {{value}} </span><span v-else style="color: green">绿色图标 {{value}} </span></template><!-- 如果指定了插槽时,则替换组件中 suf-icon 的默认的插槽的内容--><template v-slot:suf-icon><span>后置图标 😄</span></template></todo-item></todo-list>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>Vue.component('todo-item', {props: {title: String,del: {type: Boolean,default: false,},},template:`<li><slot name="pre-icon" :value="value"></slot><span v-if="!del">{{ title }}</span><span v-else style="text-decoration: line-through">{{ title }}</span><slot name="suf-icon">默认插槽值:0</slot><button v-show="!del" @click="handleClick">删除</button></li>`,data: function () {return {value: Math.random()}},methods: {handleClick(e) {console.log('点击删除按钮')this.$emit('delete', this.title)}},})Vue.component('todo-list', {template:`<ul><slot></slot></ul>`,data: function () {return {}},})var vm = new Vue({el: '#app',data: {message: 'hello world',list: [{title: '课程1',del: false}, {title: '课程2',del: true}],},methods: {handleDelete(val) {console.log('handleDelete', val)}}})</script>
</body></html>