组件插槽
文章目录
组件插槽基础使用--匿名插槽默认内容具名插槽作用域插槽使用场景自定义指令局部注册和使用全局注册和使用自定义指令-传值用来实现组件内容的分发,通过slot标签,可以接收到写在组件标签内的内容
vue提供组件插槽的能力,允许开发者在封装组件时,把不确定的部分定义为插槽
基础使用–匿名插槽
组件内使用slot 占位使用组件时 中间传入标签替换slotPannel.vue
<template><div><div class="title"><h4>鹅鹅鹅</h4><span @click="isShow = !isShow">{{isShow ? '收起' : '展开' }}</span></div><div class="container" v-show="isShow"><!--1: 组件内使用slot 占位 --><slot></slot></div></div></template><script>export default {data() {return {isShow: false,}},}</script><style scoped>h4 {text-align: center;}.title {display: flex;justify-content: space-between;align-items: center;border: 1px solid #ccc;padding: 0 10px;}.title h4 {line-height: 2;margin: 0;}.container {border: 1px solid #ccc;padding: 0 10px;}</style>
App.vue
<template><div><!-- 2 使用组件时 pannel 在组件中间 传入标签替换slot --><pannel><p>曲项向天歌</p><p>曲项向天歌</p><p>曲项向天歌</p><p>曲项向天歌</p><p>曲项向天歌</p></pannel><pannel><img src="./assets/logo.png" alt="" /></pannel></div></template><script>import Pannel from './components/Pannel.vue'export default {components: {Pannel },}</script>
默认内容
如果外面不给传,想给个默认显示内容
夹着内容默认显示内容,如果不给插槽slot传东西,就使用slot夹着的内容在原地显示
<slot>默认内容</slot>
具名插槽
当一个组件内有2处以上需要外部传入标签的地方
传入的标签可以分别派发给不同的slot位置
v-slot一般跟template标签使用(template是HTML5新出标签内容模板元素,不会渲染在页面上,一般被vue解析内部标签)
Pannel.vue
<template><div><div class="title"><slot name="title"></slot><span @click="isShow = !isShow">{{isShow ? '收起' : '展开' }}</span></div><div class="container" v-show="isShow"><!--1: 组件内使用slot 占位 --><slot name="content"></slot></div></div></template><script>export default {data() {return {isShow: false,}},}</script>
App.vue
<template><div><!-- 2 使用组件时 pannel 在组件中间 传入标签替换slot --><pannel><template v-slot:title><h4>鹅鹅鹅</h4></template><template v-slot:content><span>我是内容</span></template></pannel><!-- v-slot: 简写为 # --><pannel><template #title><h2>hello</h2></template><template #content><p>123</p></template></div></template>
总结:
v-slot: 可以简写为 #
slot的name属性起插槽名,使用组件时,template配合#插槽名传入具体的标签
作用域插槽
子组件里的值,在给插槽赋值时在父组件环境下使用
步骤:
子组件:在slot上绑定属性和子组件内的值使用组件时,传入自定义标签,用template和v-slot=“自定义变量名scope”scope变量名自动绑定slot上所有的属性和值
Pannel.vue
<template><div><div class="title"><!-- 1:slot上绑定属性和子组件内的值 --><slot name="title" :msg="msg" tit="nihao"></slot><span @click="isShow = !isShow">{{isShow ? '收起' : '展开' }}</span></div><div class="container" v-show="isShow"><!--1: 组件内使用slot 占位 --><slot name="content"> </slot></div></div></template><script>export default {data() {return {isShow: false,msg: 'hello world',}},}</script>
App.vue
<template><div><pannel><!--2 传入自定义标签 template和v-slot:插槽名="自定义变量名" --><template v-slot:title="scope"><!--3 scope上自动绑定slot上所有属性和值 --><h4>{{scope.tit }}</h4></template><template v-slot:content><span>我是内容</span></template></pannel><!-- v-slot: 简写为 # --><pannel><template #title><h2>hello</h2></template><template #content><p>123</p></template></pannel></div></template>
总结:
组件内变量绑定到slot上,使用组件v-slot:插槽名=“自定义变量”,变量上会自动绑定属性和值
使用场景
需求:封装一个表格组件,在表格组件内循环产生单元格
准备MyTable.vue组件—内置表格,传入数组循环铺设页面,把对象每个内容显示在单元格里App.vue组件里,准备数据传入给MyTable.vue使用分析 想要给td内显示图片,传入自定义的img标签(td中准备slot占位符,但是外面需要把图片地址赋予给src属性,在slot上把item数据进行绑定)
MyTable.vue
<template><div><table><thead><tr><th>序号</th><th>姓名</th><th>年龄</th><th>头像</th></tr></thead><tbody><tr v-for="(item, index) in list" :key="index"><td>{{index + 1 }}</td><td>{{item.name }}</td><td>{{item.age }}</td><td><slot :row="item"><!-- 默认值,使用组件不自定义标签显示默认文字 -->{{item.headImgUrl }}</slot></td></tr></tbody></table></div></template><script>export default {props: ['list'],}</script>
App.vue
<template><div><my-table :list="list"><template v-slot="scope"><img :src="scope.row.headImgUrl" width="50" alt="" /></template></my-table><my-table :list="list"><template v-slot="{ row }"><a :href="row.headImgUrl">{{row.headImgUrl }}</a></template></my-table></div></template><script>import MyTable from './components/MyTable.vue'export default {components: {MyTable },data() {return {list: [{name: '张三',age: 18,headImgUrl: '/vant/ipad.jpeg',},{name: '李四',age: 23,headImgUrl: '/vant/ipad.jpeg',},{name: '王五',age: 45,headImgUrl: '/vant/ipad.jpeg',},],}},}</script>
自定义指令
除了核心功能默认内置的指令(v-model和v-show),vue允许我们注册自定义指令。 v-xxxx
html+css的复用的主要形式是组件
你需要对普通DOM元素进行底层操作,这时候就会用到自定义指令
目标:获取标签 扩展额外的功能
局部注册和使用
只能在当前组件中使用
局部指令
directives:{
‘指令名’:{
bind(el,binding,vnode){},
inserted(el,binding,vnode){}
}
}
在标签上使用自定义指令 v-指令名
inserted 指令所在标签 被插入到页面上触发(一次)
update 指令对应的数据/标签更新时 触发
<template><div><div class="main"><input type="text" v-focus /></div></div></template><script>/*局部指令directives:{'指令名':{bind(el,binding,vnode){},inserted(el,binding,vnode){}}}在标签上使用自定义指令 v-指令名inserted 指令所在标签 被插入到页面上触发(一次)update 指令对应的数据/标签更新时 触发*/export default {directives: {// 页面加载时获取焦点focus: {inserted(el, binding, vnode) {// console.log(el)el.focus()},},}, }</script>
全局注册和使用
在任何的.vue文件中使用
main.js中用Vue.directive 全局注册指令
// 全局注册Vue.directive('gfocus', {inserted(el) {el.focus()},})
自定义指令-传值
使用自定义指令,传入一个值
需求:定义color指令,传入一个颜色,给标签设置文字颜色
<template><div><div class="main"><input type="text" v-focus /><input type="text" v-gfocus /></div><p v-color="theColor" @click="changeColor">修改文字颜色</p></div></template><script>/*局部指令directives:{'指令名':{bind(el,binding,vnode){},inserted(el,binding,vnode){}}}在标签上使用自定义指令 v-指令名inserted 指令所在标签 被插入到页面上触发(一次)update 指令对应的数据/标签更新时 触发*/export default {data() {return {theColor: 'blue',}},methods: {changeColor() {this.theColor = 'yellow'},},directives: {// 页面加载时获取焦点focus: {inserted(el, binding, vnode) {// console.log(el)el.focus()},},// 给标签设置文字颜色color: {inserted(el, binding) {el.style.color = binding.value},update(el, binding) {el.style.color = binding.value},},},}</script>
如果觉得《组件插槽和自定义属性》对你有帮助,请点赞、收藏,并留下你的观点哦!