基本能滿足絕大部分的需求,利用el-table預留的2個插槽位,在里面分別又放了插槽,使之變成具名插槽,並且綁定了數據,十分靈活,表頭和表格內容全部可以自定義,添加的屬性不夠可以自己加。另外,通過屬性的透傳,el-table中的Table Attributes 和 Table Events 可以直接寫在WsTable標簽內,十分酸爽。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<!-- 引入樣式 -->
<link
rel="stylesheet"
href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"
/>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
</head>
<body>
<div id="app">
<ws-table
stripe
show-select
show-index
:table-data="tableData"
:table-columns="tableColumns"
@selection-change="selectionChange"
>
<template slot="genderHeader" slot-scope="{ scope }">
<div>
<span>{{ scope.header }}</span>
<div>
<el-select v-model="region" size="mini" placeholder="請選擇性別">
<el-option label="男" value="1"></el-option>
<el-option label="女" value="2"></el-option>
<el-option label="未知" value="3"></el-option>
</el-select>
</div>
</div>
</template>
<template slot="gender" slot-scope="{ scope }">
<div>
{{ +scope.row.gender === 1 ? "男" : +scope.row.gender === 2 ? "女" :
"未知" }}
</div>
</template>
<template #operation>
<div>
<el-button>編輯</el-button>
<el-button>刪除</el-button>
</div>
</template>
</ws-table>
</div>
<script type="text/template" id="WsTable">
<el-table
ref="WsTable"
:row-key="getRowKey"
:data="tableData"
v-bind="$attrs"
v-on="$listeners"
>
<!-- 表格序號 其實這里也可以放個具名插槽 -->
<el-table-column
v-if="showSelect"
width="50"
type="selection"
reserve-selection
></el-table-column>
<!-- 表格復選框 翻譯記憶-->
<el-table-column
v-if="showIndex"
fixed
label="序號"
width="50"
type="index"
:align="align"
></el-table-column>
<el-table-column
v-for="(col, index) in tableColumns"
v-bind="col"
:key="col.prop"
:align="col.align || align"
>
<!-- 在el-table預留的2個插槽位置分別放置插槽 實現表頭表格全部自定義,並帶有默認值 -->
<template #header="scope">
<slot :name="col.header" :scope="{ header: col.label, ...scope }">
<span>{{ col.label }}</span>
</slot>
</template>
<template #default="scope">
<slot :name="col.prop" :scope="scope">
<span>{{ scope.row[col.prop] }}</span>
</slot>
</template>
</el-table-column>
<!-- 分頁組件插槽 -->
<slot v-if="tableData.length > 10" name="pagination"></slot>
</el-table>
</script>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script>
const WsTable = {
name: "WsTable",
inheritAttrs: false,
template: "#WsTable",
props: {
// 表格數據
tableData: {
type: Array,
default: () => [],
require: true,
},
// 表格列和列屬性:
// label顯示的標題
// align對齊方式
// show-overflow-tooltip當內容過長被隱藏時顯示tooltip
tableColumns: {
type: Array,
default: () => [],
require: true,
},
// 是否顯示多選框
showSelect: {
type: Boolean,
default: false,
},
// 是否顯示索引
showIndex: {
type: Boolean,
default: false,
},
// 對齊方式
align: {
type: String,
default: "center",
},
// 行數據的 Key,用來優化 Table 的渲染
rowKey: {
type: String,
default: "id",
},
},
methods: {
getRowKey(row) {
return row[this.rowKey];
},
// 請求完接口想清空表格所選
clearSelection() {
this.$refs.WsTable.clearSelection();
},
// 對 Table 進行重新布局
doLayout() {
this.$refs.WsTable.doLayout();
},
},
};
</script>
<script>
new Vue({
el: "#app",
components: {
WsTable,
},
data: function () {
return {
region: "",
tableData: [
{
name: "張三張三張三張三張三張三張三張三張三張三張三張三張三",
age: 18,
gender: "1",
},
{
name: "李四",
age: 19,
gender: "2",
},
{
name: "王五",
age: 20,
gender: "3",
},
],
tableColumns: [
{
label: "名稱",
prop: "name",
propHeader: "nameHeader",
showOverflowTooltip: true,
},
{
label: "年齡",
prop: "age",
header: "ageHeader",
sortable: true,
width: 100,
},
{
label: "性別",
prop: "gender",
header: "genderHeader",
width: 1500,
},
{
label: "操作",
prop: "operation",
header: "operationHeader",
fixed: "right",
width: 200,
},
],
};
},
methods: {
selectionChange(selection) {
console.log("selection", selection);
},
},
});
</script>
</html>