基于Element封裝一個(gè)表格組件tableList的使用方法
我們項(xiàng)目中使用的表格一般都比較類似,如果不進(jìn)行封裝的話,那么每個(gè)頁面都可能有一些類似的代碼。不僅浪費(fèi)時(shí)間,而且由于開發(fā)人員不同的開發(fā)習(xí)慣。后期維護(hù)人員需要花費(fèi)一點(diǎn)時(shí)間去看每個(gè)人的代碼。所以我直接將表格做一個(gè)二次封裝,只要一個(gè)人去維護(hù)這份代碼即可。下面是我封裝的內(nèi)容
內(nèi)容:
1、支持直接傳入后臺請求地址渲染列表,且參數(shù)修改之后自動刷新
2、支持自定義每一列的顯示
3、支持根據(jù)內(nèi)容自動撐開列寬
4、支持動態(tài)篩選表頭
5、支持分頁
6、防抖
7、列權(quán)限
...
更多請自行嘗試
以下是tableList 組件的代碼
<template>
<!--刷新按鈕 和 篩選列的多選框 layout中要有 control 才顯示,默認(rèn)顯示-->
<div class="table">
<div class="table-control" v-if="layoutKey.control">
<div class="table-control-title" @click="reload">
<i class="el-icon-refresh"></i></div>
<el-dropdown class="table-control-title">
<span class="el-dropdown-link"><i class="el-icon-s-operation table-control-icon"></i></span>
<el-dropdown-menu slot="dropdown" class="table-control-checkbox">
<el-checkbox-group v-model="headItems" @change="changeChecked">
<el-checkbox class="table-control-checkbox-item"
v-for="(item,index) in allColumn"
:label="item"
:key="index">{{item}}
</el-checkbox>
</el-checkbox-group>
</el-dropdown-menu>
</el-dropdown>
</div>
<!--列表主體-->
<el-table class="table" style="width: 100%"
ref="tableList"
:data="tableData"
:defaultSort.async="defaultSort"
v-bind="$attrs"
v-on="$listeners"
@selectionChange="selectionChange"
@sort-change="sortChange">
<ex-table-column v-if="layoutKey.expand" type="expand" fixed>
<slot name="expand" :data="props" slot-scope="props"/>
</ex-table-column>
<ex-table-column v-if="layoutKey.checkBox" fixed type="selection" :width="62"
:selectable="selectable"/>
<ex-table-column v-if="layoutKey.index" type="index" label="序號" width="60"/>
<ex-table-column v-for="(column,index) in activeColumn" :key="index"
:prop="column.field"
:column-key="column.field" :label="column.title" :fixed="column.fixed"
:sortable="column.sort" :selectable="column.selectable"
:show-overflow-tooltip="column.tooltip"
:autoFit='true' :width="column.width"
:fitByClass="autoWidth(column.width)"
:minWidth="column.minWidth || defaultWidth">
<slot :name="column.field" :data="scope.row" :field="column.field" :content="column.field"
:index="index" slot-scope="scope">
<div>{{$utils.nvl(scope.row[column.field],'--')}}</div>
</slot>
</ex-table-column>
</el-table>
<!--分頁控件,layout中要有 control 才顯示,默認(rèn)顯示-->
<el-pagination background small class="table-pagination"
:current-page.sync="page.pageNo"
:page-sizes="page.list"
:page-size="page.pageSize"
:layout="page.layout" :total="page.total"
@current-change="handleCurrentChange"
@size-change="handleSizeChange" v-if="layoutKey.page"/>
</div>
</template>
<script>
import debounce from 'lodash/debounce';
import ExTableColumn from './ExTableColumn';
export default {
components: { ExTableColumn },
// 提供出來給其他組件調(diào)用,具體用法參考 vue 官方用法
provide() {
return {
tableList: this,
};
},
props: {
// 默認(rèn)的表格大小
defaultWidth: {
type: Number,
required: false,
default: 100,
},
// 顯示的控件,目前就page,control 兩個(gè)可選,可根據(jù)需求自行擴(kuò)展
layout: {
default: 'page,control',
},
// 多選時(shí) 返回的key,默認(rèn)id
checkKey: {
type: [Number, String],
default: () => 'id',
},
// 請求參數(shù),必填
req: {
type: Object,
required: true,
default: () => ({
url: undefined,
type: 'post',
params: {
query: {},
},
pageNo: 1,
pageSize: 1,
}),
},
// 默認(rèn)排序,參考 elementUI table 用法
defaultSort: {
type: [String, Object],
required: false,
},
// 列表顯示的列
// {
title : 必填 String, 顯示的列名
field : 必填 String , 列中的key
width : 選填,String 列寬,單位像素,
fixed : 選填,String 是否固定的列,可選 right, left
sort : 選填,Boolean 是否可排序
expend: 選填,Boolean 是否可展開,配置slot:expand 顯示展開內(nèi)容
limit : 選填,Boolean 權(quán)限控制,false 則不顯示
}
columns: {
type: Array,
required: true,
default: () => [{ title: '操作', field: 'ctrl', width: '60', fixed: 'right' }],
},
// 這一行的 CheckBox 是否可以勾選,用法參考elementUI table用法
selectable: {
type: Function,
default: () => true,
},
// 其他table參數(shù),都會傳給table
},
data() {
return {
layoutKey: {},
page: {
list: [5, 10, 20, 50, 100],
total: null,
pageSize: 10,
pageNo: 1,
layout: 'total,sizes,prev,pager,next,jumper',
},
tableData: [],
sort: '',
checkRows: [],
checkKeys: [],
headItems: [],
allColumn: [],
activeColumn: [],
};
},
methods: {
sortChange({ prop, order }) {
this.sort = `${prop} ${order === 'descending' ? 'desc' : 'asc'}`;
this.refresh();
},
selectionChange(selection) {
this.checkRows = selection;
this.checkKeys = [];
selection.map((row) => {
this.checkKeys.push(row[this.checkKey]);
return true;
});
this.$emit('selectionChange', selection);
},
/** **************************method*********************************** */
// 分頁
async handleCurrentChange(currentPage) {
this.page.pageNo = currentPage;
this.$emit('handleCurrentChange', currentPage);
await this.initTable({ vm: this });
},
handleSizeChange(size) {
this.page.pageSize = size;
this.page.pageNo = 1;
this.$emit('handleSizeChange', size);
this.initTable({ vm: this });
},
/** *****************************動態(tài)渲染頭部************************************* */
// 取消選中菜單
changeChecked() {
this.changeColumn({ vm: this });
},
changeColumn: debounce(async ({ vm }) => {
const that = vm;
const keys = new Set(vm.headItems);
const activeColumn = vm.columns.filter((item) => {
if (keys.has(item.title)) {
return true;
}
return false;
});
that.activeColumn = activeColumn;
that.activeColumn.splice(1, 0);
}, 200),
/** *****************************刷新************************************* */
// 刷新表格數(shù)據(jù)(使用現(xiàn)有參數(shù))
refresh(type) {
if (type === 'delete' && this.page.pageNo > 1 && this.tableData.length === 1) {
this.page.pageNo = this.page.pageNo - 1;
}
this.initTable({ vm: this });
},
// 重新加載數(shù)據(jù)(重置到第一頁)
reload() {
if (this.page.pageNo !== 1) {
this.page.pageNo = 1;
}
this.initTable({ vm: this });
},
initTable: debounce(async ({ vm }) => {
const that = vm;
that.tableData = [];
const params = that._.assign({
pageNo: that.page.pageNo,
pageSize: that.page.pageSize,
sortStr: that.sort
}, that.req.params); // 右值覆蓋左值,返回左值
// 發(fā)起請求,根據(jù)實(shí)際項(xiàng)目中,接口來做
const { data } = await window.axios[that.req.type || 'post'](that.req.url, params);
if (data && that.$utils.Type.isArray(data.result)) {
that.tableData = data.result;
that.page.total = data.total * 1;
}
that.$nextTick(() => {
that.$emit('loadDone', that.tableData, params);
});
}, 300),
getCheckRows() {
return this.checkRows;
},
getCheckKeys() {
return this.checkKeys;
},
handleHead(columns) {
const allColumn = [];
columns.map((item) => {
if (!item.limit) {
allColumn.push(item.title);
}
return true;
});
this.headItems = allColumn;
this.allColumn = allColumn;
this.changeChecked();
},
handleLayout() {
const layout = this.layout;
if (!layout) return null;
layout.split(',')
.map(
(item) => {
const key = item.trim();
this.layoutKey[key] = true;
return true;
},
);
return this.layoutKey;
},
autoWidth(width) {
if (this.$utils.isEmpty(width)) {
return 'cell';
}
return width;
},
init() {
this.handleLayout();
this.handleHead(this.columns);
if (this.defaultSort) {
const { prop, order } = this.defaultSort;
this.sort = `${prop} ${order === 'descending' ? 'desc' : 'asc'}`;
}
this.initTable({ vm: this });
}
,
},
async created() {
this.init();
},
watch: {
queryParams: {
handler() {
this.reload({ vm: this });
},
},
columns: {
handler() {
this.handleHead(this.columns);
},
},
},
computed: {
queryParams() {
if (this.$utils.isNotEmpty(this.req.params)) {
return this.req.params;
}
return {};
},
},
};
</script>
<style lang="less" scoped>
@import './style/index';
</style>
使用方法
<template>
<div>
<table-list
:req="tableReq"
ref="tableList"
:stripe="true" // table 原來的參數(shù)也是支持使用的,方法也支持使用。
:columns="[
{title:'用戶名',field:'name',sort:'true',fixed:true},
{title:'英文名',field:'aliasName',sort:'true',fixed:true},
{title:'年齡',field:'age', sort:true},
{title:'職業(yè)',field:'job', sort:true},
{title:'郵箱',field:'email'},
{title:'出生日期',field:'birthday'},
{title:'家庭住址',field:'address'},
{title:'戶籍',field:'domicile'},
]">
<!--格式化時(shí)間列,所有的列都可以這么使用,slot 名為列field-->
<template slot="birthday" slot-scope="{data}">
<span>{{format(data.birthday)}}</span>
</template>
</table-list>
</div>
</template>
<script>
import TableList from './table/components/TableList';
export default {
name: 'HelloWorld',
components: { TableList },
data() {
return {
tableReq: {
url: '/user/list', //必填
type: 'post', //可選, 默認(rèn) post
params: {} // 可選
}
};
},
methods: {
format(time) {
if (this.$utils.isEmpty(time)) return '/';
return this.$utils.format(new Date(time), 'yyyy-MM-dd HH:mm');
},
},
mounted() {
}
};
</script>
以下是顯示效果

到此這篇關(guān)于基于Element封裝一個(gè)表格組件tableList的使用方法的文章就介紹到這了,更多相關(guān)Element tableList內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue3使用vuedraggable和grid實(shí)現(xiàn)自定義拖拽布局方式
這篇文章主要介紹了vue3使用vuedraggable和grid實(shí)現(xiàn)自定義拖拽布局方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06
vue關(guān)于select組件綁定的值為數(shù)字類型的問題
這篇文章主要介紹了vue關(guān)于select組件綁定的值為數(shù)字類型的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09
Vue下滾動到頁面底部無限加載數(shù)據(jù)的示例代碼
本篇文章主要介紹了Vue下滾動到頁面底部無限加載數(shù)據(jù)的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-04-04
關(guān)于Vue3父子組件emit參數(shù)傳遞問題(解決Vue2this.$emit無效問題)
相信很多人在利用事件驅(qū)動向父組件扔?xùn)|西的時(shí)候,發(fā)現(xiàn)原來最常用的this.$emit咋報(bào)錯(cuò)了,竟然用不了了,下面通過本文給大家分享關(guān)于Vue3父子組件emit參數(shù)傳遞問題(解決Vue2this.$emit無效問題),需要的朋友可以參考下2022-07-07
vue@cli3項(xiàng)目模板怎么使用public目錄下的靜態(tài)文件
這篇文章主要介紹了vue@cli3項(xiàng)目模板怎么使用public目錄下的靜態(tài)文件,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07
vue 實(shí)現(xiàn)在函數(shù)中觸發(fā)路由跳轉(zhuǎn)的示例
今天小編就為大家分享一篇vue 實(shí)現(xiàn)在函數(shù)中觸發(fā)路由跳轉(zhuǎn)的示例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09

