180 lines
5.4 KiB
Vue
180 lines
5.4 KiB
Vue
<template>
|
||
<div>
|
||
<el-button type="info" @click="show = true">筛选</el-button>
|
||
|
||
<el-dialog v-if="show" title="筛选" :visible.sync="show" width="960px">
|
||
<el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange">全选 </el-checkbox>
|
||
<div style="margin: 5px 0" />
|
||
<div class="dash" />
|
||
<div style="margin: 20px 0" />
|
||
<!-- 所有的表格列,注意勾选的回显 -->
|
||
<el-checkbox v-for="item in list" :key="item.prop" v-model="item.checked" :checked="item.checked" style="width: 90px">
|
||
{{ item.label }}
|
||
</el-checkbox>
|
||
<div style="margin: 5px 0" />
|
||
<div class="dash" />
|
||
<div style="margin: 20px 0" />
|
||
<!-- 使用draggable插件---绑定taglist对拖动后tagList的顺序进行修改 -->
|
||
<draggable v-model="tagList">
|
||
<el-tag v-for="tag in tagList" :key="tag.prop" type="danger">
|
||
{{ tag.label }}
|
||
</el-tag>
|
||
</draggable>
|
||
<span slot="footer">
|
||
<el-button @click="show = false">取消</el-button>
|
||
<el-button type="primary" @click="handleConfirm">确认</el-button>
|
||
</span>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import draggable from 'vuedraggable'; // 使用draggable插件---拖动筛选后的表头tag达到排序目的
|
||
export default {
|
||
name: 'SiftTableColumn',
|
||
components: {
|
||
draggable
|
||
},
|
||
props: {
|
||
allList: {
|
||
// 所有选项
|
||
type: Array,
|
||
default: () => []
|
||
},
|
||
checkedList: {
|
||
// 勾选过的选项,父组件在localstorage里取值,如果取不到值,默认为所有选项的值
|
||
type: Array,
|
||
default: () => []
|
||
}
|
||
},
|
||
data() {
|
||
return {
|
||
tagList: [], // tag绑定的值
|
||
list: [], // checkbox绑定的值
|
||
show: false,
|
||
isIndeterminate: false, // 全选是否半选
|
||
checkAll: true // 是否全选
|
||
};
|
||
},
|
||
watch: {
|
||
// 监听记录的勾选数组变化,更新数据
|
||
checkedList: {
|
||
handler() {
|
||
this.resetList();
|
||
},
|
||
deep: true,
|
||
immediate: true
|
||
},
|
||
show() {
|
||
this.resetList();
|
||
},
|
||
// 监听list的变化,如果某项被勾选或者取消勾选,更新tagList数据来使list勾选项与taglist保持一致且不改变tagList顺序
|
||
list: {
|
||
handler(val) {
|
||
this.getAllChecked();
|
||
const arr = val.filter((item) => item.checked);
|
||
const arr1 = [];
|
||
if (arr.length > this.tagList.length) {
|
||
for (const item of arr) {
|
||
const contain = this.tagList.find((it) => {
|
||
return it.prop === item.prop;
|
||
});
|
||
if (!contain) {
|
||
this.tagList.push(item);
|
||
}
|
||
}
|
||
} else {
|
||
for (const item of this.tagList) {
|
||
const contain = arr.find((it) => {
|
||
return it.prop === item.prop;
|
||
});
|
||
if (contain) {
|
||
arr1.push(item);
|
||
}
|
||
}
|
||
this.tagList = arr1;
|
||
}
|
||
},
|
||
deep: true
|
||
}
|
||
},
|
||
created() {
|
||
this.resetList();
|
||
},
|
||
methods: {
|
||
// 根据接收的val判断全选是否勾选,使list的所有checked属性变为val的值
|
||
handleCheckAllChange(val) {
|
||
this.list = this.allList.map((item) => ({
|
||
...item,
|
||
checked: val
|
||
}));
|
||
},
|
||
// 选择表头后按确认时,将tagList的值存下来,用于下次父组件中checkedList取值,同时将checkedList的值更新为tagList
|
||
handleConfirm() {
|
||
let localColumns = localStorage.getItem(this.$route.name); // 存储名设为路由名方便不同页面复用
|
||
localColumns = localColumns ? JSON.parse(localColumns) : {};
|
||
this.$set(localColumns, localStorage.getItem('name'), this.tagList); // 使要存储的数组变成map对象,以存储不同的账号的选择的表头
|
||
localStorage.setItem(this.$route.name, JSON.stringify(localColumns));
|
||
this.$emit('update:checkedList', this.tagList);
|
||
this.show = false;
|
||
},
|
||
// 判断接收到的allList和checkedList中是否具有相同的属性值对list赋值
|
||
resetList() {
|
||
this.list = this.allList.map((item) => ({
|
||
...item,
|
||
checked: this.checkedList.some((it) => it.prop === item.prop)
|
||
}));
|
||
this.tagList = this.deepClone(this.checkedList);
|
||
this.getAllChecked();
|
||
},
|
||
// 判断list中checked的数量来改变全选框中半选和全选的状态
|
||
getAllChecked() {
|
||
let num = 0;
|
||
this.list.forEach((item) => {
|
||
if (item.checked) {
|
||
num++;
|
||
}
|
||
});
|
||
this.isIndeterminate = num > 0 && num < this.list.length;
|
||
this.checkAll = num === this.list.length;
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.dash {
|
||
height: 0;
|
||
border-top: 2px dashed #ccc;
|
||
width: 100%;
|
||
}
|
||
::v-deep .el-tag--small {
|
||
margin: 5px;
|
||
}
|
||
::v-deep .el-button--info {
|
||
background-color: #f8456b;
|
||
border-color: #f8456b;
|
||
}
|
||
::v-deep .el-checkbox__input.is-indeterminate .el-checkbox__inner {
|
||
background-color: #f8456b;
|
||
border-color: #f8456b;
|
||
}
|
||
::v-deep .el-checkbox__input.is-checked .el-checkbox__inner,
|
||
.el-checkbox__input.is-indeterminate .el-checkbox__inner {
|
||
background-color: #f8456b;
|
||
border-color: #f8456b;
|
||
}
|
||
|
||
::v-deep .el-checkbox__input.is-checked + .el-checkbox__label {
|
||
color: #f8456b;
|
||
}
|
||
|
||
::v-deep .el-checkbox__input.is-focus .el-checkbox__inner {
|
||
border-color: #f8456b;
|
||
}
|
||
|
||
::v-deep .el-checkbox__inner:hover {
|
||
border-color: #f8456b;
|
||
}
|
||
</style>
|