vue如何使用笛卡尔积算法构建sku表格

 更新时间:2023年04月19日 11:01:17   作者:~柠凉id  
这篇文章主要介绍了vue如何使用笛卡尔积算法构建sku表格问题,具有很好的价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

1.根据笛卡尔积算法来构建二维数组

  • 变量1接收过滤的tag标签,生成二维数组组
  • 变量2获取维度名称

判断如果规格长度等于0,直接把规格属性赋空,然后使用笛卡尔积算法将数据进行交叉处理(使用reduce方法,参数1:空的二维数组,参数2:变量2的数据(维度名称标签),在声明一个空的数组array(用这个空数组去匹配交叉数组),再拿出reduce参数1空的二维数组,forEach循环遍历,在使用forEach遍历变量2数据(维度名称标签),进行交叉匹配,连接起来添加进array空数组,然后在这个二维数组中重新映射为对象数组,进行拼接数据构建sku表格

// 根据笛卡尔积来构建二维数组,在这个二维数组中重新映射为对象数组,首先过滤
function addTag() {
    // 根据笛卡尔积来构建二维数组,在这个二维数组中重新映射为对象数组
    const specList = formListAdd.value.specificationList//过滤tag标签,生成2维数组: 
    //数组对象中的数组取出,得到一个二维数组(蓝色tag标签)
    const valueList = specList.filter((item: any) => item.values.length).map((item: any) => item.values)
    // 添加name值(黄色tag标签)//获取维度名称,放到数组中 右边
    const titlesList = specList.filter((item: any) => item.title.length).map((item: any) => item.title)
    if (valueList.length == 0) {//如果规格没有这种属性,直接把规格属性赋空
        formListAdd.value.skuList = []
        return
    }
    // 使用笛卡尔积算法将数据进行交叉处理
    var skuArr = valueList.reduce((pre: string[][], next: any[]) => {//pre是一个空的二维数组 next(黄色tag标签)的内容也就是类型
        var array: string[][] = []//用这个空数组去匹配交叉数组
        pre.forEach(item1 => {//拿出空的一维数组
            next.forEach(item2 => {//遍历黄色tag标签内容,也就是交叉匹配
                array.push(item1.concat([item2]))//连接起来添加进array空数组
                return array
            })
        })
        return array
    }, [[]])
    // 进行拼接数据
    //构建sku表格--最终渲染出表格
    let list = skuArr.map((item: any, index: number) => {//根据skuArr来构建对象数组 
        let obj = { //对象将属性值并渲染到sku表格中
            price: formListAdd.value.skuList[index] ? formListAdd.value.skuList[index].price : 1,//现价
            originalPrice: formListAdd.value.skuList[index] ? formListAdd.value.skuList[index].originalPrice : 1,//原价
            vipPrice: formListAdd.value.skuList[index] ? formListAdd.value.skuList[index].vipPrice : 1,//vip价格
            stock: 0,//库存
            weight: 0,//重量
            img: "",//图片
            barCode: 0,//随机码
            title: '',//维度名称
            specification: ''
        } as any
        // 遍历循环添加到sku数组中
        item.forEach((val: number, index: number) => {
            // 相当于是添加一个对象
            obj['sku_' + titlesList[index]] = val;
            obj['title'] = item.join(',')
            obj['specification'] += formListAdd.value.specificationList[index].title + '_' + val + ','
        });
        return obj;
    })
    formListAdd.value.skuList.length = 0;//每次删除tag标签调用笛卡尔算法
    Object.assign(formListAdd.value.skuList, list)//最终合并渲染数据到sku表
}

2.合并表格

首先获取规格列表,判断然后对要跨行的列进行计算排除最后一个树形列,定义跨行的数量为1,循环遍历获取每一列要合并的

行数,将跨行的数量=后面数组长度的乘积,每次跨行的数量相同,所以当前行索引取余数%跨行数量==0就是要跨行的开始

  <!-- 商品详情表格渲染  span-method合并行或列的计算方法 -->
                <el-table :data="formListAdd.skuList" style="width: 100%" border :span-method="objectSpanMethod">
                    <el-table-column width="100" align="center"
                        v-for="item in (<any>formListAdd.specificationList).filter((item: any) => item.values.length > 0)"
                        :prop="'sku_' + item.title" :label="item.title" />
                    <!-- 循环数组,过滤数组的长度 -->
                    <el-table-column prop="SkuIds" label="SkuId" align="center" />
                    <el-table-column prop="vipPrice" label="¥VIP价(元)" width="150" align="center">
                        <template #default="scope">
                            <el-input-number v-model="scope.row.vipPrice" size="small" :min="1" />
                        </template>
                    </el-table-column>
                    <el-table-column prop="originalPrice" label="吊牌价" width="150" align="center">
                        <template #default="scope">
                            <el-input-number v-model="scope.row.originalPrice" size="small" :min="1" />
                        </template>
                    </el-table-column>
                    <el-table-column prop="price" label="价格" width="150" align="center">
                        <template #default="scope">
                            <el-input-number v-model="scope.row.price" size="small" :min="1" />
                        </template>
                    </el-table-column>
                    <el-table-column prop="stock" label="库存" width="150" align="center">
                        <template #default="scope">
                            <el-input-number v-model="scope.row.stock" size="small" :min="1" />
                        </template>
                    </el-table-column>
                    <el-table-column prop="weight" label="重量" width="150" align="center">
                        <template #default="scope">
                            <el-input-number v-model="scope.row.weight" size="small" :min="1" />
                        </template>
                    </el-table-column>
                    <el-table-column prop="img" label="SUK图片" width="150" align="center">
                        <template #default="scope">
                            <el-upload action="http://192.168.1.188:8080/upload/admin" :show-file-list="false"
                                :headers="headers" :on-success="handlePicSuccess" :before-upload="beforeAvatarUpload">
                                <img v-if="scope.row.img" :src="scope.row.img" class="avatars" />
                                <el-icon v-else @click="imgIndex = scope.$index">
                                    <Upload />
                                </el-icon>
                            </el-upload>
                        </template>
                    </el-table-column>
                    <el-table-column prop="barCode" label="条形码" width="250" align="center">
                        <template #default="scope">
                            <el-input v-model="scope.row.barCode" size="small" style="width:200px;">
                                <template #append>
                                    <el-button @click="scope.row.barCode = new Date().getTime()" size="small">随机</el-button>
                                </template>
                            </el-input>
                        </template>
                    </el-table-column>
                </el-table>
const objectSpanMethod = ({ row, column, rowIndex, columnIndex }: any) => {//行 列 行的下标 列的下标
    //拿到第一列要合并的行数(获取列表) 第一次渲染页面时弹框数组为空,会报空指针错误,需要使用?.运算符解决
    let specList = formListAdd.value.specificationList.filter((e: any) => e.values?.length > 0);
    if (columnIndex < specList.length - 1) {//对要跨行的列进行计算,排除最后一个属性列(最后一个属性列不存在跨行中)
        let rowSpanNum = 1;//跨行的数量
        for (let i = columnIndex + 1; i < specList.length; i++) {
            //依次拿到每一列要合并的行数
            rowSpanNum *= specList[i].values.length;//跨行的数量=后面数组长度的乘积
        }
        if (rowIndex % rowSpanNum === 0) {//每次跨行的数量相同,所以当前行索引取余数%跨行数量==0就是要跨行的开始
            return { rowspan: rowSpanNum, colspan: 1 } //当条件成立时,即合并行数
        } else {
            return { rowspan: 0, colspan: 0 }
        }
    }

注意(实现具体思路)

a.首先我们添加规格时会生成一个规格的表格,然后也会生成一个由tag标签形成的标签项,此项就是添加的规格

b.例如我添加两个规格,一个是尺寸,一个是颜色,那么就会生成两个tag标签项,当然tag标签项除了有规格之外还有一个动态编辑标签,意思就是跨域往规格里面添加不同的规格,如颜色可以添加红色,蓝色,尺寸可以添加XL,M等维度,那么在表格中怎么去生成尺寸和颜色这两个规格的数据呢?

c.首先我是定义一个数组,然后我们添加规格的时候把规格以对象的形式push进去数组中,当我们去编辑tag标签的时候,把tab的内容以数组的方式添加进去规格的对象中,做完这些操作之后就是生成SKU表格了

d.这里是采用计算属性的方式来实现的,首先使用map映射的方式获取到所有的规格组成一个二维数组例如上面添加的尺寸和颜色,那么就会获取到一个二维数组,二维数组中XL,M组成一个数组,蓝色,红色也组成一个数组,然后使用map获取到尺寸和颜色组成的数组

e.接下来是针对于二维数组使用笛卡尔积算法获得所有规格交叉之后组成的二维数组,意思就是获取一个二维数组,二维数组中尺寸和颜色全部交叉组成,组成新的一个二维数组,即生成XL和红色,XL和蓝色,M和红色,M和蓝色的数组,得到新的二维数组之后

f.我们还需要把这个二维数组使用双重循环的方式拿到每个数组的元素,然后以规格当做key,具体的规格值当做value的方式添加进去对象中

g.然后定义一个数组,把对象push进去数组中,最后把这个数组渲染到表格上就可以了,表格中的的prop属性是定义对象时的规格key值

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 解决el-date-picker 宽度溢出浏览器的问题

    解决el-date-picker 宽度溢出浏览器的问题

    这篇文章主要介绍了解决如何el-date-picker 宽度溢出浏览器问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2023-07-07
  • Vue3中emits与attrs的区别分析

    Vue3中emits与attrs的区别分析

    这篇文章主要给大家介绍了关于Vue3中emits与attrs区别的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用vue具有一定的参考学习价值,需要的朋友可以参考下
    2021-10-10
  • vue操作动画的记录animate.css实例代码

    vue操作动画的记录animate.css实例代码

    这篇文章主要介绍了vue操作动画的记录animate.css的相关知识,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-04-04
  • Vue infinite update loop的问题解决

    Vue infinite update loop的问题解决

    这篇文章主要介绍了Vue "...infinite update loop..."的问题解决,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-04-04
  • vue-quill-editor富文本编辑器上传视频功能详解

    vue-quill-editor富文本编辑器上传视频功能详解

    需求需要实现富文本的功能,同时富文本中还可以上传视频和图片,选来选去最后决定了用这个富文本编辑器,下面这篇文章主要给大家介绍了关于vue-quill-editor富文本编辑器上传视频功能的相关资料,需要的朋友可以参考下
    2023-05-05
  • vue中sync语法糖的用法详解

    vue中sync语法糖的用法详解

    Vue的.sync语法糖是一个用于双向数据绑定的指令,可以在子组件中用来监听父组件传递下来的props的变化,本文给大家介绍了在Vue中,.sync语法糖的使用方法,感兴趣的朋友跟着小编一起来学习吧
    2024-01-01
  • 使用Element进行前端开发的详细图文教程

    使用Element进行前端开发的详细图文教程

    众所周知Element是一套Vue.js后台组件库,它能够帮助你更轻松更快速地开发后台项目,下面这篇文章主要给大家介绍了关于使用Element进行前端开发的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-11-11
  • 案例实操vue事件修饰符带你快速了解与应用

    案例实操vue事件修饰符带你快速了解与应用

    这篇文章主要介绍了vue常见的事件修饰符,在平时无论是面试还是学习工作中都会经常遇到的,本文就带你快速上手,需要的朋友可以参考下
    2023-03-03
  • mpvue跳转页面及注意事项

    mpvue跳转页面及注意事项

    这篇文章主要介绍了mpvue跳转页面及注意事项的相关资料,需要的朋友可以参考下
    2018-08-08
  • 详解如何搭建mpvue框架搭配vant组件库的小程序项目

    详解如何搭建mpvue框架搭配vant组件库的小程序项目

    这篇文章主要介绍了详解如何搭建mpvue框架搭配vant组件库的小程序项目,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-05-05

最新评论