都是日常的工作小结,编写不易,转载请注明出处~考虑到会看我博客的都是和我一样的小白,尽量写细一些,有问题可在评论区留言
一 实现原理
1.1 一般我们在写elementUI表格代码时,都可以通过v-if来控制某个列要不要隐藏,因为我的写表格代码时都是用v-for来写,所以可以在循环数组中设置哪一个列隐藏,在下面的代码中我就是通过show来判断,当循环到某一项,他的show===false时,这一列就隐藏。
1.2 表格演示代码(elementUI文档直接改动的,手敲的没跑过)
点击查看代码
<template>
<el-table
:data="tableData"
style="width: 100%">
<template v-for="item in tableForList">
<el-table-column
:key="item.key"
:prop="item.prop"
:label="item.label"
:width="item.width"
:min-width="item.minWidth"
:align="item.align ? item.align : 'center'"
:show-overflow-tooltip="!item.tooltip"
v-if="item.show !== false"
></el-table-column>
</template>
</el-table>
</template>
<script>
export default {
data() {
return {
tableData: [{
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 弄'
}],
tableForList:[{
prop: "active",
label: "操作",
width: "120",
fixed: true,
},
{
prop: "id",
label: "编号",
width: "140",
},
{
prop: "name",
label: "名称",
width: "180",
show: false
},]
}
}
}
</script>
二 实现方式
如果直接在代码里写死循环数组是不灵活的,也达不到我们想要的目的,所以我们必须要把循环数组展现给用户看,让用户来设置。用户设置后,我们要保存用户的配置到数据库,下一次用户再点到这个页面,第一件事情是去读数据库里用户的表格配置,从而改变我们默认的循环数组里每一项的show属性。考虑到通用问题,所以我做成了组件TableSelectColumn(我是全局注册组件的,不需要每个页面引入,引入方式根据自己的项目来)。先是使用TableSelectColumn,把组件放到"操作"列的旁边。把循环数组传入到组件中
表格效果图:
点击配置按钮,进入配置界面效果图:
流程如下:
①用户进入A模块表格页面-->
②读取数据库用户是否有设置,如果没有,就按默认的tableForList展示,如果有就把用户设置的隐藏列更新到tableForList中被设置的列的show属性(在created中实现这一步)-->
③用户点击设置按钮-->
④通过选择等方式去设置可见列(相当于设置tableForList每一项的show属性),点击保存-->
⑤保存到数据库,并且更新到当前列表-->
⑥下一次在进入,回到第一步
2.1 表格引用代码
<template>
<el-table
:data="tableData"
style="width: 100%">
<template v-for="item in tableForList">
<el-table-column
:key="item.key"
:prop="item.prop"
:label="item.label"
:width="item.width"
:min-width="item.minWidth"
:align="item.align ? item.align : 'center'"
:show-overflow-tooltip="!item.tooltip"
v-if="item.show !== false"
>
<template slot="header" v-if="item.prop === 'active'">
<template>
操作
<TableSelectColumn
ref="tableSelectColumn"
:list.sync="tableForList"
:name="'projectPrice'"
:loadingTime="2000"
:tableRef="$refs.queryTable"
/>
</template>
</template>
</el-table-column>
</template>
</el-table>
</template>
<script>
export default {
data() {
return {
tableData: [{
id: '1',
date: '2016-05-02',
name: '王小虎',
address: '上海市普陀区金沙江路 1518 弄'
}, {
id: '2',
date: '2016-05-04',
name: '王小虎',
address: '上海市普陀区金沙江路 1517 弄'
}, {
id: '3',
date: '2016-05-01',
name: '王小虎',
address: '上海市普陀区金沙江路 1519 弄'
}],
tableForList:[{
prop: "active",
label: "操作",
width: "120",
fixed: true,
},
{
prop: "id",
label: "编号",
width: "140",
},
{
prop: "name",
label: "名称",
width: "180",
show: false
},],
created() {
//表格第一次生成时要去读取这个用户在数据库的配置
this.$nextTick(() => {
this.$refs.tableSelectColumn[0].initTable();
});
},
}
}
}
</script>
2.2 TableSelectColumn组件代码
<template>
<!-- 使用此组件的表格,不要使用min-width属性,会在表格列隐藏/显示时出现错位情况,使用doLayout也没有用。
不要在created里调用接口,在表格列头中使用自定义组件会重复注册组件,导致created重复执行。 -->
<div style="display: inline-block">
<el-button
type="text"
icon="el-icon-setting"
@click="onClick"
size="mini"
></el-button>
<el-dialog
title="设置可见列"
:visible.sync="visible"
:before-close="handleClose"
:close-on-click-modal="false"
lock-scroll
append-to-body
width="650px"
>
<el-transfer
:filterable="true"
filter-placeholder="请输入列名"
v-model="selectVal"
:data="selectList"
:props="{
key: 'val',
label: 'label',
}"
:titles="['隐藏列', '可见列']"
style="margin: 0px 10px 0px 10px"
>
</el-transfer>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="handleSubmit">确 认</el-button>
<el-button @click="handleClose">取 消</el-button>
</span></el-dialog
>
</div>
</template>
<script>
import {
getTableHideList,
addTableHideList,
editTableHideList,
} from "@/api/system/tableHideList";
export default {
name: "TableSelectColumn",
props: {
list: {
required: true, //必填,列表循环数组
},
name: {
required: true, //必填,列表名称
},
fixedColumn: {
default: () => ["id", "active", "checkedBox"], //选填,不可选择的列名prop数组,不会出现在可见列配置界面
},
tableRef: {
required: true, //选填,表格的ref,表格会出现错乱情况的可通过ref使用doLayout对表格重新布局
},
loadingTime: {
default: 1000, //选填,设置后的遮罩时间,个别复杂的表格可以设置长一些
},
initMethods: {
type: Function,
default: undefined, //选填,个别表格需要在初始化时做其他处理的,就把方法传进来
},
updateMethods: {
type: Function,
default: undefined, //选填,个别表格需要在重新设置可见列后做其他处理的,就把方法传进来
},
},
data() {
return {
form: {
name: undefined,
id: undefined,
hideList: undefined,
createBy: undefined,
},
api: {
list: getTableHideList,
add: addTableHideList,
edit: editTableHideList,
},
visible: false,
selectVal: [],
selectList: [],
};
},
created() {
//在elementUI使用自定义组件,created会重复执行
this.form.createBy = this.$store.getters.name;
this.form.name = this.name;
},
methods: {
//获取隐藏列表,更新到父组件的列表数据
initTable() {
this.api.list(this.form).then((response) => {
if (response.rows.length > 0) {
this.form.id = response.rows[0].id;
let hideList = response.rows[0].hideList.split(",");
let list = JSON.parse(JSON.stringify(this.list));
list.map((item) => {
if (hideList.includes(item.prop)) {
item.show = false;
}
});
// console.log(hideList);
// console.log(list);
this.$emit("update:list", list);
if (this.initMethods) {
this.initMethods();
}
}
});
},
//提交
handleSubmit() {
const loading = this.$loading({
lock: true,
text: "正在配置表格列,请稍等",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)",
});
//保存隐藏列表
let list = JSON.parse(JSON.stringify(this.list));
this.form.hideList = "";
list.forEach((item) => {
if (this.selectVal.includes(item.prop)) {
item.show = true;
} else if (!this.fixedColumn.includes(item.prop)) {
item.show = false;
this.form.hideList += item.prop + ",";
}
});
this.api[this.form.id ? "edit" : "add"](this.form)
.then(() => {
this.$emit("update:list", list);
if (this.updateMethods) {
this.updateMethods();
}
this.$nextTick(() => {
setTimeout(() => {
loading.close();
this.handleClose();
}, this.loadingTime);
});
})
.catch(() => {
loading.close();
});
},
//打开配置界面
onClick() {
//获取最新的配置项
this.api.list(this.form).then((response) => {
this.visible = true;
if (response.rows.length > 0) {
this.form.id = response.rows[0].id;
}
this.selectVal = [];
this.selectList = [];
this.list.map((item) => {
if (!this.fixedColumn.includes(item.prop)) {
this.selectList.push({
val: item.prop,
label: item.label,
});
if (item.show !== false) {
this.selectVal.push(item.prop);
}
}
});
});
},
handleClose() {
this.visible = false;
this.$nextTick(() => {
if (this.tableRef && this.tableRef.doLayout) {
this.tableRef.doLayout();
}
});
},
},
watch: {
// tableRef: function (val) {},
},
};
</script>
<style>
</style>
三 数据库建表参考
因为我的项目每一个模块都有一张表,每个人又有自己的配置,所以我主要是根据name和create_by去查这个人的hide_list,hide_list是隐藏列,以字符串的形式存储,例如
hide_list:'id,name'