Files
dm-manage-web/src/components/Sift/index.vue
2023-02-15 09:17:05 +08:00

180 lines
5.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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>