美文网首页
【轻知识】phper 记录一次前端代码的重构

【轻知识】phper 记录一次前端代码的重构

作者: 言十年 | 来源:发表于2019-02-21 21:59 被阅读47次

    背景

    有个需求跟之前一个需求类似。项目进度比较赶。正好发现我用技术栈跟之前类似。于是我拷贝过来了。这几天有新的改动点进来,于是我看了看之前的代码。觉得在此基础上改动,还是让我重写吧。

    唉,别想省事,早晚都是你的。

    好好审视了下之前的代码,吐槽没用。又想了想之前挪用的界面,有些逻辑不太合适。我会跟产品商量下。我还觉得有些php接口似乎设计的也不甚合理。当然每个人想法不同(说这句话真是万全)。

    另,写本篇文章,没有任何敌意。只是记录一次重构。

    先看看之前的

    我觉得变量的设计应该符合最终接口要求的格式。

    先看下接口要求的提交参数

    ......
    [
        {
            "sku_attr":[
                {
                    "attr_id":"3219",
                    "attr_name":"内存",
                    "attr_value_id":"370045",
                    "value_name":"64G"
                },
                {
                    "attr_id":"3220",
                    "attr_name":"颜色",
                    "attr_value_id":"370042",
                    "value_name":"绿色"
                },
                {
                    "attr_id":"3221",
                    "attr_name":"尺码",
                    "attr_value_id":"370039",
                    "value_name":"L"
                }
            ],
            "sku_stock":1,
            "sku_price":1,
            "sku_org_price":1,
            "vip_price":1,
            "weight":"333",
        },
        {
            "sku_attr":[
                {
                    "attr_id":"3219",
                    "attr_name":"内存",
                    "attr_value_id":"370045",
                    "value_name":"64G"
                },
                {
                    "attr_id":"3220",
                    "attr_name":"颜色",
                    "attr_value_id":"370042",
                    "value_name":"绿色"
                },
                {
                    "attr_id":"3221",
                    "attr_name":"尺码",
                    "attr_value_id":"370040",
                    "value_name":"XL"
                }
            ],
            "sku_stock":1,
            "sku_price":1,
            "sku_org_price":1,
            "vip_price":1,
            "weight":"333",
        }
    ]
    .......
    

    那么我们可以设置一个变量 goodsSkuList 或者skuList。存成这样的接口就OK了。

    再看下界面效果

    image.png

    看完图之后,完全可以用一个变量skuList渲染。

    然而之前的代码是如下

    image.png

    然后你在想。难道不能就用一个变量来搞定吗?而且specs[0]、specs[1],specs[2],为什么这么玩。而且这么写是限制了3个SKU。扩展性呢?

    1.一个变量能搞定的事情,用了多个变量。变量多,复杂度就升级了。复杂度在于。变量修改的地方越多,就写的越多,比如一个变量搞定,只改一个变量,如果你用两三个实现一个变量能搞定的事情,岂不是,要操作三个?从一到三。所以尽可能少的变量。

    图中的tableData是什么鬼?

      tableData() {
          var arr = this.specPrices
          for (var i = 0; i < arr.length; i++) {
            arr[i].spec0 = arr[i].specs[0]
            arr[i].spec1 = arr[i].specs[1]
            arr[i].spec2 = arr[i].specs[2]
          }
    
          return arr
        }
    

    那么specPrices是什么鬼?

    image.png

    好吧,当你追下去你还会发现,其他变量。因为添加规格,就会造成sku列表的联动。于是,又用了其他变量去实现。是不是很头疼。光看这些变量的变来变去就绕了。

    2.扩展性没有了。固定了3个SKU。

    于是会出现下面这种代码

    <el-table-column :label="specs[0].type" prop="spec0"/>
    <el-table-column v-if="specs[1]" :label="specs[1].type" prop="spec1"/>
    <el-table-column v-if="specs[2]" :label="specs[2].type" prop="spec2"/>
    
    computed: {
      // 表格数据
      tableData() {
        var arr = this.specPrices
        for (var i = 0; i < arr.length; i++) {
          arr[i].spec0 = arr[i].specs[0]
          arr[i].spec1 = arr[i].specs[1]
          arr[i].spec2 = arr[i].specs[2]
        }
    
        return arr
      }
    },
    

    以及sku组合的三层for循环以及对应的代码。

    // 规格组合数组
    specCombinations() {
      var arrWra = []
      var arr1, arr2, arr3, arr
      // 有2个规格type
    
      if (this.specs.length === 3) {
        arr1 = this.specs[0].children
        arr2 = this.specs[1].children
        arr3 = this.specs[2].children
        // 判断arr1是否为[], 如果是 为其添加个空字符串占位
        if (arr1.length === 0) {
          arr1 = ['']
        }
        if (arr2.length === 0) {
          arr2 = ['']
        }
        if (arr3.length === 0) {
          arr3 = ['']
        }
        arr = []
        for (let t = 0; t < arr1.length; t++) {
          for (let i = 0; i < arr2.length; i++) {
            for (let k = 0; k < arr3.length; k++) {
              arr = []
              arr.push(arr1[t])
              arr.push(arr2[i])
              arr.push(arr3[k])
              arrWra.push(arr)
            }
          }
        }
    
        return arrWra
        // 只有1个规格type
      } else if (this.specs.length === 2) {
        arr1 = this.specs[0].children
        arr2 = this.specs[1].children
        // 判断arr1是否为[], 如果是 为其添加个空字符串占位
        if (arr1.length === 0) {
          arr1 = ['']
        }
        if (arr2.length === 0) {
          arr2 = ['']
        }
        arr = []
        for (let t = 0; t < arr1.length; t++) {
          for (let i = 0; i < arr2.length; i++) {
            arr = []
            arr.push(arr1[t])
            arr.push(arr2[i])
            arrWra.push(arr)
          }
        }
    
        return arrWra
        // 只有1个规格type
      } else if (this.specs.length === 1) {
        arr = this.specs[0].children
        if (arr.length === 0) {
          arr = ['']
        }
        for (let i = 0; i < arr.length; i++) {
          const _arr = []
          _arr.push(arr[i])
          arrWra.push(_arr)
        }
        return arrWra
      } else if (this.specs.length === 0) {
        return ['']
      }
    }
    

    3.变量命名不够好。比之之前两点就不算啥了。

    重构吧

    看了这么一堆,你似乎有个结论,这种代码是堆叠式代码。有的堆叠不可怕,顶多冗余。有的堆叠就可怕了,简直是多个线交织。下面针对上面提到的前两点。

    1.减少变量的使用

    sku的列表。之前那么多变量实现的功能。我用了一个skuList。

    看下页面代码。没有spec[0]、spec[1]、spec[2] 啥的。 没有tableData。自然就没有那个方法。也没有specPrices变量等其他有关之前的变量。

    <el-table v-if="catAttrList.length !== 0 " :data="skuList" :row-class-name="tableRowClassName" style="max-width: 800px;">
        <el-table-column v-for="(item, index) in skuList[0].sku_attr" v-if="skuList[0]" :key="index" :label="item.attr_name">
        <template slot-scope="scope">
            <div class="name-wrapper" >{{ scope.row.sku_attr[index].value_name }}</div>
        </template>
        </el-table-column>
    

    2.扩展性。sku的表是根据属性组合的。我用了递归。这样即便将来扩展成多个SKU,代码不用动,而不是加for循环,加更多的spec[4]、5、6 啥的。

    递归代码如下。较之上面的堆叠(三层for,还有其他for,还有更多if )好了很多。

    assembleSkuList(data, skuAttr, arr, start) { // 递归组合sku: data 是从服务器获取的 属性list,skuArr是递归后组合的商品的skuList ,arr是不同规格一组,start 其实
        if (data.length === start) { // 递归出口,几个规格就 start
        return skuAttr
        }
        if (data[start].attr_value.length === 0) { // 因为规格 可以删除,这里为了健壮性要加默认值
        const tempObj = {}
        tempObj.attr_id = data[start].attr_id
        tempObj.attr_name = data[start].attr_name
        arr[start] = tempObj
        }
        // 下面是递归的主要逻辑
        for (let i = 0; i < data[start].attr_value.length; i++) {
        arr = deepClone(arr) // 深度拷贝,避免出错
        const tempObj = data[start].attr_value[i]
        tempObj.attr_id = data[start].attr_id
        tempObj.attr_name = data[start].attr_name
        arr[start] = tempObj // 几个规格就几个一组,用arr保存一小组
        if (arr.length == data.length) {
            skuAttr.push({
            sku_attr: arr,
            sku_org_price: this.batchElements.sku_org_price,
            sku_price: this.batchElements.sku_price,
            vip_price: this.batchElements.vip_price,
            sku_stock: this.batchElements.sku_stock,
            weight: this.batchElements.weight
            })
        }
        if (data[start + 1] !== undefined) { // 如果有下一个规格就递归下去,因为 属性是多维
            this.assembleSkuList(data, skuAttr, arr, start + 1)
        }
        }
        return skuAttr
    }
    

    对比图

    图片.png 图片.png 图片.png

    总结

    1.一个变量能搞定的,不要用多个变量来实现相同的效果。一是复杂度上升。修改地方过多。二是,容易产生代码堆叠,代码冗余的堆叠不可怕,可怕的是交织。

    2.扩展性。逻辑尽量的灵活。

    3.命名。

    4.当写的复杂的时候。尽量想想有没有其他方式(比如:api等等)或者逻辑。

    比如商品分类的选择。

    图片.png
      // 获取当前选中层级
      getCurrentIndex(value) {
        for (var i = 0; i < this.selectedArr.length; i++) {
          for (var j = 0; j < this.selectedArr[i].optionArr.length; j++) {
            if (this.selectedArr[i].optionArr[j].value === value) {
              return i
            }
          }
        }
      }
    

    当你遍历类目数组的时候,维度不就是层级么。也就是v-for的时候,index就是层级了,没必要自己算了。

    参考资料:

    《el-table-column 的嵌套v-for》https://blog.csdn.net/qq_28929589/article/details/79445354

    相关文章

      网友评论

          本文标题:【轻知识】phper 记录一次前端代码的重构

          本文链接:https://www.haomeiwen.com/subject/zozdyqtx.html