用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>
?
?