2020-12-18整理自己的封装表格数据思路

<template>
    <div class="search-card" :style="{'--expand':expandPadding}">
        <searchForm @searchQuery="search" :formConf="formConf" v-if="formConf.length" @resetAll="resetAll" :selectOptions="selectOptions" @initSearch="initSearch"
         @btnMoreAction="btnMoreAction" :btnMore="btnMore" @change="change"/>
        <div class="table-list" name="列表">
            <div class="table-padding_both">
                <el-table
                    class="c-table kyol-table_empty kyol-table_fixed"
                    :max-height="tableMaxHeight"
                    :data="tableData"
                    style="width: 100%"
                    @filter-change="filterChange"
                    @select="select"
                    @select-all="select"
                    v-loading="loading"
                    v-if="showTbale"
                    ref="pushTable"
                    :height="tableHeight"
                    >                     
                    
                    <template v-if="showTitle">                        
                        <el-table-column :label="showTitle" header-align="center">
                            <!-- 多选 -->
                            <el-table-column v-if="showSelection" type="selection" fixed="left" :selectable="selectable"> </el-table-column>
                            <!-- 索引列 -->
                            <el-table-column v-if="showIndex"  type="index" :label="showIndex.label || '序号'" :header-align="showIndex.headerAlign || 'left'" :align="showIndex.align || 'left'" :fixed="showIndex.fixed" :width="showIndex.width || '60px'"/>                   
                            <!-- 扩展内部展示块 -->
                            <el-table-column type="expand" v-if="showExpand">
                                <template slot-scope="{row,$index}">
                                    <slot :name="showExpand" :row="row" :index="$index"/>
                                </template>
                            </el-table-column> 
                            <template v-for="(item,i) in tableConf">
                                <!-- 正常列 -->
                                <template v-if="!item.insertHeader">
                                    <el-table-column :key="'tab'+i" :prop="item.prop" :label="item.label" :width="item.width" :filters="item.filters" :min-width="item.minWidth"
                                    :header-align="item.headerAlign||'left'" :align="item.align || 'left'" :column-key="item.columnKey" show-overflow-tooltip>
                                        <template slot-scope="{row}">
                                            <div class="eslpse">
                                                <!-- 正常的 如果带入函数 返回值 则使用函数带入 -->
                                                <span v-if="!item.money" :style="{color:item.colors ? item.colors.get(row[item.prop]) : ''}">{{row[item.prop] ?  item.func ? item.func(row[item.prop]) : row[item.prop] : defaultValue }}</span>
                                                <!-- 列配置 money为真 则 金钱格式化 -->
                                                <span v-else>{{row[item.prop] | toMoney | addMoneyPre}}</span>
                                            </div>
                                        </template>
                                    </el-table-column>
                                </template>
                                
                                <!-- 过滤器列 -->
                                <el-table-column :key="'tab'+i" v-else width="160px">
                                    <template slot="header" slot-scope="{column,$index}">
                                        <div class="kyol-column_header" v-if="!item.slotHeadName">
                                            <selectDataRange @search="dateQuery" :columnKey="item.columnKey" :columnName="item.label" ></selectDataRange>
                                        </div>
                                        <slot :name="item.slotHeadName" :column="column" :index="$index" v-else/>
                                    </template>
                                    <template slot-scope="{row}">
                                        <div>
                                            {{row[item.prop]}}
                                        </div>
                                     </template>
                                </el-table-column>
                                </template>
                                <slot name="lastColumn" v-if="lastColumn">
                                    <el-table-column
                                        header-align="center"
                                        align="center"
                                        label="操作"
                                        fixed="right"
                                        >
                                        <template slot-scope="{row,$index}">
                                            <div v-if="!btnSlot">
                                                <template v-for="(btn,btn_i) in (btns || row.btns || [])"> 
                                                    <el-button :key="btn_i" type="text" @click="handlerClick(row,$index)" :style="{color:btn.color}" v-if="!btn.hide || !row.hideBtns.includes(btn.label)">{{btn.label}}</el-button>     
                                                </template>
                                            </div>
                                            <div v-else>
                                                <slot name="btnSlot" :row="row" :index="$index"></slot>
                                            </div>
                                        </template>
                                    </el-table-column>
                                </slot>
                        </el-table-column>
                    </template>
                    <!-- 下面是没有带有表头标题的表格 -->
                    <template v-else>
                        <!-- 多选 -->
                        <el-table-column v-if="showSelection" type="selection" fixed="left" :selectable="selectable"> </el-table-column>
                         <!-- 索引列 -->
                        <el-table-column v-if="showIndex"  type="index" :label="showIndex.label || '序号'" :header-align="showIndex.headerAlign || 'left'" :align="showIndex.align || 'left'" :fixed="showIndex.fixed" :width="showIndex.width || '60px'"/>                   
                        <!-- 扩展内部展示块 -->
                        <el-table-column type="expand" v-if="showExpand">
                            <template slot-scope="{row,$index}">
                                <slot :name="showExpand" :row="row" :index="$index"/>
                            </template>
                        </el-table-column> 
                        <template v-for="(item,i) in tableConf">
                            <!-- 正常列 -->
                            <template v-if="!item.insertHeader">
                                <el-table-column :key="'tab'+i" :prop="item.prop" :label="item.label" :width="item.width" :filters="item.filters" :min-width="item.minWidth"
                                :header-align="item.headerAlign||'left'" :align="item.align || 'left'" :column-key="item.columnKey" show-overflow-tooltip>
                                    <template slot-scope="{row}">
                                        <div class="eslpse">
                                            <!-- 正常的 如果带入函数 返回值 则使用函数带入 -->
                                            <span v-if="!item.money" :style="{color:item.colors ? item.colors.get(row[item.prop]) : ''}">{{row[item.prop] ?  item.func ? item.func(row[item.prop]) : row[item.prop] : defaultValue}}</span>
                                            <!-- 列配置 money为真 则 金钱格式化 -->
                                            <span v-else>{{row[item.prop] | toMoney | addMoneyPre}}</span>
                                        </div>
                                    </template>
                                </el-table-column>
                            </template>
                            
                            <!-- 过滤器列 -->
                            <el-table-column :key="'tab'+i" v-else :width="item.width || '160px'">
                                <template slot="header" slot-scope="{column,$index}">
                                    <div class="kyol-column_header" v-if="!item.slotHeadName">
                                        <selectDataRange @search="dateQuery" :columnKey="item.columnKey" :columnName="item.label" ></selectDataRange>
                                    </div>
                                    <slot :name="item.slotHeadName" :column="column" :index="$index" v-else/>
                                </template>
                                <template slot-scope="{row}">
                                    <div>
                                        {{row[item.prop]}}
                                    </div>
                                </template>
                            </el-table-column>
                        </template>
                        <slot name="lastColumn" v-if="lastColumn">
                            <el-table-column
                                header-align="center"
                                align="center"
                                label="操作"
                                fixed="right"
                                >
                                <template slot-scope="{row,$index}">
                                    <div v-if="!btnSlot">
                                        <template v-for="(btn,btn_i) in (btns || row.btns || [])"> 
                                            <el-button :key="btn_i" type="text" @click="handlerClick(row,$index)" :style="{color:btn.color}" v-if="!btn.hide || !row.hideBtns.includes(btn.label)">{{btn.label}}</el-button>     
                                        </template>
                                    </div>
                                    <div v-else>
                                        <slot name="btnSlot" :row="row" :index="$index"></slot>
                                    </div>
                                </template>
                            </el-table-column>
                        </slot>
                    </template>
                    <slot name="outColumn"/>
                </el-table>

            </div>
            <page
            style="margin-top:10px;"
            v-if="showPaginaition"
            :size-change="handleSizeChange" 
            :current-change="handleCurrentChange" 
            :page-config="pageConfig" ></page>
        </div>
    </div>
</template>
<script>
import searchForm from '../components/searchForm'
import selectDataRange from "@/components/resourceManagement1/components/selectDataRange"
const creater = () => {
        const createdField = (fieldL = 'label',fieldV = 'prop',surplus) => (label,prop,options ) => ({[fieldL]:label,[fieldV]:prop,...surplus,...options})
        const setField = (label,list,compareValue = 'label') => func => {
            const field = list.find(v => v[compareValue] === label) || {}
            if(!Object.keys(field)){
            list.push(field)
            }
            func(field)
            return list
        }
        return {createdField,setField}
    }
const createdDefault = creater()
export default {
    name:'searchList',
    components:{searchForm,selectDataRange},
    props:{
        // 表单配置对象 {prop:表单字段名,}
        formConf:{
            type:Array,
            default:()=>([])
        },
        // 表格配置
        /*
        column=>
        insertHeader 时候需要表头单独设置;label:表头文字,prop:对应数据row字段名,width:宽度,fixed:固定列
        filters:过滤配置
        align:对其 
        headerAlign:表头对其
        money: Boolean 是否显示金钱 格式带¥
        color:文字颜色 类型为 new Map()的对象格式返回值
        func:列显示回调函数,用来处理列中的回显的 数据处理,必须有返回值
        slotHeadName : insertHeader为真时,给与slotHeadName,来外部设定格式配置的插槽
        */
        tableConf:{
            type:Array,
            default:()=>([])
        },
        // 内部控制按钮,自定义按钮数组
        btns:Array,
        // 是否需要按钮插槽,外部控制显示按钮
        btnSlot:Boolean,
        // 表格加载效果
        loading:Boolean,
        showSelection:Boolean,
        showPaginaition:{
            type:Boolean,default:true
        },
        tableMaxHeight:String,// 表格的高度
        tableHeight:String,// 表格高度
        showIndex:Object, // {label:显示文字,headerAlign,align 对齐方式}
        pageConf:Object,// 分页设置配置
        lastColumn:{
            type:Boolean,
            default:true
        }, // 使用最后一列插槽
        data:Array,//传入的数据对象优先显示,
        rowCheckable:Function,
        showTitle:String,// 显示表头单列,
        selectOptions:{type:Object,default:()=>({})},// 异步下拉数据表
        btnMore:{
            type:Array,default:()=>([])
        },
        resetQuery:{type:Boolean,default:true}, // 重置之后是否查询,默认查询,
        showExpand:String,// 是否有扩展的内部块
        expandPadding:{
            type:String,
            default:'10px 20px'
        },//扩展内部块的Padding
        defaultValue:{// 默认显示的文字信息
            type:String,
            default:''
        }
    },
    data(){
        return {
            dataList:[], //{ ...prop,btns:[要显示的所有按钮],hideBtns:[需要隐藏的按钮],slot}
            pageConfig: {
                pageSize: 10,
                total: 0,
                pageNumber: 1,
                pageSizes: this.pageSizes || [10, 20, 50],
                layout: 'slot,sizes, prev, pager, next, jumper',
                ...this.pageConf
            },
            curParams:{},// 当前查询变量
            showTbale:true
        }
    },
    computed:{
        tableData(){
           return  this.data || this.dataList
        }
    },
    methods:{
        // 搜索关键字
        search(formData){
            this.curParams = {
                ...this.curParams,
                ...formData,
            }
            this.query()
        },
        // 开始查询
        query(){
            if(this.showPaginaition){
                this.curParams.pageSize = this.pageConfig.pageSize
                this.curParams.pageNo = this.pageConfig.pageNumber
            }
            this.throwEmit()
        },
        // 分页大小
        handleSizeChange(val){
            this.pageConfig.pageSize = val
            this.query(this.curParams)
        },
        // 当前页
        handleCurrentChange(val){
            this.pageConfig.pageNumber = val
            this.query(this.curParams)
        },
        // 接受表格头部过滤的函数
        dateQuery(params,columnKey){
            const list = Object.keys(params).reduce( (p,c) =>{
                p[c+'Time'] = params[c]
                return p
            },{})
            this.curParams = {...this.curParams,...list}
            this.query()
        },
        // 过滤器筛选结构
        filterChange(filters){
            const {0:key} = Object.keys(filters)
            this.curParams[key] = filters[key].join()
            this.query()
        },
        select(selection,row){
            this.$emit('select',selection,row)
            console.log(selection,row)
        },
        // 清楚所有选中
        clearSelectedAll(){
            this.$refs['pushTable'].clearSelection()
        },
        //设置某一行被选中
        setCurrentRow(rows,selected){
            rows.forEach( row => this.$refs['pushTable'].toggleRowSelection(row,selected) )
        },
        // 抛出数据 和最新的查询条件
        throwEmit(){
            this.$emit('querySearch',this.curParams)
        },
        //当前行时候可勾选
        selectable(row,index){
          return  this.rowCheckable ? this.rowCheckable(row,index) : true
        },
        // 重置查询条件 
        resetAll(searchParams){
            this.curParams = {...searchParams}
            this.pageConfig.pageSize = 10
            this.pageConfig.pageNumber = 1
            this.showTbale = false
            this.$nextTick(_ =>{this.showTbale = true})
            if(this.resetQuery) this.query()
            this.$emit('resetAll',this.curParams)
        },
        // 创建函数
        createdDefault,
        //更多按钮事件
        btnMoreAction(item){
            this.$emit('btnMoreAction',item)
        },
        initSearch(clickFunc){
            this.$emit('initSearch',clickFunc)
        },
        change(params){
            this.$emit('change',params)
        }
    }
}
</script>
<style lang="scss" scoped>
 @import "@/projects/proGdton/pages/EAS/common.scss";
.search-card{
    overflow:inherit;
    .table-list{
        .table-padding_both{
            margin:10px 20px;
            /deep/ .el-table th > .cell.highlight {
                    color: #1ab394;
                }
            .kyol-column_header{
                display: flex;
                justify-content: flex-start;
                align-items:center;
            }
        }
       /deep/ .el-table{
           .el-table__expanded-cell[class*=cell]{
               padding:var(--expand)
           }
        }
        .c-table{
            .eslpse{
                width:100%;
                white-space:nowrap;
                overflow: hidden;
                text-overflow:ellipsis;
            }
        }

    }
}
</style>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341

推荐阅读更多精彩内容