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>
|