1. 程式人生 > 實用技巧 >對el-table和el-pagination元件二次封裝

對el-table和el-pagination元件二次封裝

  如果是以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頁面渲染出來如下:

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