vue2插槽
本节目标
- 默认插槽
- 后备内容
- 具名插槽
- 作用域插槽
- 案例-商品列表
默认插槽
让组件内部的一些结构 支持自定义
步骤
- 组件内需要定制的结构, 使用<slot></slot>占位
- 使用组件时, 传入结构替换slot的位置
后备内容
封装组件时, 可以为预留的<slot>插槽提供默认内容
步骤
- 在<slot>标签内, 放置内容, 作为默认显示内容
- 使用组件时, 如果不传东西, 显示slot后备内容
- 使用组件时, 传递内容, 则slot整体会被替换掉
具名插槽
一个组件内有多处结构, 需要外部传入标签, 进行定制, 需要使用具名插槽
步骤
- 组件内的slot标签, 使用 name属性 给插槽命名
- 使用组件时, 使用 template 配合 v-slot:插槽名 来分发标签
- v-slot:插槽名 可以简写成 #插槽名
作用域插槽
定义slot插槽的同时, 是可以传值的, 给插槽上绑定数据, 使用组件时可以接收数据
组件分类
- 默认插槽(组件内定义一处结构)
- 具名插槽(组件内定义多处结构)
- 作用域插槽不是一类组件, 是插槽的传参语法
封装表格组件
- 父传子, 动态渲染表格内容
- 利用默认插槽, 定制操作列
- 删除或查看操作, 都需要用到当前项的id, 属于组件内部的数据, 可以通过作用域插槽绑定数据, 供外部使用
步骤
- 给slot标签, 以添加属性的方式传值
- 所有添加的属性, 都会被收集到一个对象中
- 在template中, 通过 #插槽名="obj" 接收数据, 默认插槽, 通过 #default="obj" 接收数据
案例-商品列表
1>分析需求
my-ta组件
- 双击显示输入框, 输入框自动获取焦点
- 失去焦点, 隐藏输入框
- 回显标签信息
- 内容修改, 回车, 修改标签信息
my-table组件
- 动态传递表格数据渲染
- 表头支持自定义
- 主体支持自定义
2>创建tag组件
<template><div class="my-tag"><!-- <input class="input"type="text"placeholder="输入标签"/> --><div class="text">茶具</div></div>
</template><script>
export default {
};
</script><style lang="less" scoped>
.my-tag {cursor: pointer;.input {appearance: none;outline: none;border: 1px solid #ccc;width: 100px;height: 40px;box-sizing: border-box;padding: 10px;color: #666;&::placeholder {color: #666;}}
}
</style>
3>控制显示隐藏
<template><div class="my-tag"><inputv-if="isEdit"v-focusclass="input"type="text"placeholder="输入标签"@blur="isEdit = false"/><div v-else class="text" @dblclick="handerEdit">茶具</div></div>
</template><script>
export default {data() {return {isEdit: false,};},methods: {handerEdit() {this.isEdit = true;},},
};
</script>
... ...// 全局注册自动获取焦点指令
Vue.directive('focus', {inserted: function (el) {el.focus()}
})
... ...
4>回显/修改数据
<template><div class="my-tag"><input... ...:value="value"@keyup.enter="inputEnter"/>... ...</div>
</template><script>
export default {// 通过v-model完成父子组件通信props: {value: String,},methods: {... ...// 监听键盘回车事件inputEnter(e) {// 非空处理if (e.target.value.trim() === "") return alert("输入不能为空");// 触发自定义事件, 更新父组件数据// 通过事件对象拿到输入的新值this.$emit("input", e.target.value);// 编辑完成后, 隐藏输入框this.isEdit = false;},},
};
</script>
<template><div class="table-case"><table class="my-table">... ...<tbody><tr><td>1</td><td>梨皮朱泥三绝清代小品壶经典款紫砂壶</td><td><img src="https://yanxuan-item.nosdn.127.net/f8c37ffa41ab1eb84bff499e1f6acfc7.jpg" /></td><td><my-tag v-model="text"></my-tag></td></tr></tbody></table></div>
</template><script>
export default {name: 'TableCase',data() {return {// 临时绑定数据,检测v-modeltext: '默认数据';}},
}
</script>
5>创建my-table组件
<template><table class="my-table"><thead><tr><th>编号</th><th>名称</th><th>图片</th><th width="100px">标签</th></tr></thead><tbody><tr v-for="item in data" :key="item.id"><td>{{ item.id }}</td><td>{{ item.name }}</td><td><img :src="item.picture" /></td><td>MyTage组件<!-- <MyTage v-model="item.tag"></MyTage> --></td></tr></tbody></table>
</template><script>
export default {props: {data: {type: Array,require: true,},},
};
</script><style lang="less" scoped>
.my-table {width: 100%;border-spacing: 0;img {width: 100px;height: 100px;object-fit: contain;vertical-align: middle;}th {background: #f5f5f5;border-bottom: 2px solid #069;}td {border-bottom: 1px dashed #ccc;}td,th {text-align: center;padding: 10px;transition: all 0.5s;&.red {color: red;}}.none {height: 100px;line-height: 100px;color: #999;}
}
</style>
<template><div class="table-case"><MyTable :data="goods"></MyTable></div>
</template><script>
export default {name: "TableCase",data() {return {goods: [{id: 101,picture:"https://yanxuan-item.nosdn.127.net/f8c37ffa41ab1eb84bff499e1f6acfc7.jpg",name: "梨皮朱泥三绝清代小品壶经典款紫砂壶",tag: "茶具",},{id: 102,picture:"https://yanxuan-item.nosdn.127.net/221317c85274a188174352474b859d7b.jpg",name: "全防水HABU旋钮牛皮户外徒步鞋山宁泰抗菌",tag: "男鞋",},{id: 103,picture:"https://yanxuan-item.nosdn.127.net/cd4b840751ef4f7505c85004f0bebcb5.png",name: "毛茸茸小熊出没,儿童羊羔绒背心73-90cm",tag: "儿童服饰",},{id: 104,picture:"https://yanxuan-item.nosdn.127.net/56eb25a38d7a630e76a608a9360eec6b.jpg",name: "基础百搭,儿童套头针织毛衣1-9岁",tag: "儿童服饰",},],};},
};
</script><style lang="less" scoped>
.table-case {width: 1000px;margin: 50px auto;img {width: 100px;height: 100px;object-fit: contain;vertical-align: middle;}
}
</style>
6>结构自定义
<template><table class="my-table"><thead><tr><slot name="header"></slot></tr></thead><tbody><tr v-for="item in data" :key="item.id"><slot name="body" :item="item"></slot></tr></tbody></table>
</template><script>
export default {props: {data: {type: Array,require: true,},},
};
</script>
<template><div class="table-case"><MyTable :data="goods"><template #header><th>编号</th><th>名称</th><th>图片</th><th width="100px">标签</th></template><template #body="{ item }"><td>{{ item.id }}</td><td>{{ item.name }}</td><td><img :src="item.picture" /></td><td><!-- MyTage组件 --><MyTage v-model="item.tag"></MyTage></td></template></MyTable></div>
</template><script>
export default {name: "TableCase",data() {return {goods: [{id: 101,picture:"https://yanxuan-item.nosdn.127.net/f8c37ffa41ab1eb84bff499e1f6acfc7.jpg",name: "梨皮朱泥三绝清代小品壶经典款紫砂壶",tag: "茶具",},{id: 102,picture:"https://yanxuan-item.nosdn.127.net/221317c85274a188174352474b859d7b.jpg",name: "全防水HABU旋钮牛皮户外徒步鞋山宁泰抗菌",tag: "男鞋",},{id: 103,picture:"https://yanxuan-item.nosdn.127.net/cd4b840751ef4f7505c85004f0bebcb5.png",name: "毛茸茸小熊出没,儿童羊羔绒背心73-90cm",tag: "儿童服饰",},{id: 104,picture:"https://yanxuan-item.nosdn.127.net/56eb25a38d7a630e76a608a9360eec6b.jpg",name: "基础百搭,儿童套头针织毛衣1-9岁",tag: "儿童服饰",},],};},
};
</script>