如果是以elementUI作后管系統的UI庫的話,很多頁面基本都會用到el-table和el-pagination這兩個組件用於數據的表格顯示和分頁,但是這個兩個組件相對獨立,於是再寫了N次的el-table和el-pagination之后,我覺得是是時候需要把這兩個東西封裝起來了。對於我個人來說,是不喜歡封裝組件的,雖然個人用起來很舒服,html標簽可以少寫很多,但是代碼有時不是為了自己而寫,因為考慮到之后如果接手你項目的攻城獅不會用或是用不習慣,那你抽成組件就反而是畫蛇添足了。哈哈,主要還是像我后端同事說的,不會用還不是因為文檔沒寫清楚,寫的詳細不就好了,你就是懶。
按照產品經理說過的一致性原則,我們有些樣式都可以css寫好,反正是需要保持用戶邏輯使用一致的。先上一個el-table-pagination組件的代碼:
<template>
<div>
<el-table
:data="tableData"
:height="$attrs['height']"
:highlight-current-row="$attrs['highlight-current-row']"
v-bind="$attrs"
v-on="$listeners"
@row-click="rowClick"
:header-cell-style="{background:'#F3F4F7',height:'40px'}">
<template v-for="item in columnData">
<slot v-if="item.filters">
<el-table-column
:type="item.type"
:prop="item.prop"
:label="item.label">
<template slot-scope="scope">
<span>{{ filter(scope.row[scope.column.property],item.filters) }}</span>
</template>
</el-table-column>
</slot>
<slot v-else>
<el-table-column
:type="item.type"
:prop="item.prop"
:label="item.label">
</el-table-column>
</slot>
</template>
</el-table>
<div class="tableButtons">
<slot name="tableButtons" style="float:right"></slot>
</div>
<el-pagination
class="pagination"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page.sync="currentPage"
:page-sizes="[10, 15, 20]"
:page-size="pagesize"
:total="total"
></el-pagination>
</div>
</template>
<script>
export default {
props: {
// 分頁數據總數
total: {
type: Number,
default: 0,
required: false
},
// 單頁數據量
pagesize: {
type: Number,
default: 10,
required: false
},
// 當前頁碼
currentPage: {
type: Number,
default: 1,
required: false
},
// 表格數據
tableData: {
type: Array,
default:()=>[],
required: false
},
// 表頭數據
columnData: {
type: Array,
required: true
},
},
data() {
return {
currentRow:{}
}
},
methods: {
rowClick(row){
this.currentRow=row;
},
rowClickedCheck(str){
if(JSON.stringify(this.currentRow)!='{}'){
eval(str);
return true;
}else{
this.$message.error('請選擇某一行數據')
return false;
}
},
handleCurrentChange: function (currentPage) {
this.$emit('handleChange', this.pagesize, currentPage)
},
handleSizeChange: function (pageSize) {
this.$emit('handleChange', pageSize, this.currentPage)
},
filter(val,filterName) {
let filterObj = this.$options.filters[filterName]
return filterObj(val)
}
}
}
</script>
<style scoped>
.tableButtons{
float: right;
margin-top:20px;
}
.pagination{
text-align: center;
margin-top:20px;
margin-bottom: 30px;
}
</style>
然后,再貼上一個demo來展示如何使用:
<template>
<div>
<h2>Demo</h2>
<el-table-pagination
ref="elTP"
height="600"
:columnData="columnData"
:tableData="tableData"
:total="total"
:highlight-current-row= "true"
:pagesize="pagesize"
:currentPage="currentPage"
@handleChange="handleChangeData">
<template slot="tableButtons">
<el-button type="primary" @click="operation()">操作</el-button>
</template>
</el-table-pagination>
</div>
</template>
<script>
export default {
inject:['reload'],
components: {
'el-table-pagination': () => import('@/components/el-table-pagination'),
},
data(){
return{
tableData:[],
columnData:[{
prop:'Id',
label:'序號'
},{
prop:'Name',
label:'名稱'
}],
total: 0,
pagesize: 10,
currentPage: 1 ,
}
},
methods: {
handleChangeData (pagesize, currentPage) {
this.pagesize = pagesize;
this.currentPage = currentPage;
this.getNewData();
},
getNewData(){
var params={
pageSize:this.pagesize,
pageNum:(this.currentPage-1)*this.pagesize
};
this.$axios.get("/XXXX/xxxx", {params:params}).then(data => {
this.tableData = data.responseData.data ;
this.total= data.responseData.totalNum ;
});
},
operation(){
if(this.$refs.elTP.rowClickedCheck()==true){
console.log("目前選中行的數據為:"+this.$refs.elFTP.currentRow);
}
}
},
mounted:function(){
this.getNewData();
},
}
</script>
然后需要Vue.component()方法注冊全局組件,這里就不推薦局部注冊了,畢竟組件封裝出來就是為了共用。最后,demo頁面渲染出來如下:

當然,我這里封裝的組件是相對於自己業務需求的封裝,二次封裝代碼也很簡單,最后使用的時候還得做適應的調整。
