需求:用户想自由选取某几列进行显示,并且可以修改列的顺序
先看实现的页面,字段的顺序是直接手动拖动的
代码
组件tableui
用到了vuedraggable插件 npm i -S vuedraggable
<template>
<div>
<el-dialog :visible.sync="dialogVisible" width="30%" title="字段配置">
<el-tabs v-model="activeName">
<el-tab-pane label="字段选择" name="fieldsChosen">
<el-checkbox
v-model="checkAll"
@change="handleCheckAllChange"
:indeterminate="isIndeterminate"
>全部</el-checkbox
>
<el-checkbox-group
v-model="checkedColumn"
@change="handleCheckedList"
>
<el-checkbox
style="width: 40%"
v-for="item in columns"
:label="item.name"
:key="item.name"
>{{ item.name }}</el-checkbox
>
</el-checkbox-group>
</el-tab-pane>
<el-tab-pane label="字段顺序" name="fieldSorted">
<vuedraggable
:list="checkedColumn"
@start="dragging = true"
@end="dragging = false"
animation="300"
>
<div
v-for="item in checkedColumn"
style="
background-color: gainsboro;
margin: 10px;
padding: 5px;
text-align: center;
cursor: pointer;
"
:key="item"
>
{{ item }}
</div>
</vuedraggable>
</el-tab-pane>
</el-tabs>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisiblefalse" class="buttonRight"
>取 消</el-button
>
<el-button type="primary" @click="submit" class="buttonRight"
>确 定</el-button
>
</span>
</el-dialog>
</div>
</template>
<script>
import vuedraggable from "vuedraggable";
export default {
name: "Test",
components: {
vuedraggable,
},
props: {
dialogVisible: {
type: Boolean,
},
// 列信息
checkedColumns: {
type: Array,
},
},
data() {
return {
dragging: false,
expandRowKeys: [],
activeName: "fieldsChosen",
checkAll: false,
isIndeterminate: true,
fieldsTemp: [], //存放按指定顺序排列的fields数组
fields: [],
deepCloneArray: [],
checkedColumnsSelect: [],
checkedColumn: [],
};
},
computed: {
fieldList() {
return this.checkedColumns;
},
columns() {
return this.checkedColumns;
},
},
watch: {
checkedColumns(val) {
this.checkedColumn = JSON.parse(JSON.stringify(val));
//这里我只拿了名字
this.checkedColumn = this.checkedColumn.map((o) => o.name);
},
},
mounted() {
this.deepCloneArray = JSON.parse(JSON.stringify(this.fields));
},
methods: {
//关弹框
dialogVisiblefalse() {
this.$emit("dialogVisiblefalse", false);
},
//全选
handleCheckAllChange(val) {
this.checkedColumn = val ? this.checkedColumns.map((o) => o.name) : [];
this.isIndeterminate = false;
},
handleCheckedList(val) {
this.checkedColumnsSelect = val;
let checkedCount = val.length;
this.checkAll = checkedCount === this.columns.length;
this.isIndeterminate =
checkedCount > 0 && checkedCount < this.columns.length;
},
//保存
submit() {
//按拖动后的顺序给列表排队,没选择的就不显示
let index = 0;
let sortArray = []
// 这里this.checkedColumn是拖动后的顺序名称列表,将属性的列表按照排序的列表排序
for (const name of this.checkedColumn) {
const item = this.fieldList.find((o) => o.name == name);
if (item) {
item.index = index; //index好像没用到
sortArray.push(item);
index++;
}
}
//更新表格展示列,把数据传回父组件
this.$emit("getlabList",sortArray)
//关弹框
this.dialogVisiblefalse();
},
},
};
</script>
<style lang="scss" scoped>
:deep(.el-dialog__body) {
padding-top: 0;
}
</style>
原页面 传给组件完整的属性,组件处理好再传回来保存并且渲染
<template>
<el-button type="primary" @click="handleConfig" size="mini">字段配置</el-button>
<el-table .....> //原来的写法就行
//不需要动态的列就原来的写法
//下边演示的是需要自由设置的列
<el-table-column
v-for="item in filterLabList"
:key="item.index"
:label="item.name"
show-overflow-tooltip
align="center"
:prop="item.prop"
>
//下边演示不能直接prop渲染,需要处理的列写法,就是一个iF判断
<template slot-scope="scope">
<div v-if="item.name == '测试时间'">
<span>{{ getformatDate(scope.row.gmtCreate) }}</span>
</div>
</template>
</el-table-column>
</el-table>
<-- 弹框组件 -->
<tableui
:dialogVisible="dialogVisible"
:checkedColumns="checkedColumns" //把所有列传给组件
@getlabList="getlabList" //这是保存后列按照配置的刷新
@dialogVisiblefalse="dialogVisiblefalse" //关弹框
</tableui>
</template>
<script>
import tableui from "@/views/components/tableui";
export default {
components: {tableui },
data() {
return {
dialogVisible: false,
checkedColumns: [ //自己列的全部属性
{ name: "日期", prop: "testDate" },
{ name: "项目名称", prop: "testName" },
..................
{ name: "测试时间", prop: "gmtCreate" },
],
filterLabList:[]
}
},
mounted() {
this.getStorageList() //先去取本地存的顺序列表
},
methods:{
//取本地
getStorageList() {
var storedList = JSON.parse(localStorage.getItem("filterLabList"));
if (storedList) {
this.filterLabList = storedList;
} else {
this.filterLabList = this.checkedColumns
}
},
//开关弹框
handleConfig() {
this.dialogVisible = true;
},
dialogVisiblefalse() {
this.dialogVisible = false;
},
//存本地
getlabList(list) {
this.filterLabList = list;
//存一份到本地
var listString = JSON.stringify(list);
localStorage.setItem("filterLabList", listString);
}
}
}
</script>
意思就这么个意思,仅做个参考