前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >前端SKU实现

前端SKU实现

作者头像
用户9260067
修改2022-03-24 18:30:52
6150
修改2022-03-24 18:30:52
举报
文章被收录于专栏:开发小白的笔记

个人理解,有问题或者更好的方法欢迎一起探讨

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>前端SKU实现</title>
</head>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>

<body>
    <div id="app">
        <h3>前端SKU实现</h3>
        <div v-for="(item,index) in specList" :key="index">
            <div class='title'>{{item.title}}</div>
            <div class='spec'>
                <div class='spec-item' v-for="(its,ins) in item.list" :key="its.name + ins">
                    <span @click="changeSpec(item.title, its.name, its.able)"
                        :class="[selectSpec[item.title] === its.name ? 'active' : '' , its.able? '' : 'disabled']">{{its.name}}</span>
                </div>
            </div>
        </div>
    </div>
</body>
<script>
    var app = new Vue({
        el: '#app',
        data: {
            specList: [
                { title: "颜色", list: ["红色", "紫色", "白色", "黑色"] },
                { title: "套餐", list: ["套餐一", "套餐二", "套餐三", "套餐四"] },
                { title: "内存", list: ["64G", "128G", "256G"] }
            ],

            skuList: [
                // { id: 1608188117177, specs: ["红色", "套餐一", "64G"] },
                { id: 1608188117178, specs: ["红色", "套餐一", "128G"] },
                { id: 1608188117179, specs: ["红色", "套餐一", "256G"] },
                { id: 1608188117180, specs: ["红色", "套餐二", "64G"] },
                { id: 1608188117181, specs: ["红色", "套餐二", "128G"] },
                { id: 1608188117182, specs: ["红色", "套餐二", "256G"] },
                { id: 1608188117183, specs: ["红色", "套餐三", "64G"] },
                { id: 1608188117184, specs: ["红色", "套餐三", "128G"] },
                { id: 1608188117185, specs: ["红色", "套餐三", "256G"] },
                // { id: 1608188117186, specs: ["红色", "套餐四", "64G"] },
                // { id: 1608188117187, specs: ["红色", "套餐四", "128G"] },
                // { id: 1608188117188, specs: ["红色", "套餐四", "256G"] },
                // { id: 1608188117189, specs: ["紫色", "套餐一", "64G"] },
                // { id: 1608188117190, specs: ["紫色", "套餐一", "128G"] },
                // { id: 1608188117191, specs: ["紫色", "套餐一", "256G"] },
                { id: 1608188117192, specs: ["紫色", "套餐二", "64G"] },
                { id: 1608188117193, specs: ["紫色", "套餐二", "128G"] },
                { id: 1608188117194, specs: ["紫色", "套餐二", "256G"] },
                { id: 1608188117195, specs: ["紫色", "套餐三", "64G"] },
                { id: 1608188117196, specs: ["紫色", "套餐三", "128G"] },
                { id: 1608188117197, specs: ["紫色", "套餐三", "256G"] },
                { id: 1608188117198, specs: ["紫色", "套餐四", "64G"] },
                { id: 1608188117199, specs: ["紫色", "套餐四", "128G"] },
                { id: 1608188117200, specs: ["紫色", "套餐四", "256G"] },
                { id: 1608188117201, specs: ["白色", "套餐一", "64G"] },
                { id: 1608188117202, specs: ["白色", "套餐一", "128G"] },
                { id: 1608188117203, specs: ["白色", "套餐一", "256G"] },
                { id: 1608188117204, specs: ["白色", "套餐二", "64G"] },
                // { id: 1608188117205, specs: ["白色", "套餐二", "128G"] },
                // { id: 1608188117206, specs: ["白色", "套餐二", "256G"] },
                // { id: 1608188117207, specs: ["白色", "套餐三", "64G"] },
                // { id: 1608188117208, specs: ["白色", "套餐三", "128G"] },
                // { id: 1608188117209, specs: ["白色", "套餐三", "256G"] },
                // { id: 1608188117210, specs: ["白色", "套餐四", "64G"] },
                { id: 1608188117211, specs: ["白色", "套餐四", "128G"] },
                { id: 1608188117212, specs: ["白色", "套餐四", "256G"] },
                // { id: 1608188117213, specs: ["黑色", "套餐一", "64G"] },
                // { id: 1608188117214, specs: ["黑色", "套餐一", "128G"] },
                // { id: 1608188117215, specs: ["黑色", "套餐一", "256G"] },
                // { id: 1608188117216, specs: ["黑色", "套餐二", "64G"] },
                // { id: 1608188117217, specs: ["黑色", "套餐二", "128G"] },
                // { id: 1608188117218, specs: ["黑色", "套餐二", "256G"] },
                // { id: 1608188117219, specs: ["黑色", "套餐三", "64G"] },
                // { id: 1608188117220, specs: ["黑色", "套餐三", "128G"] },
                // { id: 1608188117221, specs: ["黑色", "套餐三", "256G"] },
                // { id: 1608188117222, specs: ["黑色", "套餐四", "64G"] },
                // { id: 1608188117223, specs: ["黑色", "套餐四", "128G"] },
                // { id: 1608188117224, specs: ["黑色", "套餐四", "256G"] }
            ],
            selectSpec: {},
        },
        created() {
            // 初始化选择数据的对象 
            // this.specList.forEach(item => {
            //     this.$set(this.selectSpec, item.title, "");
            // })
            this.selectSpec = {
                '颜色': '',
                '套餐': '套餐一',
                '内存': '64G'
            }
            // 将规格数据处理成我们视图所需要的数据类型 
            this.specList = this.specList.map(item => {
                return {
                    title: item.title,
                    list: item.list.map(its => {
                        return {
                            name: its,
                            //  判断是否可以选择
                            //  这里相当于init 初始化数据  this.isAble() 核心判断逻辑  
                            able: this.isAble(item.title, its)  // 注释的调试看逻辑代码 false 
                        }
                    })
                }
            })
            // 注释的调试看逻辑代码
            // this.selectSpec = {
            //   '颜色':'',
            //   '套餐':'套餐一',
            //   '内存':'64G'
            // }
            // this.isAble('颜色', '红色')
        },
        methods: {
            // 核心判断逻辑 
            // 判断规格是否可以被选择  核心函数 key当前的规格的title   value规格值
            // '颜色', '红色'
            isAble(key, value) {  //此时 key = 颜色    value = 红色
                var copySelectSpec = JSON.parse(JSON.stringify(this.selectSpec));
                // 赋值当前选择项
                copySelectSpec[key] = value;  // 此时 copySelectSpec = {"颜色":"红色","套餐":"套餐一","内存":"64G"}

                let flag = this.skuList.some(item => {
                    // 按照上面的skuList数据 此时第一次循环 item = { id: 1608188117178, specs: ["红色", "套餐一", "128G"] }
                    var i = 0;
                    // copySelectSpec去匹配item.specs
                    /* {"颜色":"红色","套餐":"套餐一","内存":"64G"} 匹配 ["红色", "套餐一", "128G"] 
                    如果选了 套餐一和64G 的情况下 结果i=2;证明此项不可选择*/
                    for (let k in copySelectSpec) {  //  for in  懂吧?
                        // copySelectSpec[k]  判断第一个标签是否可选的时候(红色),依次是 '红色' \ '套餐一' \ '64G'
                        if (copySelectSpec[k] != "" && item.specs.includes(copySelectSpec[k])) {  // item中有红色 i++    
                            i++
                        } else if (copySelectSpec[k] == "") {   // ''后面规格是空字符串 不管 也执行 i++(""为没有选择当前项)
                            i++;
                        }
                    }
                    console.log(this.specList.length, i)
                    // 此时 红色满足条件 return true  此时红色规格校验完毕 并会退出当选skuList循环
                    // 
                    return i == this.specList.length
                })
                return flag
            },
            // 点击事件
            changeSpec(key, value, able) {
                if (!able) return
                if (this.selectSpec[key] === value) {
                    this.selectSpec[key] = ''
                } else {
                    this.selectSpec[key] = value
                }
                // forEach循环改变原数组 
                this.specList.forEach(item => {
                    item.list.forEach(its => {
                        its.able = this.isAble(item.title, its.name);
                    });
                });
            }
        }
    })
</script>
<style>
    .spec-item {
        display: inline-block;
        margin-right: 10px;
    }

    .spec-item span {
        border: 1px solid #eee;
        cursor: pointer;
        padding: 5px 10px;
    }

    .spec-item .active {
        border: 1px solid red;
        background-color: red;
        color: #fff;
    }

    .spec-item .disabled {
        color: #c0c4cc;
        cursor: not-allowed;
        background-image: none;
        background-color: #fff;
        border-color: #ebeef5;
    }
</style>

</html>

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档