手写一个淘宝商品动态计算功能

91 阅读1分钟

最终效果图

image.png 倒数第二行是筛选条件,最后一行是筛选出的商品。

从后端获取的数据如下:

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>