对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页面渲染出来如下:

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章