在ElTable基础上添加列隐藏,在使用el-table 时候,想要实现这种效果一般是给每个el-form-item添加v-if 判断的,看看el-table中看有没有什么办法能使用更方便的方式去管理,最后发现内部的【插入】和【删除】两个方法可以达到我们要的效果。
具体效果如下
文章来源地址https://www.toymoban.com/news/detail-610144.html
- 业务组件定义好数据,支持默认隐藏
- 使用right-toolbar 切换显示&隐藏 将切换的值保存在 vuex + vuex-persistedstate 方便刷新页面保持动作
- 对 el-table 源码进行改动
改动文件目录
- el-table
- table.vue
- store
- index.js
覆盖注册组件
import ElementUI from "element-ui"
import "element-ui/lib/theme-chalk/index.css";
Vue.use(ElementUI);
import ElTable from '@/components/element-ui/ElTable';
import ElTableColumn from "@/components/element-ui/el-table-column";
Vue.component(ElTable.name, ElTable); // 这个步骤同等于对象重新赋值的操作
Vue.component(ElTableColumn.name, ElTableColumn);
项目使用方式
将 table 传递给 right-toolbar
<template>
<div>
<right-toolbar :search="false" :table.sync="table" @interaction="(x) => (hiddenColumns = x)" :componentName="$options.name" />
<el-table ref="table" :data="table.data" v-loading="table.loading" :hiddenColumns="hiddenColumns">
<el-table-column align="center" type="selection" width="55" />
<el-table-column align="center" label="类型" prop="type" />
<el-table-column align="center" label="名称" prop="name" />
<el-table-column align="center" label="描述信息" prop="desp" />
<el-table-column align="center" label="值" prop="value" />
<el-table-column align="center" label="默认值" prop="defaultValue" />
<el-table-column align="center" label="操作" class-name="small-padding fixed-width">
<template>
<el-button size="mini" type="text" icon="el-icon-edit" >修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
table: {
loading: false,
table: [
{
type: "FilePath",
name: "probeEnforcement",
desp: "文件生成路径",
value: "/home/qchen/",
defaultValue: "3",
},
],
},
hiddenColumns: [], // 默认隐藏的列
checkTableInfo: ["类型", "名称", "描述信息", "值", "默认值", "操作"],
};
},
};
</script>
自定义组件(right-toolbar)
<template>
<div class="top-right-btn" :style="style">
<el-row>
<el-tooltip effect="dark" :content="showSearch ? '隐藏搜索' : '显示搜索'" placement="top" v-if="search">
<el-button size="mini" circle icon="el-icon-search" @click="$emit('update:showSearch', !showSearch)" />
</el-tooltip>
<el-tooltip effect="dark" content="刷新" placement="top">
<el-button size="mini" circle icon="el-icon-refresh" @click="$emit('queryTable')" />
</el-tooltip>
<el-tooltip v-if="checkTableInfo.length" effect="dark" content="显隐列" placement="bottom-start">
<el-popover v-model="visible" placement="right" trigger="click">
<p class="clearfix">
<i class="el-icon-refresh fr" @click="reset" />
</p>
<el-checkbox-group v-model="checks">
<el-checkbox style="display: block" v-for="item in checkTableInfo" :disabled="['selection', '操作'].includes(item)" :key="item" :label="item" />
</el-checkbox-group>
<el-divider class="my-10" />
<template>
<el-button size="mini" type="primary" @click="submit(), (visible = false)">确定</el-button>
<el-button v-if="componentName" size="mini" @click="cancel">取消</el-button>
</template>
<el-button class="ml-10" slot="reference" size="mini" circle icon="el-icon-menu" />
</el-popover>
</el-tooltip>
</el-row>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex';
import { localstorageGet, localstorageSet } from '@/lib/util';
export default {
name: 'RightToolbar',
data() {
return {
checks: Array.from(this.table.checkTableInfo.filter(item => !this.table.hiddenColumns.includes(item)) || []),
checkTableInfo: Array.from(this.table.checkTableInfo || []),
visible: false,
};
},
props: {
showSearch: { type: Boolean, default: true },
search: { type: Boolean, default: true },
gutter: { type: Number, default: 10 },
table: { type: Object, default: () => ({}) },
componentName: { type: String, default: '' },
},
mounted() {
const cacheColumn = this.tableColumns[this.componentName];
if (cacheColumn) {
this.checks = this.table.checkTableInfo.filter(item => !cacheColumn.includes(item));
this.$emit('interaction', cacheColumn);
} else {
const arr = this.table.checkTableInfo.filter(item => !this.checks.includes(item));
this.$emit('interaction', arr);
}
},
methods: {
// 项目中会使用vuex ,vuex 中有持久化存储到localstorage的数据
...mapMutations('tablecolumn', ['setTableCache']),
submit() {
const differs = this.table.checkTableInfo.filter(item => !this.checks.includes(item));
this.$emit('interaction', differs);
if (!this.componentName) return;
this.setTableCache({ key: [this.componentName], value: differs });
},
cancel() {
this.tableColumns[this.componentName]?.length && (this.checks = this.tableColumns[this.componentName]);
this.visible = false;
},
reset() {
this.checks = this.table.checkTableInfo;
this.submit();
},
},
computed: {
...mapState('tablecolumn', ['tableColumns']),
style() {
const ret = {};
if (this.gutter) {
ret.marginRight = `${this.gutter / 2}px`;
}
return ret;
},
},
};
</script>
<style lang="scss" scoped>
.top-right-btn {
margin: 2px 12px;
}
</style>
table组件中 (./el-table/table.vue)
<script>
import { cloneDeep } from 'lodash-es'
...其他导入
export default {
name: "ElTable",
props: {
hiddenColumns: {
type: Array,
default: () => [],
},
// ... 其他props
},
watch: {
hiddenColumns: {
immediate: true,
handler(value) {
...其他代码
const { states } = this.store;
const { _columns } = states;
if (!this.cache_columns || !this.cache_columns.length) {
this.cache_columns = deepClone(_columns);
}
const show = this.cache_columns.filter(x => {
if (['selection', 'index', 'expand'].includes(x.type)) return false;
if (['#', '操作'].includes(x.label)) return false;
return !value.includes(x.label);
});
const showLabels = _columns.map(x => x.label);
show.forEach(item => {
if (showLabels.includes(item.label)) return;
this.store.commit('insertColumn', item, item.insertColumnIndex);
});
const hide = this.cache_columns.filter(x => {
if (['selection', 'index', 'expand'].includes(x.type)) return false;
if (['#', '操作'].includes(x.label)) return false;
return value.includes(x.label);
});
hide.forEach(item => {
const column = _columns.find(x => x.label === item.label);
if (!column) return;
this.store.commit('removeColumn', column);
});
},
},
}
};
</script>
store/index.js (./el-table/store/index.js)
Watcher.prototype.mutations = {
...其他代码
insertColumn(states, column, index, parent) {
let array = states._columns;
if (parent) {
array = parent.children;
if (!array) array = parent.children = [];
}
if (typeof index !== 'undefined') {
array.splice(index, 0, column);
} else {
array.push(column);
}
if (column.type === 'selection') {
states.selectable = column.selectable;
states.reserveSelection = column.reserveSelection;
}
/**
* 加入 index 标识,插入时用到
*/
if (!column.insertColumnIndex) {
column.insertColumnIndex = index;
}
if (this.table.$ready) {
this.updateColumns(); // hack for dynamics insert column
this.scheduleLayout();
}
},
};
Watcher.prototype.commit = function (name, ...args) {...
};
Watcher.prototype.updateTableScrollY = function () {...
};
export default Watcher;
文章来源:https://www.toymoban.com/news/detail-610144.html
到了这里,关于给el-table实现列显隐的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!