前言:
如果你不了解什么是slot,建议先去补知识:
【建议参考的好文】(虽然文中的语法是vue2,现在已经是vue3,但是概念和思路讲得十分清楚:)Vue中slot与slot-scope的理解及使用
【官方文档】:插槽
简单来说,slot就是一个可以被替换的接口(插座)
,
例如:
有天我写了一个机器人,并在机器人的心留下了一个插槽(slot)。如果我想做一个牛心的机器人
,那么我就定义一个牛心
,然后将牛心
加到机器人身上。
当机器人运行到使用心脏
的位置时,读取到这里插入了一个牛心
,于是机器人将牛心的插入使用程序
调出来,插入一颗牛心并继续运作。
如果有天牛心变质了,我想换别的,我只要在放机器人心脏的地方,再放一颗别的什么替代品,例如机械心脏
即可,而不用再去机器人心脏的地方挖个洞。
使用v-for
循环和slot
进行优化el-table
构造
el-table的父子结构 的时候,可以有好几种方式。其中一种就是根据下面的博客,写出来的:
使用了 v-for
来优化模版中的 el-table-column,
将每一列作为一个配置项传入,然后再巧用 slot
,为 el-table
封装一层。
定义一个el-table
,按列初始化,如果该column
是外部传入的插槽类型,则使用外部定义的插槽来设置这个列名
下面的空格里面的内容;
例如:
如果插槽(slot
)是一个按钮,那么初始化列后,则将对应的空白部分,替换成按钮。
这样一来,原本只能放文本
的table,就落入了我们手中,可以任意地进行定制。
具体实现代码:
table.vue
// my-table.vue
<template>
<el-table :data="data">
<template v-for="colConfig in colConfigs" :key="colConfig.prop" >
<!--插槽类型,读取colConfig作为插槽名,用:data来将列名colConfig.data.label传到外面-->
<slot v-if="colConfig.slot" :name="colConfig.slot" :data="colConfig">
</slot>
<!--当不是插槽类型的列时,直接使用 label作为列名,读取data的每一个prop作为列的内容-->
<el-table-column
v-if="!colConfig.slot"
:prop="colConfig.prop"
:label="colConfig.label"
:width="colConfig.width"
></el-table-column>
</template>
</el-table>
</template>
<script>
export default {
props: ["colConfigs", "data"],
mounted() {},
methods: {
test() {},
},
};
</script>
TableList.vue
<template>
<my-table :data="tableData" :col-configs="colConfigs">
<!--定义一个插槽(slot),列名为 :label="colConfig.data.label" ,列里的值的标记为 :prop="colConfig.data.prop",列宽度被设置为:
:width="colConfig.data.width" 并且这个插槽slot里放了一个按钮-->
<template #opt="colConfig">
<el-table-column
:prop="colConfig.data.prop"
:label="colConfig.data.label"
:width="colConfig.data.width"
>
<el-button size="mini" @click="Test(colConfig)">
{{ colConfig.data.label }}
</el-button>
</el-table-column>
</template>
<!--定义一个插槽(slot),列名为 :label="colConfig.data.label" ,列里的值的标记为 :prop="colConfig.data.prop",列宽度被设置为:
:width="colConfig.data.width" 并且这个插槽slot里放了一个输入框-->
<template #input="colConfig"
><el-table-column
:prop="colConfig.data.prop"
:label="colConfig.data.label"
:width="colConfig.data.width"
>
<el-input type="textarea" v-if="true" placeholder="colConfig.data.label">
}</el-input
>
<span v-else>{{ scope.row.actionmethod }}</span>
</el-table-column>
</template>
</my-table>
</template>
<script>
import myTable from "./table.vue";
export default {
methods: {
Test(data) {
console.log(data);
},
},
components: { myTable },
data() {
this.colConfigs = [
{
prop: "date",
label: "日期",
width: 160,
editable: true,
},
{ prop: "name", label: "姓名", width: 150, editable: true },
{ prop: "address", label: "地址", width: 180, editable: true },
{ prop: "info", label: "信息", width: 180, editable: true },
{
prop: "type",
label: "类型",
width: 270,
editable: true,
chooseble: false,
slot: "input",
resize: "both",
},
{ prop: "test", label: "测试", width: 140, slot: "opt" },
// 模版中的元素需要对应的有 slot="opt" 属性
];
return {
tableData: [
{
date: "2016-05-02",
name: "王小虎",
address: "上海市普陀区金沙江路 1518 弄",
type: 12312,
info: 1212312312312312312312,
test: 123,
},
{
date: "2016-05-04",
name: "打磨",
address: "西岸",
},
],
};
},
};
</script>
不过这个实现并不能谈上好,
因为当我们使用数据的时候就会 发现,插槽的位置十分尴尬,导致这里的数据无法获取为真正的data里面的数据