Files
dm-manage-web/src/components/Sift/index.vue

180 lines
5.4 KiB
Vue
Raw Normal View History

2023-02-15 09:17:05 +08:00
<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>