zoukankan      html  css  js  c++  java
  • 对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页面渲染出来如下:

      当然,我这里封装的组件是相对于自己业务需求的封装,二次封装代码也很简单,最后使用的时候还得做适应的调整。

  • 相关阅读:
    Luogu P3919【模板】可持久化数组(可持久化线段树/平衡树)
    线段树||BZOJ5194: [Usaco2018 Feb]Snow Boots||Luogu P4269 [USACO18FEB]Snow Boots G
    线段树||BZOJ1593: [Usaco2008 Feb]Hotel 旅馆||Luogu P2894 [USACO08FEB]酒店Hotel
    CF 610E. Alphabet Permutations
    BZOJ 1227: [SDOI2009]虔诚的墓主人
    BZOJ1009: [HNOI2008]GT考试
    BZOJ3674: 可持久化并查集加强版
    BZOJ3261: 最大异或和
    BZOJ2741: 【FOTILE模拟赛】L
    BZOJ3166: [Heoi2013]Alo
  • 原文地址:https://www.cnblogs.com/jdWu-d/p/13689571.html
Copyright © 2011-2022 走看看