基础效果
- 要实现以上效果,可对 el-table 进行封装,将列配置视为数组,循环 el-table-column 标签
- 模板组件
<div class="tableSlot">
<el-table :data="dataList" border>
<el-table-column
v-for="(item, index) in columns"
:key="index"
:prop="item.prop"
:label="item.label"
:width="item.width"
></el-table-column>
</el-table>
</div>
<script>
export default {
props: {
// 表格数据
dataList: {
type: Array,
default: () => [],
},
// 列配置
columns: {
type: Array,
default: () => [],
},
},
name: "tableSlot",
};
</script>
- 父组件
<div class="dataList">
<p>表格 - 嵌套渲染</p>
<tableSlot :dataList="dataList" :columns="columns"></tableSlot>
</div>
<script>
import tableSlot from "../../common/tableSlot.vue";
import axios from "axios";
export default {
name: "dataList",
components: { tableSlot },
data() {
return {
dataList: [],
// prop 为数据的 key,label 为表头
columns: [
{ prop: "id", label: "用户ID" },
{ prop: "date", label: "日期" },
{ prop: "name", label: "姓名" },
{ prop: "count", label: "金额" },
{ prop: "address", label: "地址", width: "400" },
],
};
},
mounted() {
this.getData1();
},
methods: {
getData1() {
this.dataList = [];
axios.get("/list2").then((res) => {
console.log("res", res);
if (res.status == 200) {
this.dataList = res.data;
}
});
},
},
};
</script>
添加特殊样式
- 如果想为某些列添加特殊样式,可以在 columns 中添加特殊参数
- 比如为金额列添加颜色,大于 0 的显示绿色,否则显示红色
- 比如添加操作列并回传点击事件
- 模板组件
<el-table :data="dataList" border>
<el-table-column
v-for="(item, index) in columns"
:key="index"
:prop="item.prop"
:label="item.label"
:width="item.width"
>
<template slot-scope="scope">
<template v-if="item.reset">
<!-- 特殊样式 - 数值颜色 -->
<template v-if="item.reset == 'countColor'">
<div :class="scope.row[item.prop] > 0 ? 'green' : 'red'">
{{
scope.row[item.prop] > 0
? "+" + scope.row[item.prop]
: scope.row[item.prop]
}}
</div>
</template>
<!-- 特殊样式 - 操作按钮组 -->
<template v-if="item.reset == 'operate'">
<el-button
type="text"
v-for="(itemBtn, indexBtn) in item.btns"
:key="indexBtn"
@click="handelRow(itemBtn, scope.row)"
>
{{ itemBtn }}
</el-button>
</template>
</template>
<template v-else>
<!-- 非特殊样式,直接展示 -->
{{ scope.row[item.prop] }}
</template>
</template>
</el-table-column>
</el-table>
<script>
export default {
props: {
// 表格数据
dataList: {
type: Array,
default: () => [],
},
// 列配置
columns: {
type: Array,
default: () => [],
},
},
name: "tableSlot",
methods: {
handelRow(type, row) {
console.log("点击了当前行", type, row);
this.$emit("handelRow", type, row);
},
},
};
</script>
<style lang="less" scoped>
.tableSlot {
.red {
color: red;
}
.green {
color: green;
}
}
</style>
- 父组件
<div class="dataList">
<p>表格 - 嵌套渲染</p>
<tableSlot :dataList="dataList" :columns="columns" @handelRow="handelRow"></tableSlot>
</div>
<script>
import tableSlot from "../../common/tableSlot.vue";
import axios from "axios";
export default {
name: "dataList",
components: { tableSlot },
data() {
return {
dataList: [],
// 用 reset 来标记特殊列的展示样式
columns: [
{ prop: "id", label: "用户ID" },
{ prop: "date", label: "日期" },
{ prop: "name", label: "姓名" },
{ prop: "count", label: "金额", reset: "countColor" }, // reset 标记,特殊颜色
{ prop: "address", label: "地址", width: "400" },
{
prop: "operate",
label: "操作",
width: "200",
reset: "operate",
btns: ["按钮1", "按钮2"],
}, // reset 标记,按钮组
],
};
},
mounted() {
this.getData1();
},
methods: {
getData1() {
this.dataList = [];
axios.get("/list2").then((res) => {
console.log("res", res);
if (res.status == 200) {
this.dataList = res.data;
}
});
},
handelRow(type, row) {
console.log("从表格模板传过来的点击事件", type, row);
},
},
};
</script>
- 点击表格第一行的按钮1时,可以看到,父组件可以接收到传递的参数
利用具名插槽
- 如果 reset 标记不够满足父组件中的定制化样式,还可以利用具名插槽
- 比如为姓名列添加文本内容
- 比如截取日期格式
-
可以将 columns 数组中的 prop 属性作为具名插槽的 name 来使用
-
模板组件
<template>
<div class="tableSlot">
<el-table :data="dataList" border>
<el-table-column
v-for="(item, index) in columns"
:key="index"
:prop="item.prop"
:label="item.label"
:width="item.width"
>
<template slot-scope="scope">
<template v-if="item.reset">
<!-- 特殊样式 - 数值颜色 -->
<template v-if="item.reset == 'countColor'">
<div :class="scope.row[item.prop] > 0 ? 'green' : 'red'">
{{
scope.row[item.prop] > 0
? "+" + scope.row[item.prop]
: scope.row[item.prop]
}}
</div>
</template>
<!-- 特殊样式 - 操作按钮组 -->
<template v-if="item.reset == 'operate'">
<el-button
type="text"
v-for="(itemBtn, indexBtn) in item.btns"
:key="indexBtn"
@click="handelRow(itemBtn, scope.row)"
>
{{ itemBtn }}
</el-button>
</template>
<!-- 特殊样式 - 具名插槽,去父组件展示,回传 row 的内容 -->
<template v-if="item.reset == 'slot'">
<!-- 将 prop 属性作为具名插槽的 name 来保证唯一 -->
<slot :name="item.prop" :item="scope.row"></slot>
</template>
</template>
<template v-else>
<!-- 非特殊样式,直接展示 -->
{{ scope.row[item.prop] }}
</template>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
props: {
// 表格数据
dataList: {
type: Array,
default: () => [],
},
// 列配置
columns: {
type: Array,
default: () => [],
},
},
name: "tableSlot",
methods: {
handelRow(type, row) {
console.log("点击了当前行", type, row);
this.$emit("handelRow", type, row);
},
},
};
</script>
<style lang="less" scoped>
.tableSlot {
.red {
color: red;
}
.green {
color: green;
}
}
</style>
- 父组件
<template>
<div class="dataList">
<p>表格 - 嵌套渲染</p>
<tableSlot :dataList="dataList" :columns="columns" @handelRow="handelRow">
<!-- 姓名的插槽,接收 item 值,渲染格式 【姓名】 -->
<template v-slot:name="{ item }">{{ `【${item.name}】` }}</template>
<!-- 日期的插槽,接收 item 值,渲染格式 截取掉时间中的时分秒,只保留年月日 -->
<template v-slot:date="{ item }">{{ item.date.split(" ")[0] }}</template>
</tableSlot>
</div>
</template>
<script>
import tableSlot from "../../common/tableSlot.vue";
import axios from "axios";
export default {
name: "dataList",
components: { tableSlot },
data() {
return {
dataList: [],
columns: [
{ prop: "id", label: "用户ID" },
{ prop: "date", label: "日期", reset: "slot" }, // reset 标记,插槽
{ prop: "name", label: "姓名", reset: "slot" }, // reset 标记,插槽
{ prop: "count", label: "金额", reset: "countColor" },
{ prop: "address", label: "地址", width: "400" },
{
prop: "operate",
label: "操作",
width: "200",
reset: "operate",
btns: ["按钮1", "按钮2"],
},
],
};
},
mounted() {
this.getData1();
},
methods: {
getData1() {
this.dataList = [];
axios.get("/list2").then((res) => {
console.log("res", res);
if (res.status == 200) {
this.dataList = res.data;
}
});
},
handelRow(type, row) {
console.log("从表格模板传过来的点击事件", type, row);
},
},
};
</script>