<template>
<el-table
:data="tableData"
border
style="width: 100%">
<el-table-column
fixed
prop="date"
label="日期"
width="150">
</el-table-column>
<el-table-column
prop="name"
label="姓名"
width="120">
</el-table-column>
<el-table-column
prop="province"
label="省份"
width="120">
</el-table-column>
<el-table-column
prop="city"
label="市区"
width="120">
</el-table-column>
<el-table-column
prop="address"
label="地址"
width="300">
</el-table-column>
<el-table-column
prop="zip"
label="邮编"
width="120">
</el-table-column>
<el-table-column
fixed="right"
label="操作"
width="100">
<template slot-scope="scope">
<el-button @click="handleClick(scope.row)" type="text" size="small">查看</el-button>
<el-button type="text" size="small">编辑</el-button>
</template>
</el-table-column>
</el-table>
</template>
<script>
export default {
methods: {
handleClick(row) {
console.log(row);
}
},
data() {
return {
tableData: [{
date: '2016-05-02',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1518 弄',
zip: 200333
}, {
date: '2016-05-04',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1517 弄',
zip: 200333
}, {
date: '2016-05-01',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1519 弄',
zip: 200333
}, {
date: '2016-05-03',
name: '王小虎',
province: '上海',
city: '普陀区',
address: '上海市普陀区金沙江路 1516 弄',
zip: 200333
}]
}
}
}
</script>
代码有点多,维护起来有点痛苦。特别是当字段超过50个以后!!!为什么要对进行二次封装?
1 element-ui组件的部分样式不满足当前项目的需求
2 产品要求排序方式只有asc,desc两个,不可取消排序。
3 提高代码复用性
<template>
<ftoTable
stripe
border
@cell-click="handleitemChange"
:ajaxConfig="ajaxConfig"
:Action="Action"
height="250"
@sort-change="sorthandle"
:default-sort="sortMap"
:columns="tableHeadData" >
<template v-slot:first>
<el-table-column label="序号" type="index" width="50"></el-table-column>
</template>
</ftoTable>
</template><script>
import { getList } from "@/api/table";
import moment from "moment";
export default { filters: {
statusFilter(status) {
const statusMap = {
published: "success",
draft: "gray",
deleted: "danger"
};
return statusMap[status]; } },
data() {
return {
list: null,
listLoading: true,
activeName: "first",
queryparam: {
selectDateInfo: {},
Areacode: ""
},
tableHeadData: [ { prop: "author",
label: "作者",
className: "allowclick",
allowclick: true //允许下钻
},
{ prop: "display_time",
label: "时间",
sortable: "custom",
className: "allowclick",
allowclick: true
},
{ prop: "status",
label: "状态",
sortable: "custom"
}
],
sortMap: {
prop: "display_time",//排序字段名称
order: "descending" //倒叙
},
ajaxConfig: {
requestapi: getList,
dataKey: "items"
},
Action: "" //Action=>query 执行查询 }; }, created() {},
methods: {
fetchData() {
this.listLoading = true;
getList().then(response => {
this.list = response.data.items;
this.listLoading = false;
});
},
handleitemChange(row, column, cell, event) {
let { property } = column;
let Headitem = this.tableHeadData.find(item => item.prop == property); //处理下钻
if (Headitem.allowclick == true) {
console.log("allowclick", "aaaaaaaaa");
}
},
sorthandle() {
console.log("aaaaaaaa");
},
handleClick(tab, event) {
console.log(tab, event);
},
queryHandle() {
this.Action = "query";
setTimeout(()=>{
this.Action = "";
},500);
}
}
};
</script>
#columns 表头 必填项
#ajaxConfig 选填
#Action: "" // Action=>query 执行查询 选填
#除了这3个参数,其他用法与el-table api完成一致,妈妈再也不用担心element-ui 属性和方法更新了!
这是怎样实现的呢?
<template>
<div class="fto-table-container" v-loading="showLoading">
<el-table
ref="ftotableDatatable"
:data="tableData"
v-bind="$attrs"
v-on="$listeners" >
<slot name="first" />
<el-column v-for="(item, index) in columns" :key="index" :item="item" />
<slot />
</el-table>
</div>
</template>
<script>
import ElColumn from "./el-column";
var lang = require("lodash/lang");
import { assign } from "lodash/object";
export default {
name: "ftotableDatatable",
components: { ElColumn },
props: {
serverParams: { // 查询参数 type: Object },
columns: { // 指定表格属性 type: Array, default: () => [] },
pageParams: { type: Object, default: () => {} },
ajaxConfig: { type: Object, default: () => {} },
Action: { type: String, default: () => "" }
},
}...省略ElColumn组件做了什么操作呢?
<template>
<el-table-column :type="item.type"
:index="item.index"
:column-key="item.columnKey"
:label="item.label"
:prop="item.prop"
:width="item.width"
:min-width="item.minWidth"
:fixed="item.fixed"
:render-header="item.renderHeader"
:sortable="item.sortable || false"
:sort-method="item.sortMethod"
:sort-by="item.sortBy"
:sort-orders="['ascending', 'descending']"
:resizable="item.resizable || true"
:formatter="item.formatter"
:show-overflow-tooltip="item.showOverflowTooltip || false"
:align="item.align || 'left'"
:header-align="item.headerAlign"
:class-name="item.className"
:label-class-name="item.labelClassName"
:selectable="selectable || item.selectable"
:reserve-selection="item.reserveSelection || false"
:filters="item.filters"
:filter-placement="item.filterPlacement"
:filter-multiple="item.filterMultiple || true"
:filter-method="item.filterMethod"
:filtered-value="item.filteredValue">
<el-column v-for="(child, index) in item.children"
:key="index" :item="child" />
</el-table-column>
</template>
<script>
export default {
name: "ElColumn",
props: {
item: {
type: Object, default: () => null
},
selectable: { type: Function }
}
};
</script>核心代码只有两行,v-bind="$attrs" v-on="$listeners"
$attrs 包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。
当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class和 style 除外),
并且可以通过 v-bind="$attrs" 传入内部组件——在创建高级别的组件时非常有用。
$listener 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。
它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。