📝个人主页:五敷有你
🔥系列专栏:Vue
⛺️稳中求进,晒太阳
插槽
作用:让组件内部一些 结构 支持 自定义
插槽的分类:
- 默认插槽。
- 具名插槽。
基础语法
组件内需要定制的结构部分,改用占位
<template><div class="main"><h2>确认吗</h2><slot></slot><div class="bottom"><button>确认</button><button>取消</button></div></div>
</template>
使用组件时,标签内部,传入结构替换slot
<BaseA>我是插槽练习</BaseA>
插槽的默认值
通过插槽完成内容的定制,传什么显示什么,但是不传,则是空白
插槽的后备内容:封装组件时,可以为预留的插槽提供后备内容(默认内容)
- 语法:在slot标签内,放置内容,作为默认显示内容
- 效果:
- 外部使用组件不传东西,则slot会显示后备内容
- 外部使用组件传东西了,则slot整体会被替换掉
具名插槽(一个组件有多处结构需要外部传入标签,进行定制)
语法:
多个slot使用name属性区分名字
简写:v-slot:插槽名 简化---- #插槽名
<div class="main"><h2><slot name="head"></slot></h2><slot name="body">我是默认值</slot><div class="bottom"><slot name="foot"></slot></div></div>
template配置v-slot:名字 来分发对应标签
<BaseA><template v-slot:head>我是标题</template><template v-slot:body><p>我是身体</p></template><template v-slot:foot><button>确认</button><button>取消</button></template></BaseA>
作用域插槽
作用域插槽:定义slot插槽的同时,是可以传值的,给插槽上 可以绑定数据, 将来 使用组件时可以用
场景:封装表格组件
基本使用步骤:
1. 给slot标签,以添加属性的方式传值。
<slot :id="item.id" msg="测试文本"></slot>
2. 所有添加属性,都会收集到一个对象中
{id:3,msg:"测试文本"}
3. 在template中,通过 #插槽名='obj'接收,默认插槽名为 default
<MyTable :list="list"><template #default="obj"><button @click="del(obj.id)">删除</button></template></MyTable>
商品列表(实战):
App.vue
<template><div id="app"><MyTable :list="list"><template #thead><td>编号</td><td>图片</td><td>名称</td><td>标签</td></template><template #tbody="{item,index}" ><td>{{ index+1 }}</td><td>{{ item.img }}</td><td>{{ item.name }}</td><td><MyEle v-model="item.sign"></MyEle></td></template></MyTable></div>
</template><script>import MyEle from "./components/MyEle.vue"
import MyTable from "./components/MyTable.vue"
export default {data(){return{list:[{id:101,img:'001',name:"紫砂壶",sign:"茶具"},{id:102,img:'001',name:"皮鞋",sign:"男鞋"},{id:103,img:'001',name:"棉衣",sign:"衣服"},{id:104,img:'001',name:"毛衣",sign:"衣服"},{id:105,img:'001',name:"帽子",sign:"衣服"}]}},components:{MyEle,MyTable
},
methods:{},//局部注册指令
directives:{//指令名:指令配置项color:{inserted(el,binding){el.style.color=binding.value},update(el,binding){el.style.color=binding.value}}
},}</script><style scoped>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;text-align: center;margin-top: 60px;display: flex;justify-content: space-around;
}</style>
MyTable.vue
<template>
<div class="main"><table border="1"><thead><tr><!-- <td>编号</td><td>图片</td><td>名称</td><td>标签</td> --><slot name="thead"></slot></tr></thead><tbody><tr v-for="(item,index) in list" :key="item.id"><slot name="tbody" :item="item" :index="index" ></slot></tr></tbody></table>
</div>
</template>
<script>export default {props:{"list":Array,}
}
</script>
<style scoped></style>
Mytag.vue
<template>
<div class="main"><div class="ele" v-if="isShow" @click="isShow=false">{{ value }}</div><div v-else><input type="text" :value="value" v-focus @keyup.enter='update'></div>
</div></template>
<script>export default {props:{"value":String},data(){return {isShow:true,}},directives:{focus:{inserted(el){el.focus()}}},methods:{update(e){this.$emit("input",e.target.value)this.isShow=true}}
}
</script>
<style scoped>
.ele{text-align: center;color:rgb(50, 49, 49);font-size: 15px;
}
input{padding: 3px 4px;color:gray;font-size: 13px;
}
</style>