使用element-ui怎么封装一个Table模板组件
今天就跟大家聊聊有關使用element-ui怎么封裝一個Table模板組件,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
大家在做后臺管理系統的時候,寫的最多的可能就是表格頁面了,一般分三部分:搜索功能區、表格內容區和分頁器區。一般這些功能都是使用第三方組件庫實現,比如說element-ui,或者vuetify。這兩個組件庫都各有各的優點,但就table組件來說,我還是比較喜歡vuetify的實現,不用手寫一個個column,只要傳入headers的配置數組就行,甚至分頁器都內置在了table組件里,用起來十分方便。有興趣可以看看:vuetify data table。
上面是一個經典的用element-ui開發的table頁面,而且實際工作中如果每個table頁面都寫一遍,重復代碼太多了,所以不妨寫一個table模板組件,減少重復代碼。我的思路是這樣的:
搜索功能區:
提供searchBar插槽,可以自定義搜索輸入框,搜索、重置按鈕必有,新增按鈕通過props控制顯隱。這里對應的代碼如下:
genSearchBar(){
if(this.noSearchBar||!this.$scopedSlots.searchBar)return'';
return(
<el-formclass="seatch-form"inline={true}label-width="100">
{this.$scopedSlots.searchBar()}
<el-button
class="filter-item"
icon="el-icon-search"
type="primary"
onClick={this.handleSearchBtnClick}
>
查詢
</el-button>
<el-button
class="filter-item"
icon="el-icon-refresh"
onClick={this.handleResetBtnClick}
>
重置
</el-button>
<el-button
class="filter-item"
icon="el-icon-plus"
type="primary"
v-show={this.showAddBtn}
onClick={this.handleAddBtnClick}
>
新增
</el-button>
</el-form>
);
}
表格內容區:
通過傳入headers自動生成columns,參數如下:
{
label:'性別',
prop:'sex',
width:'180',
filter:'sexFilter'
}
可對應如下代碼:
<el-table-column
prop="sex"
label="性別"
width="180">
<templateslot-scope="scope">{{scope.row.sex|sexFilter}}</template>
</el-table-column>
注意,只支持全局filter。
如果你想自定義column,也提供tableColumn插槽,支持自定義column,可以如下配置:
{
prop:'action'
}
<el-table-column prop="action" label="操作" width="180"> <templateslot-scope="scope"> <el-button>編輯</el-button> <el-button>刪除</el-button> </template> </el-table-column>
這樣,就會按傳入的prop匹配對應的column,十分方便。
實現代碼如下:
genTableSlot(h){
letcustomeColumns=this.$scopedSlots.tableColumn
?this.$scopedSlots.tableColumn()
:[];
returnthis.headers.map((item)=>{
//根據item.prop判斷是否使用傳入的插槽內容
letfoundItem=customeColumns.find(
(ele)=>
ele.componentOptions&&
ele.componentOptions.propsData.prop===item.prop
);
returnfoundItem
?foundItem
:h('el-table-column',{
props:{
...item,
},
scopedSlots:{
default:(props)=>{
//根據傳入的全局filter處理column數據
letfilter=this.$options.filters[
item.filter
];
letitemValue=props.row[item.prop];
returnh(
'span',
filter?filter(itemValue):itemValue
);
},
},
});
});
}
genTable(h){
returnh(
'el-table',
{
ref:'tableRef',
props:{
...this.$attrs,
data:this.data,
},
on:{
'selection-change':(val)=>{
this.$emit('selection-change',val);
},
},
},
[...this.genTableSlot(h)]
);
}
分頁器區:
如無特殊需求,分頁器功能一致,所以直接內置。
實現代碼如下:
genPagination(){
return(
<divclass="pagination-wrap">
<el-pagination
layout="total,prev,pager,next,jumper"
current-page={this.current}
page-size={this.pageSize}
total={this.total}
{...{
on:{'current-change':this.handleCurrentChange},
}}
></el-pagination>
</div>
);
}
最后附完整代碼和demo:
<script>
exportdefault{
name:'TableTemplate',
props:{
data:{
type:Array,
default:()=>[],
required:true,
},
headers:{
type:Array,
default:()=>[],
required:true,
},
current:{
type:Number,
default:1,
},
pageSize:{
type:Number,
default:10,
},
total:{
type:Number,
default:0,
},
noSearchBar:Boolean,
showAddBtn:Boolean,
},
mounted(){
this.$nextTick(()=>{
this.$emit('search');
});
},
methods:{
genSearchBar(){
if(this.noSearchBar||!this.$scopedSlots.searchBar)return'';
return(
<el-formclass="seatch-form"inline={true}label-width="100">
{this.$scopedSlots.searchBar()}
<el-button
class="filter-item"
icon="el-icon-search"
type="primary"
onClick={this.handleSearchBtnClick}
>
查詢
</el-button>
<el-button
class="filter-item"
icon="el-icon-refresh"
onClick={this.handleResetBtnClick}
>
重置
</el-button>
<el-button
class="filter-item"
icon="el-icon-plus"
type="primary"
v-show={this.showAddBtn}
onClick={this.handleAddBtnClick}
>
新增
</el-button>
</el-form>
);
},
genTableSlot(h){
letcustomeColumns=this.$scopedSlots.tableColumn
?this.$scopedSlots.tableColumn()
:[];
returnthis.headers.map((item)=>{
//根據item.prop判斷是否使用傳入的插槽內容
letfoundItem=customeColumns.find(
(ele)=>
ele.componentOptions&&
ele.componentOptions.propsData.prop===item.prop
);
returnfoundItem
?foundItem
:h('el-table-column',{
props:{
...item,
},
scopedSlots:{
default:(props)=>{
letfilter=this.$options.filters[
item.filter
];
letitemValue=props.row[item.prop];
returnh(
'span',
filter?filter(itemValue):itemValue
);
},
},
});
});
},
genTable(h){
returnh(
'el-table',
{
ref:'tableRef',
props:{
...this.$attrs,
data:this.data,
},
on:{
'selection-change':(val)=>{
this.$emit('selection-change',val);
},
},
},
[...this.genTableSlot(h)]
);
},
genPagination(){
return(
<divclass="pagination-wrap">
<el-pagination
layout="total,prev,pager,next,jumper"
current-page={this.current}
page-size={this.pageSize}
total={this.total}
{...{
on:{'current-change':this.handleCurrentChange},
}}
></el-pagination>
</div>
);
},
resetPagination(){
this.$emit('update:current',1);
},
handleCurrentChange(val){
this.$emit('update:current',val);
this.$emit('search');
},
handleSearchBtnClick(){
this.$emit('search');
},
handleResetBtnClick(){
this.resetPagination();
this.$emit('reset');
},
handleAddBtnClick(){
this.$emit('add');
},
getTableRef(){
returnthis.$refs.tableRef;
},
},
render(h){
return(
<div>
{this.genSearchBar()}
{this.genTable(h)}
{this.genPagination()}
</div>
);
},
};
</script>
<stylescoped>
.seatch-form{
text-align:left;
}
.pagination-wrap{
margin-top:20px;
text-align:right;
}
</style>
Demo:
<template>
<div>
<table-template
border
:headers="headers"
:data="tableData"
:current.sync="current"
:total="total"
ref="tableTemplate"
showAddBtn
@search="handleSearch"
@reset="handleReset"
@add="handleAdd"
@selection-change="handleSelectionChange"
>
<template#searchBar>
<el-form-itemlabel="姓名:"prop="title">
<el-inputclass="filter-item"v-model="searchForm.title"></el-input>
</el-form-item>
</template>
<template#tableColumn>
<el-table-column
prop="selection"
type="selection"
width="55"
></el-table-column>
<el-table-columnprop="test"label="姓名"width="180">
<templateslot-scope="scope">
<el-popovertrigger="hover"placement="top">
<p>姓名:{{scope.row.name}}</p>
<p>住址:{{scope.row.address}}</p>
<divslot="reference"class="name-wrapper">
<el-tagsize="medium">{{scope.row.name}}</el-tag>
</div>
</el-popover>
</template>
</el-table-column>
</template>
</table-template>
</div>
</template>
<script>
importTableTemplatefrom'./TableTemplate';
exportdefault{
name:'Demo',
components:{
TableTemplate,
},
data(){
return{
current:1,
total:100,
headers:[
{
prop:'selection',
},
{
label:'姓名',
prop:'name',
width:'100',
},
{
label:'年齡',
prop:'year',
},
{
label:'性別',
prop:'sex',
width:'sexFilter',
},
{
prop:'test',
},
],
tableData:[
{
name:'curry',
year:18,
sex:'female',
address:'天安門',
},
],
searchForm:{
title:'',
},
};
},
methods:{
handleSearch(){
console.log(this.current);
},
handleReset(){
this.searchForm={
title:'',
};
},
handleAdd(){
console.log('添加');
},
handleSelectionChange(val){
console.log(val);
},
getTableRef(){
console.log(this.$refs.tableTemplate.getTableRef());
},
},
};
</script>
總結
以上是生活随笔為你收集整理的使用element-ui怎么封装一个Table模板组件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NetBeans eclipse比較
- 下一篇: 用epl的開源產品開發,可以閉源