Vue+Element Ui实现el-table自定义表头下拉选择表头筛选

发布时间:2024年01月11日

用vue+element ui开发管理系统时,使用el-table做表格,当表格列过多的时候,想要做成可选表头的,实现表格列的筛选显示,效果如下:

代码文件结构:

废话不多说,直接上代码:

第一步:新建名为 TableHeaderRender.vue?的文件

<template>

??<el-popover

????placement="bottom"

????width="200"

????trigger="manual"

????v-model="visible"

????@show="showPopover"

????popper-class="table-header-popover"

??>

????<div?class="table-header-popover-template">

??????<el-input

????????placeholder="请输入内容"

????????v-model="value"

????????size="small"

????????clearable

????????@keyup.enter.native="confirm"

????????ref="sInput"

??????>

????????<!--?<el-button?slot="append"?icon="el-icon-search"?@click="confirm">?-->

????????<!--?</el-button>?-->

??????</el-input>

????</div>

????<div?class="el-table-filter__bottom">

??????<button?@click="confirm">筛选</button>

??????<button?@click="resetData">重置</button>

????</div>

????<span

??????slot="reference"

??????style="margin-left:?5px"

??????@click.stop="popClick"

??????v-click-outside="closeOver"

????>

??????<i

????????class="filter-icon?el-icon-search"

????????:style="{?color:?iconColor???'#9a4b9b'?:?'#909399'?}"

??????></i>

??????<!--?<i?class="el-icon-search"?:style="{'color':iconColor}"?></i>?-->

??????<!--?<svg

????????viewBox="64?64?896?896"

????????data-icon="search"

????????width="1em"

????????height="1em"

????????fill="currentColor"

????????:style="{

??????????color:?iconColor???'#9A4B9B'?:?'',

??????????'margin-right':?'2px',

??????????cursor:?'pointer',

????????}"

??????>

????????<path

??????????d="M909.6?854.5L649.9?594.8C690.2?542.7?712?479?712?412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5?31.3-212.1?87.9C143.2?256.5?112?331.8?112?412c0?80.1?31.3?155.5?87.9?212.1C256.5?680.8?331.8?712?412?712c67?0?130.6-21.8?182.7-62l259.7?259.6a8.2?8.2?0?0?0?11.6?0l43.6-43.5a8.2?8.2?0?0?0?0-11.6zM570.4?570.4C528?612.7?471.8?636?412?636s-116-23.3-158.4-65.6C211.3?528?188?471.8?188?412s23.3-116.1?65.6-158.4C296?211.3?352.2?188?412?188s116.1?23.2?158.4?65.6S636?352.2?636?412s-23.3?116.1-65.6?158.4z"

????????></path>

??????</svg>?-->

????</span>

??</el-popover>

</template>

<script>

export?default?{

??name:?"tableHeaderRender",

??data()?{

????return?{

??????//?input?绑定的值

??????value:?"",

??????visible:?false,

??????iconColor:?false,

????};

??},

??props:?{

????tableColumn:?{

??????type:?Object,

??????default:?()?=>?{},

????},

????columnProp:?{

??????type:?String,

??????default:?"",

????},

????defaultValue:?{

??????type:?String,

??????default:?"",

????},

????inputFilteredMap:?{

??????type:?Object,

??????default:?()?=>?{},

????},

??},

??created()?{

????this.value?=?this.defaultValue;

????this.iconColor?=?this.value.trim()???true?:?false;

??},

??methods:?{

????showPopover()?{

??????this.$nextTick(()?=>?{

????????this.$refs.sInput.focus();

??????});

????},

????resetData()?{

??????console.log("reset");

??????this.value?=?"";

??????this.visible?=?false;

??????this.iconColor?=?false;

??????const?self?=?this;

??????if?(this.inputFilteredMap[self.columnProp])?{

????????delete?this.inputFilteredMap[self.columnProp];

??????}

??????self.$emit("resetChangeMethod",?this.tableColumn,?self.columnProp);

????},

????closeOver()?{

??????this.visible?=?false;

????},

????popClick(e)?{

??????//?e.stopPropagation()

??????this.visible?=?!this.visible;

????},

????confirm()?{

??????this.visible?=?false;

??????if?(this.value.trim())?{

????????this.iconColor?=?true;

????????this.inputFilteredMap[this.columnProp]?=?this.value;

????????this.$emit(

??????????"filterInputMethod",

??????????this.tableColumn,

??????????this.inputFilteredMap

????????);

??????}?else?{

????????//?如果搜索input输入为空,等同重置

????????this.resetData();

??????}

????},

??},

??directives:?{

????clickOutside:?{

??????bind(el,?binding,?vnode)?{

????????function?clickHandler(e)?{

??????????//?这里判断点击的元素是否是本身,是本身,则返回

??????????if?(el.contains(e.target))?{

????????????return?false;

??????????}

??????????//?判断指令中是否绑定了函数

??????????if?(binding.expression)?{

????????????//?如果绑定了函数?则调用那个函数,此处binding.value就是handleClose方法

????????????binding.value(e);

??????????}

????????}

????????//?给当前元素绑定个私有变量,方便在unbind中可以解除事件监听

????????el.__vueClickOutside__?=?clickHandler;

????????document.addEventListener("click",?clickHandler);

??????},

??????update()?{},

??????unbind(el,?binding)?{

????????//?解除事件监听

????????document.removeEventListener("click",?el.__vueClickOutside__);

????????delete?el.__vueClickOutside__;

??????},

????},

??},

};

</script>

<style>

.filter-icon?{

??font-size:?14px;

??color:?#909399;

??cursor:?pointer;

??font-weight:?400;

}

.table-header-popover?{

??padding:?0;

}

.table-header-popover?.table-header-popover-template?{

??margin:?10px;

}

</style>




?

第二步:新建名为 operateTable.vue?的文件

<template>

??<div?class="operateTable">

????<el-dropdown

??????size="small"

??????trigger="click"

??????v-if="options.columnsSelect?||?options.columnsTreeSelect"

??????class="column-dropdown"

????>

??????<el-button?style="padding:?9px?10px!important"?size="small">

????????<i?style="font-size:?12px"?class="el-icon-menu"></i>

????????<i?class="el-icon-arrow-down?el-icon--right"></i>

??????</el-button>

??????<el-dropdown-menu?slot="dropdown">

????????<div?style="margin:10px;"?class="caoz_ft_warp"?v-if="isInit||isSave">

??????????<el-button

????????????v-if="isInit"

????????????size="small"

????????????type="primary"?

????????????plain

????????????style="width:70px;"

????????????@click="initColumns(true)"

??????????>初始化</el-button>

??????????<el-button

????????????v-if="isSave"

????????????size="small"

????????????type="primary"?

????????????plain

????????????style="width:70px;"

????????????@click="$emit('saveSettingColumns',checkedList)"

???????????>保存</el-button>

????????</div>

????????<div?style="margin:10px;"?class="caoz_ft_warp">

??????????<el-input?size="small"?placeholder="请输入关键字"?v-model="cloumnKeyword"?clearable></el-input>

????????</div>

????????<el-checkbox?:indeterminate="isIndeterminate"?v-model="checkAll"?@change="handleCheckAllChange"?style="padding-left:10px;">Select?All</el-checkbox>

????????<el-checkbox-group

??????????v-if="!options.columnsTreeSelect"

??????????v-model="checkedList"

??????????style="max-height:?300px"

??????????@change="handleCheckedCitiesChange"

????????>

??????????<div?class="checkboxScorll">

????????????<template?v-for="(option,?index)?in?checkBoxOptions">

??????????????<template?v-if="cloumnKeyword?&&?option.toLowerCase().indexOf(cloumnKeyword.toLowerCase())>-1">

????????????????<el-checkbox

??????????????????:key="index"

??????????????????class="checkbox"

??????????????????:label="option"

????????????????></el-checkbox>

??????????????</template>

??????????????<template?v-else-if="!cloumnKeyword">

????????????????<el-checkbox

??????????????????:key="index"

??????????????????class="checkbox"

??????????????????:label="option"

????????????????></el-checkbox>

??????????????</template>

??????????????<template?v-else></template>

????????????</template>

??????????</div>

????????</el-checkbox-group>

????????<div?v-else?class="checkboxTree">

??????????<el-tree

????????????ref="tree"

????????????:check-on-click-node="true"

????????????:data="treeColumn"

????????????show-checkbox

????????????node-key="label"

????????????:default-expanded-keys="defaultExpanded"

????????????:default-checked-keys="defaultChecked"

????????????:props="{

??????????????children:?'children',

??????????????label:?'label',

????????????}"

????????????@check="checkChange"

????????????style="max-height:?300px;?overflow-y:?auto"

??????????>

??????????</el-tree>

????????</div>

??????</el-dropdown-menu>

????</el-dropdown>

????<el-table

??????id="iTable"

??????ref="operateTable"

??????border

??????:data="dataSource"

??????:stripe="options.stripe"

??????:highlight-current-row="options.highlightCurrentRow"

??????:max-height="options.maxHeight"

??????:size="options.size"

??????:fit="options.fit"

??????:show-header="options.showHeader"

??????:empty-text="options.emptyText"

??????:default-sort="options.defaultSort"

??????:row-key="getRowKeys"

??????:default-expand-all="options.defaultExpandAll"

??????:tree-props="options.treeProps"

??????:lazy="options.lazy"

??????:load="load"

??????@cell-mouse-enter="cellMouseEnter"

??????@cell-mouse-leave="cellMouseLeave"

??????@cell-click="cellClick"

??????@cell-dblclick="cellDblclick"

??????@row-click="rowClick"

??????@row-contextmenu="rowContextmenu"

??????@row-dblclick="rowDblclick"

??????@header-click="headerClick"

??????@header-contextmenu="headerContextmenu"

??????@sort-change="sortChange"

??????@select="select"

??????@select-all="selectAll"

??????@selection-change="checkboxSelected"

??????@filter-change="filterChange"

????>

??????<slot?name="expandRow"></slot>

??????<!--?复选框?-->

??????<el-table-column

????????:reserve-selection="options.reserveSelection"

????????:key="0"

????????type="selection"

????????:selectable="selectable"

????????width="40"

????????align="left"

????????v-if="options.showCheckBox"

????????:resizable="false"

??????>

??????</el-table-column>

??????<el-table-column

????????ref="fixedColumn"

????????label="操作"

????????align="left"

????????:width="operates.dropDown???'50'?:?operates.width"

????????:fixed="operates.fixed"

????????:min-width="operates.minwidth"

????????:resizable="operates.resizable"

????????v-if="operates.list.length?>?0"

??????>

????????<template?slot-scope="scope">

??????????<!--?操作列?不折叠?全为icon-->

??????????<div

????????????class="operate-group"

????????????v-if="!operates.dropDown?&&?!operates.isText"

??????????>

????????????<template

??????????????v-for="item?in?operates.list[0]?instanceof?Array

??????????????????operates.list[scope.$index]

????????????????:?operates.list"

????????????>

??????????????<div?class="item"?v-if="item.show"?:key="item.id">

????????????????<el-switch

??????????????????v-if="item.type?===?'switch'"

??????????????????v-model="scope.row[item.prop]"

??????????????????active-color="#13ce66"

??????????????????@change="item.method(scope.$index,?scope.row)"

????????????????></el-switch>

????????????????<el-tooltip

??????????????????v-else-if="item.type?===?'tooltipIcon'"

??????????????????:enterable="false"

??????????????????effect="light"

??????????????????placement="bottom"

????????????????>

??????????????????<div?slot="content">{{?item.tooltip?}}</div>

??????????????????<el-button?

????????????????????type="primary"?

????????????????????plain?

????????????????????:icon="item.icon"

????????????????????size="mini"?

????????????????????:disabled="item.disabled"

????????????????????@click="item.method(scope.$index,?scope.row)"

??????????????????></el-button>

????????????????</el-tooltip>

????????????????<el-button?

??????????????????v-else-if="item.type?===?'icon'"

??????????????????type="primary"?

??????????????????plain?

??????????????????:icon="item.icon"

??????????????????size="mini"?

??????????????????:disabled="item.disabled"

??????????????????@click="item.method(scope.$index,?scope.row)"

????????????????></el-button>

??????????????</div>

????????????</template>

??????????</div>

??????????<!--?操作列?不折叠?全为文字-->

??????????<div

????????????class="operate-group"

????????????v-if="!operates.dropDown?&&?operates.isText"

??????????>

????????????<template

??????????????v-for="item?in?operates.list[0]?instanceof?Array

??????????????????operates.list[scope.$index]

????????????????:?operates.list"

????????????>

??????????????<div?class="item"?v-if="item.show"?:key="item.id">

????????????????<el-button

??????????????????size="small"

??????????????????type="text"

??????????????????:disabled="item.disabled"

??????????????????@click.native.prevent="item.method(scope.$index,?scope.row)"

??????????????????>{{?item.label?}}</el-button

????????????????>

??????????????</div>

????????????</template>

??????????</div>

??????????<!--?操作列?折叠下拉-->

??????????<div?class="operate-group"?v-else-if="operates.dropDown">

????????????<el-dropdown

??????????????@command="handleCommand"

??????????????trigger="hover"

??????????????placement="bottom-start"

????????????>

??????????????<span?class="el-dropdown-link">

????????????????<i?class="el-icon-s-unfold"?style="font-size:?16px;"></i>

??????????????</span>

??????????????<!--?根据operates.list?来渲染操作列下拉的内容?-->

??????????????<el-dropdown-menu?slot="dropdown">

????????????????<el-dropdown-item

??????????????????v-for="(item,?index)?in?operates.list[0]?instanceof?Array

??????????????????????operates.list[scope.$index]

????????????????????:?operates.list"

??????????????????:disabled="item.disabled"

??????????????????:key="index"

??????????????????:command="composeValue(item,?scope.row,?scope.$index)"

??????????????????>{{?item.label?}}</el-dropdown-item

????????????????>

??????????????</el-dropdown-menu>

????????????</el-dropdown>

??????????</div>

????????</template>

??????</el-table-column>

??????<!--region?数据列-->

??????<template?v-for="column?in?columns">

????????<!--?:filter-method="column.filters???column.filterMethod?:?undefined"?-->

????????<!--?v-if="

????????????options.columnsSelect?||?options.columnsTreeSelect

????????????????checkedList.includes(column.label)

??????????????:?true

??????????"?-->

????????<el-table-column

??????????v-if="

????????????options.columnsSelect?||?options.columnsTreeSelect

????????????????checkedList.includes(column.label)

??????????????:?true

??????????"

??????????:prop="column.prop"

??????????:key="column.label"

??????????:label="column.label"

??????????align="left"

??????????:width="column.width"

??????????:min-width="column.minwidth"

??????????:resizable="column.resizable"

??????????:sortable="column.sortable"

??????????:filters="column.filters"

??????????:filter-method="column.filters???column.filterMethod?:?undefined"

??????????:filtered-value="column.filteredValue"

??????????:fixed="column.fixed"

??????????:column-key="column.prop"

????????>

??????????<template?slot="header"?slot-scope="scope"

????????????>{{?column.label?}}

????????????<TableHeaderRender

??????????????v-if="column.filterInput"

??????????????:columnProp="column.prop"

??????????????:tableColumn="scope.column"

??????????????:defaultValue="column.defaultValue"

??????????????:inputFilteredMap="inputFilteredMap"

??????????????@filterInputMethod="filterInputMethod"

??????????????@resetChangeMethod="resetChangeMethod"

????????????></TableHeaderRender>

??????????</template>

??????????<!--?:filtered-value="column.filteredValue"?-->

??????????<template?slot-scope="scope">

????????????<!--?如果传进来的column没有render函数执行以下代码?-->

????????????<template?v-if="!column.render">

??????????????<!--?如果传进来的column没有render函数但有formatter函数执行以下代码?-->

??????????????<template?v-if="column.formatter">

????????????????<span?v-html="column.formatter(scope.row,?column)"></span>

??????????????</template>

??????????????<!--?如果传进来的column既没有render函数也没有formatter函数执行以下代码?-->

??????????????<template?v-else>

????????????????<span>{{?scope.row[column.prop]?}}</span>

??????????????</template>

????????????</template>

????????????<!--?如果传进来的column有render函数执行以下代码?-->

????????????<template?v-else>

??????????????<expand-dom

????????????????:column="column"

????????????????:row="scope.row"

????????????????:render="column.render"

????????????????:index="scope.$index"

??????????????></expand-dom>

????????????</template>

??????????</template>

????????</el-table-column>

??????</template>

??????<!--endregion-->

????</el-table>

??</div>

</template>

<script>

import?TableHeaderRender?from?"./TableHeaderRender.vue";

export?default?{

??name:?"OperateTable",

??props:?{

????//?表格的数据源

????dataSource:?{

??????type:?Array,

??????default:?()?=>?[],

????},

????//?需要展示的列

????columns:?{

??????type:?Array,

??????default:?()?=>?[{}],

????},

????//?table?表格的控制参数

????options:?{

??????type:?Object,

??????default:?()?=>?{

????????return?{

??????????stripe:?true,?//?是否为斑马纹?table

????????};

??????},

????},

????//?操作按钮组?===?label:?文本,show:是否显示,icon:按钮图标,disabled:是否禁用,method:回调方法,?等等

????operates:?{

??????type:?Object,

??????default:?()?=>?{

????????return?{

??????????list:?[],

????????};

??????},

????},

????defaultSelectedColumn:?{

??????type:?Array,

??????default:?()?=>?[],

????},

????defaultColumn:?{

??????type:?Array,

??????default:?()?=>?[],

????},

????totalColumn:?{

??????type:?Array,

??????default:?()?=>?[],

????},

????treeColumn:?{

??????type:?Array,

??????default:?()?=>?[],

????},

????defaultChecked:?{

??????type:?Array,

??????default:?()?=>?[],

????},

????defaultExpanded:?{

??????type:?Array,

??????default:?()?=>?[],

????},

????isInit:?{

??????type:?Boolean,

??????default:?false

????},

????isSave:?{

??????type:?Boolean,

??????default:?false

????}

??},

??components:?{

????TableHeaderRender,

????expandDom:?{

??????functional:?true,

??????props:?{

????????row:?Object,

????????render:?Function,

????????index:?Number,

????????column:?{

??????????type:?Object,

??????????default:?null,

????????},

??????},

??????render:?(h,?ctx)?=>?{

????????const?params?=?{

??????????row:?ctx.props.row,

??????????index:?ctx.props.index,

????????};

????????if?(ctx.props.column)?params.column?=?ctx.props.column;

????????return?ctx.props.render(h,?params);

??????},

????},

??},

??data()?{

????return?{

??????cloumnKeyword:"",//字段关键字搜索

??????isIndeterminate:true,//全选状态

??????checkAll:false,//字段全选

??????checkBoxOptions:?[],?//?全部表头

??????checkedList:?[],?//?选中表头

??????count:?0,?//?用于判断表格是否刚渲染

??????isCheckBoxSort:?false,?//?用于判断是否是由自定义数据列引发的排序

??????//?以下是之前放于vuex中用于记录状态

??????preCheckedList:?[],?//?前一次的checkbox

??????//?排序的状态

??????sort:?{

????????prop:?"",

????????order:?"",

????????label:?"",

??????},

??????//?筛选的状态

??????checkBoxFilteredMap:?{},

??????//?input?所有的筛选

??????inputFilteredMap:?{},

??????//?columns?label及prop对应的键值对

??????columnsLabelMap:?{}

????};

??},

??watch:?{

????//?监听defaultColumn,若这个发生变化,代表传入的默认column变化,即数据表格发生了切换

????defaultColumn()?{

??????this.initColumns();

????},

????checkedList()?{

??????//?if(this.checkedList.length>0){

??????//???this.$emit("selectedColumn",this.checkedList);

??????//?}

??????//?处理当点击checkbox显示的是排序列时,恢复排序列的显示

??????let?showLabelArray?=?this.checkboxShowLabel();

??????console.log("showLabelArray",?showLabelArray);

??????//?if?(value.length?!==?0)?{

??????//???value.map((item)?=>?{

??????//?????this.handleStatusRevert(item);

??????//???});

??????this.columns.map((column,?index)?=>?{

????????this.handleStatusRevert(column,?index,?showLabelArray);

??????});

????},

??},

??created()?{

????this.normalizeColumnsLabelMap();

??},

??mounted()?{

????if?(!this.options.columnsTreeSelect)?{

??????this.checkedList?=?this.$props.defaultColumn;

??????this.checkBoxOptions?=?this.$props.totalColumn;

????}?else?{

??????this.checkedList?=?this.$refs.tree

????????.getCheckedNodes()

????????.map((item)?=>?item.label);

????}

????//?挂载时将defaultSort属性传给vuex

????this.handleDefaultSort();

??},

??//?动态切换表头的时候闪烁是因为表头重新计算高度导致的,以下方法解决此bug

??beforeUpdate()?{

????this.$nextTick(()?=>?{

??????//在数据加载完,重新渲染表格

??????this.$refs["operateTable"].doLayout();

????});

??},

??methods:?{

????//全选字段

????handleCheckAllChange(val){

??????this.checkedList?=?val???this.checkBoxOptions?:?[];

??????this.isIndeterminate?=?false;

????},

????//反选

????handleCheckedCitiesChange(value){

??????let?checkedCount?=?value.length;

??????this.checkAll?=?checkedCount?===?this.checkBoxOptions.length;

??????this.isIndeterminate?=?checkedCount?>?0?&&?checkedCount?<?this.checkBoxOptions.length;

????},

????//初始化字段

????initColumns(flag){

??????if(flag){

????????this.checkedList?=?this.$props.defaultSelectedColumn;

??????}else{

????????this.checkedList?=?this.$props.defaultColumn;

??????}

??????this.checkBoxOptions?=?this.$props.totalColumn;

????},

????//?处理判断checkbox?点击时,显示的是哪个字段名

????checkboxShowLabel()?{

??????//?判断显示的字段是哪个字段,如果是树形,可能有多个,故更改为数组接收

??????let?value?=?[];

??????console.log("this.checkedList",?this.checkedList);

??????if?(this.count?===?0)?{

????????this.saveCheckedList(this.checkedList);

????????//?this.$componentsStore.commit("table/saveCheckedList",?this.checkedList);

????????this.count++;

??????}?else?{

????????if?(this.checkedList.length?>?this.preCheckedList.length)?{

??????????for?(let?index?=?0;?index?<?this.checkedList.length;?index++)?{

????????????if?(!this.preCheckedList.includes(this.checkedList[index]))?{

??????????????value.push(this.checkedList[index]);

????????????}

????????????//?if?(this.checkedList[index]?!==?this.preCheckedList[index])?{

????????????//???value?=?this.checkedList[index];

????????????//?}

??????????}

????????}

????????this.saveCheckedList(this.checkedList);

????????//?this.$componentsStore.commit("table/saveCheckedList",?this.checkedList);

??????}

??????return?value;

????},

????//?处理sort\filterd由隐藏变为显示状态的恢复

????handleStatusRevert(column,?index,?showLabelArray)?{

??????let?compareLabel?=?column.label;

??????if?(showLabelArray.includes(compareLabel))?{

????????//?如果是有checkbox?筛选的字段,恢复筛选

????????let?filteredValue?=

??????????this.checkBoxFilteredMap[this.columnsLabelMap[compareLabel]];

????????//?如果是有input?筛选的字段,恢复筛选

????????let?filteredInputValue?=

??????????this.inputFilteredMap[this.columnsLabelMap[compareLabel]];

????????this.columns[index].filteredValue?=?filteredValue;

????????this.columns[index].defaultValue?=?filteredInputValue;

????????this.$nextTick(()?=>?{

??????????this.$refs.operateTable.store.states.columns.map((column)?=>?{

????????????if?(column.filteredValue?&&?column.filteredValue.length)?{

??????????????this.$refs.operateTable.store.commit("filterChange",?{

????????????????column,

????????????????values:?column.filteredValue,

????????????????silent:?true,

??????????????});

????????????}

??????????});

????????});

??????}?else?{

????????this.columns[index].filteredValue?=?[];

????????this.columns[index].defaultValue?=?"";

??????}

??????//?如果是有排序的字段,恢复排序

??????if?(showLabelArray.includes(this.sort.label))?{

????????this.$nextTick(()?=>?{

??????????//在数据加载完,重新渲染表格

??????????this.isCheckBoxSort?=?true;

??????????this.$refs.operateTable.sort(this.sort.prop,?this.sort.order);

????????});

??????}

??????/**

??????//?如果是有checkbox?筛选的字段,恢复筛选

??????let?filteredValue?=?this.checkBoxFilteredMap[this.columnsLabelMap[value]];

??????//?如果是有input?筛选的字段,恢复筛选

??????let?filteredInputValue?=?this.inputFilteredMap[

????????this.columnsLabelMap[value]

??????];

??????for?(let?i?=?0;?i?<?this.columns.length;?i++)?{

????????if?(this.columns[i].label?===?value)?{

??????????this.columns[i].filteredValue?=?filteredValue;

??????????this.columns[i].defaultValue?=?filteredInputValue;

??????????this.$nextTick(()?=>?{

????????????this.$refs.operateTable.store.states.columns.map((column)?=>?{

??????????????if?(column.filteredValue?&&?column.filteredValue.length)?{

????????????????console.log("!11");

????????????????this.$refs.operateTable.store.commit("filterChange",?{

??????????????????column,

??????????????????values:?column.filteredValue,

??????????????????silent:?true,

????????????????});

??????????????}

????????????});

??????????});

????????}?else?{

??????????this.columns[i].filteredValue?=?[];

??????????this.columns[i].defaultValue?=?"";

????????}

??????}

??????//?for?(let?i?=?0;?i?<?this.columns.length;?i++)?{

??????//???if?(this.columns[i].label?===?value)?{

??????//?????this.columns[i].defaultValue?=?filteredInputValue;

??????//???}?else?{

??????//?????this.columns[i].defaultValue?=?"";

??????//???}

??????//?}

??????//?如果是有排序的字段,恢复排序

??????if?(value?===?this.sort.label)?{

????????this.$nextTick(()?=>?{

??????????//在数据加载完,重新渲染表格

??????????this.isCheckBoxSort?=?true;

??????????this.$refs.operateTable.sort(this.sort.prop,?this.sort.order);

????????});

??????}

??????*/

????},

????//?处理生成columns?的label?prop键值对

????normalizeColumnsLabelMap()?{

??????this.columns.map((column)?=>?{

????????this.columnsLabelMap[column.label]?=?column.prop;

??????});

????},

????filterInputMethod(column,?inputFilteredMap)?{

??????console.log("column,?inputFilteredMap",?column,?inputFilteredMap);

??????this.inputFilteredMap?=?inputFilteredMap;

??????this.$emit("filterInputMethod",?column,?inputFilteredMap);

????},

????resetChangeMethod(tableColumn,?columnProp)?{

??????this.$emit("resetChangeMethod",?tableColumn,?this.inputFilteredMap);

????},

????cellMouseEnter(row,?column,?cell,?event)?{

??????this.$emit("cell-mouse-enter",?row,?column,?cell,?event);

????},

????cellMouseLeave(row,?column,?cell,?event)?{

??????this.$emit("cell-mouse-leave",?row,?column,?cell,?event);

????},

????cellClick(row,?column,?cell,?event)?{

??????this.$emit("cell-click",?row,?column,?cell,?event);

????},

????cellDblclick(row,?column,?cell,?event)?{

??????this.$emit("cell-dblclick",?row,?column,?cell,?event);

????},

????rowClick(row,?column,?event)?{

??????this.$emit("row-click",?row,?column,?event);

????},

????rowContextmenu(row,?column,?event)?{

??????this.$emit("row-contextmenu",?row,?column,?event);

????},

????rowDblclick(row,?column,?event)?{

??????this.$emit("row-dblclick",?row,?column,?event);

????},

????headerClick(column,?event)?{

??????this.$emit("header-click",?column,?event);

????},

????headerContextmenu(column,?event)?{

??????this.$emit("header-contextmenu",?column,?event);

????},

????sortChange(sortObj)?{

??????this.changeSort(sortObj);

??????//?this.$componentsStore.commit("table/changeSort",?sortObj);

??????if?(!this.isCheckBoxSort)?{

????????this.$emit("sort-change",?sortObj);

??????}

??????//?还原isCheckBoxSort

??????this.isCheckBoxSort?=?false;

????},

????handleDefaultSort()?{

??????if?(this.options.defaultSort?!==?undefined)?{

????????let?column?=?{?label:?""?};

????????//?for?(let?index?=?0;?index?<?this.columns.length;?index++)?{

????????//???if?(this.columns[index].prop?===?this.options.defaultSort.prop)?{

????????//?????column.label?=?this.columns[index].label;

????????//?????break;

????????//???}

????????//?}

????????column.label?=?this.columnsLabelMap[this.options.defaultSort.prop];

????????this.changeSort({

??????????...this.options.defaultSort,

??????????column,

????????});

??????}

????},

????//?点击操作的下拉项目后触发事件

????handleCommand(command)?{

??????if?(command.method)?{

????????command.method(command.index,?command.row,?command.label);

??????}

????},

????//?点击dropDown传参方法

????composeValue(item,?row,?index)?{

??????return?{

????????label:?item.label,

????????row:?row,

????????index:?index,

????????method:?item.method,

??????};

????},

????select(selection,?row)?{

??????this.$emit("select",?selection,?row);

????},

????selectAll(selection)?{

??????this.$emit("select-all",?selection);

????},

????checkboxSelected(selection)?{

??????this.$emit("selection-change",?selection);

????},

????selectable(row,?index)?{

??????let?data?=?true;

??????this.$emit("selectable",?row,?index,?(val)?=>?{

????????data?=?val;

??????});

??????return?data;

????},

????getRowKeys(row)?{

??????let?data;

??????for?(let?index?=?0;?index?<?this.dataSource.length;?index++)?{

????????if?(row?===?this.dataSource[index])?{

??????????data?=?index;

??????????break;

????????}

??????}

??????//?this.dataSource.map((item,?index)?=>?{

??????//???if?(row?===?item)?{

??????//?????data?=?index;

??????//???}

??????//?});

??????this.$emit("row-key",?row,?(val)?=>?{

????????data?=?val;

??????});

??????return?data;

????},

????load(tree,?treeNode,?resolve)?{

??????this.$emit("load",?tree,?treeNode,?resolve);

????},

????//?记录表格总的筛选状态,用于列显示隐藏时保存checkbox状态

????filterChange(filters)?{

??????let?currKey?=?Object.keys(filters)[0];

??????if?(filters[currKey].length?===?0)?{

????????delete?this.checkBoxFilteredMap[currKey];

??????}?else?{

????????this.checkBoxFilteredMap[currKey]?=?filters[currKey];

??????}

??????this.$emit("filter-change",?filters);

????},

????checkChange(nodeObj,?checkObj)?{

??????this.checkedList?=?checkObj.checkedNodes.map((item)?=>?{

????????return?item.label;

??????});

????},

????//?之前写在vuex里的方法

????changeSort(sort)?{

??????this.sort.prop?=?sort.prop;

??????this.sort.order?=?sort.order;

??????this.sort.label?=?sort.column.label;

????},

????saveCheckedList(preCheckedList)?{

??????this.preCheckedList?=?preCheckedList;

????},

??},

};

</script>

<style>

????.operateTable{

????????position:?relative;

????????width:?100%;

????}

????.operateTable?.column-dropdown{

????????position:?absolute;

????????right:?0px;

????????top:?-42px;

????????z-index:?99;

????}

????.caoz_ft_warp{

??????text-align:?center;

????}

????.caoz_ft_warp?.el-input.is-active?.el-input__inner,?.caoz_ft_warp?.el-input__inner:focus{

????????border-color:?#9A4B9B;

????????outline:?0;

????}

????.el-checkbox__input.is-checked?.el-checkbox__inner,.el-checkbox__input.is-indeterminate?.el-checkbox__inner?{

????????background-color:?#9a4b9b;

????????border-color:?#9a4b9b;

????}

????.el-checkbox__inner:hover?{

????????border-color:?#9A4B9B;

????}

????.el-checkbox__input.is-focus?.el-checkbox__inner{

????????border-color:?#9A4B9B;

????}

????.el-checkbox__input.is-checked+.el-checkbox__label?{

????????color:?#9A4B9B;

????}

????.checkboxScorll?.el-checkbox__input.is-checked?+?.el-checkbox__label?{

????????color:?#666;

????}

????.column-dropdown?.el-button{margin-right:?0?!important;min-width:0;}

????.column-dropdown?.el-button:focus,?.el-button:hover{

????????color:?#9A4B9B;

????????border-color:?#e1c9e1;

????????background-color:?#f5edf5;

????}

????.checkboxScorll?{

????????max-height:?300px;

????????overflow-y:?auto;

????}

????.checkboxScorll?.checkbox?{

????????display:?block;

????????margin-top:?10px;

????????padding-left:?20px;

????}

</style>

第三步:在页面中引入operateTable并使用

<template>

??<div?class="tableView">

????<div?class="content">

??????<operateTable

????????v-loading="loading"

????????:dataSource="operateTableData"

????????:columns="operateTableColumns"

????????:options="operateTableOption"

????????:defaultColumn="defaultColumns"

????????:totalColumn="totalColumns"

????????:defaultSelectedColumn="defaultSelectedColumn"

????????@sort-change="sortChange"

????????@saveSettingColumns="saveSettingColumns"

??????></operateTable>

????</div>

??</div>

</template>

<script>

import?operateTable?from?"./components/operateTable.vue";

export?default?{

??name:?"",

??components:?{

????operateTable,

??},

??data()?{

????return?{

??????loading:?false,

??????operateTableData:?[

????????{

??????????date:?"2016-05-02",

??????????name:?"王小虎",

??????????address:?"上海市普陀区金沙江路?1518?弄",

????????},

????????{

??????????date:?"2016-05-04",

??????????name:?"王小虎",

??????????address:?"上海市普陀区金沙江路?1517?弄",

????????},

????????{

??????????date:?"2016-05-01",

??????????name:?"王小虎",

??????????address:?"上海市普陀区金沙江路?1519?弄",

????????},

????????{

??????????date:?"2016-05-03",

??????????name:?"王小虎",

??????????address:?"上海市普陀区金沙江路?1516?弄",

????????},

??????],

??????operateTableColumns:?[

????????{

??????????prop:?"action",

??????????label:?"操作",

??????????width:?100,

??????????fixed:?true,

??????????render:?(h,?params)?=>?{

????????????return?h(

??????????????"div",

??????????????{

????????????????class:?"operate-group",

??????????????},

??????????????[

????????????????h(

??????????????????"el-tooltip",

??????????????????{

????????????????????props:?{

??????????????????????content:?"处理",

??????????????????????placement:?"bottom",

??????????????????????enterable:?false,

??????????????????????effect:?"light",

????????????????????},

????????????????????class:?"item",

??????????????????},

??????????????????[

????????????????????h("i",?{

??????????????????????props:?{},

??????????????????????class:?"el-icon-edit",

??????????????????????on:?{

????????????????????????click:?()?=>?{

??????????????????????????console.log(params.row);

????????????????????????},

??????????????????????},

????????????????????}),

??????????????????]

????????????????),

??????????????]

????????????);

??????????},

????????},

????????{

??????????prop:?"date",

??????????label:?"日期",

??????????minwidth:?150,

??????????sortable:?"custom",

????????},

????????{

??????????prop:?"name",

??????????label:?"姓名",

??????????minwidth:?150,

??????????sortable:?"custom",

????????},

????????{

??????????prop:?"address",

??????????label:?"地址",

??????????minwidth:?150,

??????????sortable:?"custom",

????????},

??????],

??????operateTableOption:?{

????????stripe:?true,?//?是否为斑马纹?table

????????highlightCurrentRow:?true,?//?是否要高亮当前行

????????columnsSelect:?true,

????????maxHeight:?300,

??????},

??????defaultColumns:?["操作",?"日期",?"姓名",?"地址"],

??????totalColumns:?["操作",?"日期",?"姓名",?"地址"],

??????//所有用户默认勾选的列??用于初始化

??????defaultSelectedColumn:?[],

????};

??},

??methods:?{

????//表头排序

????sortChange(column,?prop,?order)?{

??????if?(column.order?===?"ascending")?{

????????this.orderfield?=?column.prop;

????????this.orderby?=?"ASC";

??????}?else?if?(column.order?===?"descending")?{

????????this.orderfield?=?column.prop;

????????this.orderby?=?"DESC";

??????}?else?{

????????this.orderfield?=?"";

????????this.orderby?=?"";

??????}

??????//???this.getTabldHandle();

????},

????//保存自定义字段

????saveSettingColumns(data)?{

??????console.log(data);

????},

??},

??mounted()?{},

};

</script>

<style>

.tableView?{

??width:?100%;

??height:?100%;

}

.content?{

??padding:?60px;

}

.disableIcon?{

??color:?#c0c4cc;

??cursor:?not-allowed;

}

</style>

?

?

文章来源:https://blog.csdn.net/Calvin_qiang/article/details/135522265
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。