vue表格列筛选显示

271 阅读2分钟

痛点: 表格显示列太多,用户只想看到自己想要看的列数据

解决思路: 让用户可自己勾选显示的列

方案: 已勾选显示的列show属性为true,表格的列是动态渲染(show为true显示)

<template>
   <!-- 表格动态列筛选 -->
   <el-container class="a-section" style="margin-top: 150px;">
   	<el-table ref="dataTable" :data="tableData" element-loading-text="加载中" fit>
   		<template v-for="(item, index) in tableHeader">
   			<el-table-column v-if="tableHeader[index].isShow" :key="index" :label="item.label" :prop="item.prop" align="center">
   				<template slot-scope="scope">
   					<span>{{ scope.row[item.prop] }}</span>
   				</template>
   			</el-table-column>
   		</template>
   		<el-table-column label="操作" fixed="right">
   			<template slot="header" slot-scope="scope">
   				<a href="javascript:;">
   					<el-popover :ref="`popover-${scope.$index}`" width="400" placement="left" trigger="click">
   						<p>表格显示列调整:</p>
   						<el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox>
   						<p></p>
   						<el-checkbox-group class="columnSelectGroup" v-model="columnSelecteds" @change="columnSelectedChange">
   							<el-checkbox v-for="item in tableHeader" v-show="item.label" :key="item.label" :label="item.label" />
   						</el-checkbox-group>
   						<div slot="reference">
   							<i class="el-icon-s-grid" />
   							操作
   						</div>
   					</el-popover>
   				</a>
   			</template>
   			<template slot-scope="scope">
   				<el-button class="a-btn-mini">
   					编辑
                       
   				</el-button>
   			</template>
   		</el-table-column>
   	</el-table>
   </el-container>
</template>
<script>
export default {
   name: 'move_table',
   data: function () {
   	var vm = this;
   	return {
   		tableHeader: [
   			{
   				label: '日期',
   				prop: 'date',
   			},
   			{
   				label: '姓名',
   				prop: 'name',
   			},
   			{
   				label: '省',
   				prop: 'province',
   			},
   			{
   				label: '区',
   				prop: 'city',
   			},
   			{
   				label: '地址',
   				prop: 'address',
   			},
   			{
   				label: '邮编',
   				prop: 'zip',
   			},
   			{
   				label: '标签',
   				prop: 'tag',
   			},
   		],
   		tableData: [{
   			date: '2016-05-02',
   			name: '王小虎',
   			province: '上海',
   			city: '普陀区',
   			address: '上海市普陀区金沙江路 1518 弄',
   			zip: 200333,
   			tag: '家'
   		}, {
   			date: '2016-05-04',
   			name: '王小虎',
   			province: '上海',
   			city: '普陀区',
   			address: '上海市普陀区金沙江路 1517 弄',
   			zip: 200333,
   			tag: '公司'
   		}, {
   			date: '2016-05-01',
   			name: '王小虎',
   			province: '上海',
   			city: '普陀区',
   			address: '上海市普陀区金沙江路 1519 弄',
   			zip: 200333,
   			tag: '家'
   		}, {
   			date: '2016-05-03',
   			name: '王小虎',
   			province: '上海',
   			city: '普陀区',
   			address: '上海市普陀区金沙江路 1516 弄',
   			zip: 200333,
   			tag: '公司'
   		}],
   		isIndeterminate: true, //indeterminate 属性用以表示 checkbox 的不确定状态,一般用于实现全选的效果
   		checkAll: false, //是否全选
   		columnSelecteds: [], // 已选择的项
   	}
   },
   watch: {
   },
   mounted: function () {
   	this.initColumnSelected()
   },
   methods: {
   	// 初始化要显示的列
   	initColumnSelected() {
   		// 拿到所有页面中的表格列,并赋值isShow字段
   		let allLabels = this.tableHeader.map((item) => {
   			item.isShow = true;
   			return item.label;
   		})
   		// 先存储,因为isShow是后面加上的,页面不会渲染,要清空掉tableHeader重新渲染一遍
   		let tableHeader = Common.Util.deepCopy(this.tableHeader)
   		this.tableHeader = []

   		// 从缓存中取表格列
   		if (JSON.parse(localStorage.getItem(this.$options.name + 'columnSelecteds')) && JSON.parse(localStorage.getItem(this.$options.name + 'columnSelecteds')).length) {
   			// 如果有,则要判断缓存的表格列中是否有已经删掉的列,有则去除掉
   			let oldColumnSelecteds = JSON.parse(localStorage.getItem(this.$options.name + 'columnSelecteds'))
   			this.columnSelecteds = oldColumnSelecteds.filter(value => {
   				return allLabels.includes(value)
   			});
   		} else { //如果没有,则所有的表格列都显示
   			this.columnSelecteds = allLabels
   		}

   		this.tableHeader = tableHeader;
   		this.columnSelectedChange(this.columnSelecteds)
   	},
   	// 显示列变动事件
   	columnSelectedChange(newArrayVal) {
   		// 计算为被选中的列标题数组
   		var nonSelecteds = this.tableHeader
   			.filter((item) => newArrayVal.indexOf(item.label) === -1)
   			.map((item) => item.label)
   		// 根据计算结果进行表格重绘
   		this.tableHeader.filter((item) => {
   			const isNonSelected = nonSelecteds.indexOf(item.label) !== -1
   			if (isNonSelected) {
   				// 隐藏未选中的列
   				item.isShow = false
   				this.$nextTick(() => {
   					this.$refs.dataTable.doLayout()
   				})
   			} else {
   				// 显示已选中的列
   				item.isShow = true
   				this.$nextTick(() => {
   					this.$refs.dataTable.doLayout()
   				})
   			}
   		})
   		this.judgeAll(newArrayVal)

   	},
   	// 全选显示逻辑
   	judgeAll(newArrayVal) {
   		let options = this.tableHeader.map((item) => {
   			return item.label
   		})
   		let checkedCount = newArrayVal.length;
   		this.checkAll = checkedCount === options.length;
   		this.isIndeterminate = checkedCount > 0 && checkedCount < options.length;
   		localStorage.setItem(this.$options.name + 'columnSelecteds', JSON.stringify(this.columnSelecteds))
   	},
   	// 全选变动事件
   	handleCheckAllChange(val) {
   		let options = this.tableHeader.map((item) => {
   			return item.label
   		})
   		this.columnSelecteds = val ? options : [];
   		this.isIndeterminate = false;
   		this.columnSelectedChange(this.columnSelecteds)
   	},
   },

}
</script>
<style lang="scss" scoped>
.columnSelectGroup {
   display: flex;
   // flex-direction: column;
   flex-wrap: wrap;
   .el-checkbox {
   	width: 45%;
   	margin-left: 0px;
   	margin-right: 0px;
   }
}
</style>

结果展示

image.png