♻️ 重构WIKI筛选组件筛选逻辑

This commit is contained in:
BTMuli
2025-12-28 22:55:12 +08:00
parent bfab4a6ac6
commit e779467034
4 changed files with 115 additions and 51 deletions

View File

@@ -1,12 +1,13 @@
<!-- 角色筛选 -->
<template>
<TOverlay v-model="visible">
<div class="two-sc-container">
<div class="two-sc-item">
<div class="two-sc-title">星级</div>
<v-item-group multiple mandatory v-model="selectedStar" class="two-sc-select">
<v-item-group v-model="selectedStar" class="two-sc-select" multiple>
<div v-for="(item, index) in selectStarList" :key="index">
<v-item v-slot="{ isSelected, toggle }" :value="item">
<v-btn @click="toggle" :color="isSelected ? 'primary' : ''">
<v-btn :color="isSelected ? 'primary' : ''" @click="toggle">
<v-icon>{{ isSelected ? "mdi-star" : "mdi-star-outline" }}</v-icon>
<span>{{ item }}</span>
</v-btn>
@@ -16,10 +17,10 @@
</div>
<div class="two-sc-item">
<div class="two-sc-title">武器</div>
<v-item-group multiple mandatory v-model="selectedWeapon" class="two-sc-select">
<v-item-group v-model="selectedWeapon" class="two-sc-select" multiple>
<div v-for="(item, index) in selectWeaponList" :key="index">
<v-item v-slot="{ isSelected, toggle }" :value="item">
<v-btn @click="toggle" :color="isSelected ? 'primary' : ''">
<v-btn :color="isSelected ? 'primary' : ''" @click="toggle">
<img :alt="`${item}`" :src="`/icon/weapon/${item}.webp`" class="two-sci-icon" />
<span>{{ item }}</span>
</v-btn>
@@ -29,10 +30,10 @@
</div>
<div class="two-sc-item">
<div class="two-sc-title">元素</div>
<v-item-group multiple mandatory v-model="selectedElements" class="two-sc-select">
<v-item-group v-model="selectedElements" class="two-sc-select" multiple>
<div v-for="(item, index) in selectElementList" :key="index">
<v-item v-slot="{ isSelected, toggle }" :value="item">
<v-btn @click="toggle" class="element-btn" :color="isSelected ? 'primary' : ''">
<v-btn :color="isSelected ? 'primary' : ''" class="element-btn" @click="toggle">
<img
:alt="`${item}元素`"
:src="`/icon/element/${item}元素.webp`"
@@ -46,10 +47,10 @@
</div>
<div class="two-sc-item">
<div class="two-sc-title">阵营</div>
<v-item-group multiple mandatory v-model="selectedArea" class="two-sc-select">
<v-item-group v-model="selectedArea" class="two-sc-select" multiple>
<div v-for="(item, index) in selectAreaList" :key="index">
<v-item v-slot="{ isSelected, toggle }" :value="item">
<v-btn @click="toggle" :color="isSelected ? 'primary' : ''">
<v-btn :color="isSelected ? 'primary' : ''" @click="toggle">
<v-icon>{{ isSelected ? "mdi-check" : "mdi-checkbox-blank-outline" }}</v-icon>
<span>{{ item }}</span>
</v-btn>
@@ -64,10 +65,10 @@
</div>
</TOverlay>
</template>
<script setup lang="ts">
<script lang="ts" setup>
import TOverlay from "@comp/app/t-overlay.vue";
import showSnackbar from "@comp/func/snackbar.js";
import { ref, toRaw, watch } from "vue";
import { ref, shallowRef, watch } from "vue";
export type SelectedCValue = {
star: Array<number>;
@@ -97,11 +98,16 @@ const selectAreaList = [
"挪德卡莱",
];
// 选中的元素
const selectedStar = ref<Array<number>>(selectStarList);
const selectedWeapon = ref<Array<string>>(selectWeaponList);
const selectedElements = ref<Array<string>>(selectElementList);
const selectedArea = ref<Array<string>>(selectAreaList);
const selectedStar = ref<Array<number>>([]);
const selectedWeapon = ref<Array<string>>([]);
const selectedElements = ref<Array<string>>([]);
const selectedArea = ref<Array<string>>([]);
const oldVal = shallowRef<SelectedCValue>({
star: selectedStar.value,
weapon: selectedWeapon.value,
elements: selectedElements.value,
area: selectedArea.value,
});
const visible = defineModel<boolean>();
const resetModel = defineModel<boolean>("reset");
@@ -110,25 +116,47 @@ watch(
() => {
if (resetModel.value) {
if (
toRaw(selectedStar.value) === selectStarList &&
toRaw(selectedWeapon.value) === selectWeaponList &&
toRaw(selectedElements.value) === selectElementList &&
toRaw(selectedArea.value) === selectAreaList
isNotFilter(selectedStar.value, selectStarList) &&
isNotFilter(selectedWeapon.value, selectWeaponList) &&
isNotFilter(selectedElements.value, selectElementList) &&
isNotFilter(selectedArea.value, selectAreaList)
) {
showSnackbar.warn("无需重置");
resetModel.value = false;
return;
}
selectedStar.value = selectStarList;
selectedWeapon.value = selectWeaponList;
selectedElements.value = selectElementList;
selectedArea.value = selectAreaList;
selectedStar.value = [];
selectedWeapon.value = [];
selectedElements.value = [];
selectedArea.value = [];
oldVal.value = {
star: selectedStar.value,
weapon: selectedWeapon.value,
elements: selectedElements.value,
area: selectedArea.value,
};
resetModel.value = false;
showSnackbar.success("已重置");
}
},
);
watch(
() => visible.value,
() => {
if (visible.value) {
selectedStar.value = oldVal.value.star;
selectedWeapon.value = oldVal.value.weapon;
selectedArea.value = oldVal.value.area;
selectedElements.value = oldVal.value.elements;
}
},
);
function isNotFilter<T>(list: Array<T>, data: Array<T>): boolean {
return list.length === 0 || list.length === data.length;
}
function confirmSelect() {
const value: SelectedCValue = {
star: selectedStar.value,
@@ -137,6 +165,7 @@ function confirmSelect() {
area: selectedArea.value,
};
emits("select-c", value);
oldVal.value = value;
visible.value = false;
}
</script>

View File

@@ -1,12 +1,13 @@
<!-- 武器筛选 -->
<template>
<TOverlay v-model="visible">
<div class="two-sw-container">
<div class="two-sw-item">
<div class="two-sw-title">星级</div>
<v-item-group multiple mandatory v-model="selectedStar" class="two-sw-select">
<v-item-group v-model="selectedStar" class="two-sw-select" mandatory multiple>
<div v-for="(item, index) in selectStarList" :key="index">
<v-item v-slot="{ isSelected, toggle }" :value="item">
<v-btn @click="toggle" :color="isSelected ? 'primary' : ''">
<v-btn :color="isSelected ? 'primary' : ''" @click="toggle">
<v-icon>{{ isSelected ? "mdi-star" : "mdi-star-outline" }}</v-icon>
<span>{{ item }}</span>
</v-btn>
@@ -16,10 +17,10 @@
</div>
<div class="two-sw-item">
<div class="two-sw-title">武器</div>
<v-item-group multiple mandatory v-model="selectedWeapon" class="two-sw-select">
<v-item-group v-model="selectedWeapon" class="two-sw-select" mandatory multiple>
<div v-for="(item, index) in selectWeaponList" :key="index">
<v-item v-slot="{ isSelected, toggle }" :value="item">
<v-btn @click="toggle" :color="isSelected ? 'primary' : ''">
<v-btn :color="isSelected ? 'primary' : ''" @click="toggle">
<img :alt="`${item}元素`" :src="`/icon/weapon/${item}.webp`" class="two-swi-icon" />
<span>{{ item }}</span>
</v-btn>
@@ -34,12 +35,12 @@
</div>
</TOverlay>
</template>
<script setup lang="ts">
<script lang="ts" setup>
import TOverlay from "@comp/app/t-overlay.vue";
import showSnackbar from "@comp/func/snackbar.js";
import { ref, toRaw, watch } from "vue";
import { ref, shallowRef, watch } from "vue";
export type SelectedWValue = { star: Array<number>; weapon: Array<string>; isReset: boolean };
export type SelectedWValue = { star: Array<number>; weapon: Array<string> };
type TwoSelectWEmits = (e: "select-w", value: SelectedWValue) => void;
const emits = defineEmits<TwoSelectWEmits>();
@@ -47,8 +48,12 @@ const emits = defineEmits<TwoSelectWEmits>();
const selectStarList = [4, 5];
const selectWeaponList = ["单手剑", "双手剑", "弓", "法器", "长柄武器"];
const selectedStar = ref<Array<number>>(selectStarList);
const selectedWeapon = ref<Array<string>>(selectWeaponList);
const selectedStar = ref<Array<number>>([]);
const selectedWeapon = ref<Array<string>>([]);
const oldVal = shallowRef<SelectedWValue>({
star: selectedStar.value,
weapon: selectedWeapon.value,
});
const visible = defineModel<boolean>();
const resetModel = defineModel<boolean>("reset");
@@ -57,23 +62,43 @@ watch(
() => {
if (resetModel.value) {
if (
toRaw(selectedStar.value) === selectStarList &&
toRaw(selectedWeapon.value) === selectWeaponList
isNotFilter(selectedStar.value, selectStarList) &&
isNotFilter(selectedWeapon.value, selectWeaponList)
) {
showSnackbar.warn("无需重置");
resetModel.value = false;
return;
}
selectedStar.value = selectStarList;
selectedWeapon.value = selectWeaponList;
selectedStar.value = [];
selectedWeapon.value = [];
oldVal.value = {
star: selectedStar.value,
weapon: selectedWeapon.value,
};
resetModel.value = false;
emits("select-w", { star: selectedStar.value, weapon: selectedWeapon.value, isReset: true });
showSnackbar.success("已重置");
}
},
);
watch(
() => visible.value,
() => {
if (visible.value) {
selectedStar.value = oldVal.value.star;
selectedWeapon.value = oldVal.value.weapon;
}
},
);
function isNotFilter<T>(list: Array<T>, data: Array<T>): boolean {
return list.length === 0 || list.length === data.length;
}
function confirmSelect(): void {
emits("select-w", { star: selectedStar.value, weapon: selectedWeapon.value, isReset: false });
const value: SelectedWValue = { star: selectedStar.value, weapon: selectedWeapon.value };
emits("select-w", value);
oldVal.value = value;
visible.value = false;
}
</script>