页面布局
标签筛选器类型
- 前几层的select选择框是单选,最后一层select选择框是多选,最后一层选择后,要带着前几层选择的值和最后一层选择的值,以单个标签的形式显示到下面的div中,最后一层的select框和div框中的每一个标签相互联动
- 若前几层select框的值经过几次改动后,又选择回来之前选择的值,最后一层select框要回显之前选择的值,同时下面的div框也要显示出相应的单值标签
数据处理方法:
- 因为层级的层数和每一层里面的数据要通过两个接口获取,这里使用两个数组处理数据,用一个数组记录层级数(用于渲染select),修改层级数组中的level字段,使其从0开始,去生成对应select下option内容的数组
let temp_data: Array<CascadeItem> = [];
const last_data = [
{
level: res.data.length + 1,
description: '请选择',
},
];
temp_data = res.data.concat(last_data);
// 这里修改level的值,是为了循环出的select和option的值能够一一对上
temp_data.forEach((i, idx) => {
i.level = idx;
});
store.filter_level_list = cloneDeep(temp_data);
store.filter_level_list.forEach(async (item, index) => {
// 这里循环层级是为了给每个select,匹配相应的option,设置每个option的初始值,清空上一次的值
store.filter_level_values[item.level] = [];
// 设置当前select选中的值
if (index === store.filter_level_list.length - 1) {
store.filter_current_value[item.level] = [];
} else {
store.filter_current_value[item.level] = '';
}
// 为了打开弹窗时,获取到第一个下拉框的option
if (index === 0) {
...
}
});
2.最后一层select是多选框,有全选的功能,在change函数中要特殊处理,同时要记录前面几层选择的值,以便显示到下面的内容展示框中层级筛选器
// 如果是最后一层(全选或非全选)
if (idx === length - 1) {
store.filter_current_value[idx] = option.map((i: any) => {
return i.value;
});
if (option.length > 0) {
option.forEach((i: any) => {
// 处理全选
if (i.value === '全选') {
...
} else {
// 处理不选择全选的情况
store.filter_level_values[idx].forEach(
(item) => {
if (item.value_name === '全选') {
item.is_disabled = true;
}
},
);
...
}
});
} else if (option.length === 0) {
...
}
} else {
// 非最后一层(层级筛选)
store.filter_current_value[idx] = option.value;
const pre_filter_name_arr: any = [];
Array(length)
.fill(0)
.forEach((_, i) => {
if (
store.filter_current_value[i] !== '' &&
typeof store.filter_current_value[i] ===
'string'
)
pre_filter_name_arr.push(
store.filter_current_value[i],
);
});
// 记录前几层选择的值
store.pre_filter_name = pre_filter_name_arr.join('/') + '/';
const new_temp = cloneDeep(store.filter_current_value);
// 改变选择的值,清空数据
for (let i = 0; i < length; i++) {
if (is_clean_data) {
store.filter_level_values[i] = [];
if (i === length - 1) {
new_temp[i] = [];
} else {
new_temp[i] = '';
}
} else if (i === idx) {
is_clean_data = true;
}
}
store.filter_current_value = new_temp;
...
}
3.select多选框删除已选择的值时,保持div框中内容联动一致,这里用了select的onDeselect方法,它的参数是删除的值,通过它的参数处理div中单值标签数组,保证内容一致,同时删除div中单值标签,也要保证select框的数据是正确的,使用tag的onClose事件
// select多选时,取消选中时,触发函数
async handleLevelFilterSelectDeChange(value: any) {
const length = store.filter_level_list.length;
store.de_select_option_value = value;
store.show_filter_content_list = store.show_filter_content_list.filter(
(item) => item.value !== value,
);
if (value === '全选') {
...
}
},
// 点击展示标签的删除时,上下联动效果
handleTagClose(data_value: ShowFilterValue) {
const length = store.filter_level_list.length;
// 删除已经选中的值
store.show_filter_content_list.forEach((i, idx) => {
if (i.value === data_value.value) {
store.show_filter_content_list.splice(idx, 1);
}
});
// 最后一个select当前选择的值
let last_select_values = store.filter_current_value[length - 1];
// 检验当前删除的值,是否在列表中
const temp_arr = store.filter_level_values[length - 1].filter(
(item) => {
return item.value_name === data_value.value;
},
);
// 如果删除的值在列表中
if (temp_arr.length > 0) {
// 如果当前值选择是全选,删除一个值,则需要把全选置灰,同时需要修改当前选择的值
...
}
// 重置当前选择的值
...
// 将选择的值删除完了,则全选也可以选择了
...
},
上面主要说了层级筛选器数据交互的处理方法,对于与后端交互数据封装就不在这里啰嗦啦!