如果是以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页面渲染出来如下:
当然,我这里封装的组件是相对于自己业务需求的封装,二次封装代码也很简单,最后使用的时候还得做适应的调整。