最终效果图
倒数第二行是筛选条件,最后一行是筛选出的商品。
从后端获取的数据如下:
export default {
json1: [
['红色', '黄色', '蓝色'],
['S', 'M'],
['棉的', '涤纶']
],
json2: [
{
color: '红色',
type: 'S',
mianliao: '棉的',
price: 600
},
{
color: '黄色',
type: 'S',
mianliao: '棉的',
price: 500
},
{
color: '蓝色',
type: 'S',
mianliao: '棉的',
price: 1000
},
{
color: '红色',
type: 'M',
mianliao: '涤纶',
price: 100
},
{
color: '黄色',
type: 'M',
mianliao: '棉的',
price: 1000
}
]
}
代码:
<template>
<div style="height: 400px">
<ul>
<li v-for="(rowData, rowIndex) in mockData.json1"
:key="rowIndex"
style="display: flex; justify-content: center; align-items: center;margin:10px 0; text-align: center;">
<div v-for="(item, index) in rowData"
:key="index"
:class="{
active: condition[types[rowIndex]] === item // STEP6
}"
@click="handleBtnClick(item, rowIndex)"
style="width: 100px; height: 60px; line-height: 60px; border: 1px solid red;margin:0 8px;">
{{item}}
</div>
</li>
</ul>
<hr />
{{condition}}
<hr />
{{displayData}}
</div>
</template>
<script>
import mockData from './data'
// STEP5
function _diff(obj1, obj2) {
if (!obj1 || !obj2) throw new Error('传参格式不正确')
for (const key in obj1) {
const val1 = obj1[key]
const val2 = obj2[key]
if (val1 !== val2) return false
}
return true
}
export default {
data() {
return {
mockData: Object.freeze(mockData),
condition: {},
types: []
}
},
methods: {
handleBtnClick(item, rowIndex) {
// STEP1
this.$set(this.condition, this.types[rowIndex], item)
},
},
computed: {
// STEP4
displayData() {
return this.mockData.json2.filter(item => _diff(this.condition, item))
}
},
created() {
// STEP2
const defaultGood = this.mockData.json2[0]
this.types = Object.keys(defaultGood)
// STEP3,设置默认值:初始匹配第一个元素的条件
this.types.forEach(propName => {
// this.condition[propName] = defaultGood[propName]
// 动态添加的属性,数据更新,页面不更新,用$SET
// 因为vue2无法察觉对对象新增或删除的属性,vue3的proxy可以察觉
if (propName === 'price') return false
this.$set(this.condition, propName, defaultGood[propName])
})
},
}
</script>
<style scoped>
.active {
background: pink;
}
</style>