很多人知道插槽分为三种,但是实际到elementui当中为什么这么用,就一脸懵逼,接下来就跟大家聊一聊插槽在elementui中的应用,并且自己写一个类似el-table的组件
vue的slot分为三种::匿名插槽,具名插槽, 作用域插槽,主要作用:让父组件可以向子组件指定位置插入 html 结构,也是一种组件间通信的方式,适用于父组件=>子组件
1、匿名插槽
匿名组件相当于一个占位符,将父组件的数据传入子组件的slot标签内
父组件:
<template><ChildSlot>父组件调用</ChildSlot>
</template>import ChildSlot from "@/components/ChildSlot";
export default {components:{ChildSlot}
}
子组件:
<template><h1>我是子组件</h1><slot></slot>
</template>export default {name: "ChildSlot"
}
运行结果如下:
此时父组件中的“父组件调用”这段内容就传递到了子组件,并填入了slot挖的坑当中
2、具名插槽
具名插槽相当于给插槽添加了一个名字(给插槽加入name属性就是具名插槽)
父组件:
<template><child-slot><template v-slot:username>我是父组件传递的用户姓名</template></child-slot><child-slot><template v-slot:age>我是父组件传递的年龄</template></child-slot>
</template>import ChildSlot from "@/components/ChildSlot";
export default {components:{ChildSlot}
}
子组件:
<template><h1>我是子组件</h1><slot name="username"></slot><slot name="age"></slot>
</template>export default {name: "ChildSlot"
}
运行结果如下:
此时父组件中的根据slot的name,将内容填入了slot挖的坑当中,一个萝卜一个坑
3、作用域插槽
与前两者的不同 slot自定义:name="值" 子组件可向父组件传递信息
父组件:
<template><child-slot><template v-slot="{username}">我是子组件传递的用户姓名:{{username}}</template></child-slot>
</template>import ChildSlot from "@/components/ChildSlot";
export default {components:{ChildSlot}
}
子组件:
<template><h1>我是子组件</h1><slot :username="username"></slot>
</template>export default {name: "ChildSlot",data(){return{username:'java',}}
}
运行结果如下:
通过作用域插槽,我们可以将子组件中的值传入到父组件,在父组件进行数据处理后,填坑到子组件
4、模拟写一个el-table
先看一个el-table的例子,当需要对一行中的某一个单元格的内容进行处理的时候,需要用到slot插槽,例如下面的姓名name的处理
<template><el-table:data="tableData"style="width: 100%"><el-table-columnlabel="姓名"width="180"><template slot-scope="scope"><el-popover trigger="hover" placement="top"><p>姓名: {{ scope.row.name }}</p><p>住址: {{ scope.row.address }}</p><div slot="reference" class="name-wrapper"><el-tag size="medium">{{ scope.row.name }}</el-tag></div></el-popover></template></el-table-column><el-table-columnprop="address"label="地址"></el-table-column></el-table>
</template>
参照el-table,实现我们自己的table组件,讲解下为什么需要用插槽,用了哪些插槽
4.1为了传递table,首先通过匿名插槽,写一个的组件,目的就是模拟下面这三行内容
<el-table :data="tableData" style="width: 100%">
<template><div><slot></slot></div>
</template>export default {name: "MyTable"
}
4.2实现el-table-column,通过作用域插槽,写我们自己的el-table-column
<template><div><div><!--通过传递label标签,展示表头--><span v-if="label">{{ label }}</span></div><!--获取主页面的data值:$parent.$parent.$data.tableList--><div v-for="(user,index) in $parent.$parent.$data.tableList" :key="index"><!--当传递prop属性的时候,就取user用户的数据--><div v-if="prop">{{user[prop]}}</div><!--当不传递prop属性的时候,将用户的数据通过row属性,传递到父组件当中,也就是app.vue--><slot v-else :row="user"></slot></div></div>
</template>export default {name: "MyTableColumn",props: {prop: {type: String},label: {type: String}}
}
4.2调用my-table,my-table-column
我们通过my-table标签,将内容my-table和my-table-column放置到my-table的匿名插槽中,并通过子组件的props属性,接收prop和label。如同elementui一样,如果prop为空,子附件将父组件的user通过作用域插槽传递到父组件,并在父组件进行处理
<template><div><my-table :data="tableList" style="display: flex; flex-direction: row;"><my-table-column prop="name" label="姓名"></my-table-column><my-table-column prop="sex" label="性别"></my-table-column><my-table-column label="地址"><template v-slot="scope"><span style="background-color: deepskyblue">{{scope.row.address}}</span></template></my-table-column></my-table></div>
</template>import MyTable from "@/components/MyTable";
import MyTableColumn from "@/components/MyTableColumn";
export default {name: 'App',components:{MyTableColumn,MyTable},data(){return{tableList:[{name: 'java大师1',sex: '男',address: '西藏1'},{name: 'java大师2',sex: '男',address: '西藏2'},{name: 'java大师3',sex: '男',address: '西藏3'},{name: 'java大师4',sex: '男',address: '西藏4'}]}}
}
展示结果如下:
参考文章:
1、Vue插槽的使用(匿名插槽、具名插槽、作用域插槽)以及ElementUI中table-column的slot-scope应用(scope.row、scope.$index、scope.column)_table-column 插槽-CSDN博客
2、Vue -- 插槽_vue插槽-CSDN博客