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

背景

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

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

好好审视了下之前的代码,吐槽没用。又想了想之前挪用的界面,有些逻辑不太合适。我会跟产品商量下。我还觉得有些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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345