template
<template> <div id="app"> <div class="info-line" v-for="key in Object.keys(menuInfo)" :key="key"> <div class="info-title">{{ menuInfo[key].title }}</div> <div class="info-list"> <div :class="{ active: menuInfo[key].activeIdx === idx, disabled: item.disabled }" class="info-item" v-for="(item, idx) in menuInfo[key].arr" :key="item.value" @click="itemClick(item, key, idx)" > {{ item.value }} </div> </div> </div> </div></template>
data
data() { return { menuInfo: { size: { activeIdx: -1, title: "大小", arr: [ { value: "XS", disabled: false, }, { value: "S", disabled: false, }, { value: "M", disabled: false, }, { value: "L", disabled: false, }, ], }, color: { activeIdx: -1, title: "颜色", arr: [ { value: "红色", disabled: false, }, { value: "绿色", disabled: false, }, { value: "蓝色", disabled: false, }, { value: "黑色", disabled: false, }, ], }, material: { activeIdx: -1, title: "面料", arr: [ { value: "条轮", disabled: false, }, { value: "纯棉", disabled: false, }, { value: "人造革", disabled: false, }, ], }, // 库存 infoArr: [ { color: "红色", size: "S", material: "人造革", num: 50, price: 84, }, { color: "黑色", size: "M", material: "条轮", num: 50, price: 84, }, { color: "黑色", size: "M", material: "条轮", num: 50, price: 84, }, { color: "蓝色", size: "L", material: "纯棉", num: 20, price: 84, }, ], }, // 筛选条件数组 filterList: [], // 结果数组 resList: [], }; },
methods
// 用户选择 itemClick(item, key, idx) { const filterIdx = this.filterList.findIndex((item) => item.key === key); // 已经选择的 再次点击取消选择 if (this.menuInfo[key].activeIdx === idx) { this.menuInfo[key].activeIdx = -1; if (filterIdx > -1) this.filterList.splice(filterIdx, 1); } else { // 未选择 更改选择 进栈 if (!item.disabled) { this.menuInfo[key].activeIdx = idx; if (filterIdx > -1) { this.filterList.splice(filterIdx, 1, { key, value: item.value }); } else { this.filterList.push({ key, value: item.value, }); } } } this.refreshDom(); },
// 刷新页面选择栏 refreshDom() { // 更新结果数组 this.resList = [...this.menuInfo.infoArr]; for (let i = 0; i < this.filterList.length; i++) { const filterItem = this.filterList[i]; this.resList = [...this.resList.filter((item) => item[filterItem.key] === filterItem.value)]; } // 遍历选择列表 Object.keys(this.menuInfo).forEach((key) => { if (this.menuInfo[key].arr) { this.menuInfo[key].arr.forEach((item) => { const it = this.resList.find((subItem) => subItem[key] === item.value); item.disabled = it ? false : true; }); } }); },
mounted
this.refreshDom();
style
.info-line { padding-top: 20px;}.info-title { font-size: 14px; font-weight: bold;}.info-list { display: flex; column-gap: 20px; padding-top: 20px;}.info-item { padding: 4px 10px; border: 1px solid #000; display: inline-block; cursor: pointer; font-size: 12px;}.info-item.active { color: red; border-color: red;}.info-item.disabled { color: #999; border-color: #999; cursor: not-allowed;}