最近在写一个根据输入的规格,属性值动态生成sku表格,实现的效果大致如图,这是在vue项目里,结合element-UI表格写的,写好了就整理了一下,把代码贴上来,方便以后使用,不过代码里还是有一些重复的东西没整理,因为急着完成功能,也没太注意代码整洁,以后有时间再整理一下

读取规格列表的功能是,如果你这次存了一个表格给后台,查看详情时,后台返回给你,你需要把它渲染到页面上用的,我这里写的比较复杂,因为用v-model绑定input,取值的时候要用对象取法,所以存进去的时候也是用的对象存放

如果你只是要实现动态生成规格表的话,有这段代码就行了,可以生成3*2*2的组合

/**
* 递归生成规格列表
* @param {*} skuarr 存储每一种排列组合的数组
* @param {*} i 要用list数据的第几项作为基数,i为几,最后的结果就是以list[i]的数据开头,一般以第一项的值放在组合的第一位,如果要以其他属性开头,方法需要变动一下,有兴趣可以自己研究
* @param {*} list 要生成排列的原始数据
*/
  1. var arr = []
function func(skuarr=[], i, list){  
  1. for (let j=0; j<list[i].length; j++) {
  2. if (i<list.length-1) {    // 演示一下第一次执行函数的结果
  3. skuarr[i] = list[i][j] // skuarr[0] = ['黑色'] i=0, j=0
  4. func(skuarr, i+1, list) // 执行递归 skuarr[1] = ['s'] i=1, j=0
  5. } else {
          // 拓展运算符合并数组
  6. arr.push([...skuarr,list[i][j]]) // arr[0] = ['黑色','s','好'] i=2不符合if条件,执行else j=0
  7. }
  8. }
  9. return arr
  10. }
    const list = [
      ['黑色','红色','白色'],
      ['S','M'],
      ['好','差']
    ]
    console.log(func([],0,list))
    // 打印的结果
  1. 0:(3) ["黑色", "S", "好"]
  2. 1:(3) ["黑色", "S", "差"]
  3. 2:(3) ["黑色", "M", "好"]
  4. 3:(3) ["黑色", "M", "差"]
  5. 4:(3) ["红色", "S", "好"]
  6. 5:(3) ["红色", "S", "差"]
  7. 6:(3) ["红色", "M", "好"]
  8. 7:(3) ["红色", "M", "差"]
  9. 8:(3) ["白色", "S", "好"]
  10. 9:(3) ["白色", "S", "差"]
  11. 10:(3) ["白色", "M", "好"]
  12. 11:(3) ["白色", "M", "差"]
  1.  

最近用数组的reduce方法时,想到了另一种实现笛卡尔积的方法,补充进来

  1. handleData () {
  2. // 测试的数据
  3. let arrs = [['红','黄', '蓝'], ['大', '中', '小']] // 如果你的数据类型是其他形式,需要转换成二维数组的格式再进行
  4.  
  5. /**
  6. * 思路: 以第一项为基础,循环合并之后的每一项再循环的值
  7. * @param {*} acc 累计的值
  8. * @param {*} cur 当前遍历项
  9. * @param {*} index 当前遍历索引
  10. */
  11. let result = arrs.reduce((acc, cur, index) => {
  12. // 从第二项开始合并值
  13. if (index > 0) {
  14. let saveArr = []
  15. acc.forEach(item => {
  16. cur.forEach(subItem => {
  17. saveArr.push(`${item},${subItem}`)
  18. })
  19. })
  20. acc = saveArr
  21. }
  22. return acc
  23. }, arrs[0]) // 把数组的第一项传入作为初始值
  24. console.log(result) //["红,大", "红,中", "红,小", "黄,大", "黄,中", "黄,小", "蓝,大", "蓝,中", "蓝,小"]
  25. }

整个页面的代码,写得比较乱,见谅

  1. <template>
  2. <div>
  3. <div class="stand">
  4. <ul>
  5. <li class="attr" v-for="(item,index) in standData" :key="index">
  6. <span @click="remove(index)">删除:</span>
  7. <el-input class="title" v-model="item.title" placeholder="请输入属性">:</el-input>
  8. <div class="putt" v-if="item.attrs.length" v-for="(subitem,i) in item.attrs" :key="i">
  9. <el-input v-model="subitem.attr" placeholder="请输入值"></el-input>
  10. <div class="close" @click="closeAtrr(index,i)">×</div>
  11. </div>
  12. <div class="append" @click="addAtrr(index)">+</div>
  13. </li>
  14. </ul>
  15. <div class="add">
  16. <el-button type="primary" @click="addStand">添加规格</el-button>
  17. <el-button type="primary" @click="getTable">生成规格列表</el-button>
  18. <el-button type="primary" @click="read">读取规格列表</el-button>
  19.  
  20. </div>
  21.  
  22. </div>
  23. <div class="table">
  24. <el-table v-if="isTable"
  25. :data="tableData"
  26. border
  27. style="width: 100%">
  28. <el-table-column
  29. prop="date"
  30. label="属性"
  31. width="180">
  32. </el-table-column>
  33. <el-table-column
  34. prop="name"
  35. label="价格1"
  36. width="180">
  37. </el-table-column>
  38. <el-table-column
  39. prop="address"
  40. label="价格2">
  41. </el-table-column>
  42. </el-table>
  43. </div>
  44. </div>
  45. </template>
  46. <style>
  47. .table,.stand {
  48. padding: 40px;
  49. }
  50. .table {
  51. height: 500px;
  52. }
  53. .add {
  54. margin-top: 20px;
  55. }
  56. .attr {
  57. margin-bottom: 10px;
  58. }
  59. .el-input {
  60. width: auto;
  61.  
  62. }
  63. .putt {
  64. display: inline-block;
  65. position: relative;
  66. margin-right: 10px;
  67. }
  68. .append {
  69. width: 40px;
  70. height: 40px;
  71. background-color: aqua;
  72. line-height: 40px;
  73. text-align: center;
  74. display: inline-block;
  75. font-size: 28px;
  76. cursor: pointer;
  77. vertical-align: middle;
  78. }
  79. .title {
  80. background-color: bisque;
  81. margin-right: 10px;
  82. }
  83. .close {
  84. position: absolute;
  85. width: 15px;
  86. height: 15px;
  87. background-color: burlywood;
  88. border-radius: 50%;
  89. line-height: 15px;
  90. text-align: center;
  91. right: -5px;
  92. top: -5px;
  93. }
  94. </style>
  95.  
  96. <script>
  97. export default {
  98. data() {
  99. return {
  100. tableData: [],
  101. input: '',
  102. isTable: false,
  103. standData: [],
  104. list: [],
  105. group: []
  106. }
  107. },
  108. created() {
  109.  
  110. },
  111. methods: {
  112. // 添加规格行
  113. addStand (i) {
  114. // 限制规格种类不超过4种
  115. if (this.standData.length>3) {
  116. this.$message('不能超过四行')
  117. } else {
  118. this.standData.push({title: '', attrs: []})
  119. }
  120. },
  121. // 添加规格表格
  122. getTable () {
  123. this.isTable = true
  124. this.tableData = []
  125. this.group = []
  126. this.list = []
  127. // console.log(this.standData);
  128. const num = this.standData.length
  129. this.standData.forEach(item => {
  130. this.list.push(item.attrs)
  131. });
  132. // console.log(this.list);
  133. var arr = []
  134. var that = this
  135. function func(skuarr=[], i){
  136. for (let j=0; j<that.list[i].length; j++) {
  137. if (i<that.list.length-1) {
  138. skuarr[i] = that.list[i][j].attr
  139. func(skuarr, i+1)
  140. } else {
  141. arr.push([...skuarr,that.list[i][j].attr])
  142. }
  143. }
  144. return arr
  145. }
  146. let newList = func([], 0)
  147. let b
  148. newList.forEach(item => {
  149. b = ''
  150. for (let i = 0; i < num; i++) {
  151. let a = this.standData[i].title
  152. a = a + ':' + item[i]
  153. b = b + a + ';'
  154. }
  155. this.group.push(b)
  156. })
  157. console.log(this.group)
  158. let table = []
  159. for (let j = 0; j < this.group.length; j++) {
  160. table.push({
  161. date: this.group[j],
  162. name: '',
  163. address: ''
  164. })
  165. }
  166. this.tableData = table
  167. },
  168.  
  169. // 删除规格行
  170. remove (i) {
  171. this.standData.splice(i,1)
  172. },
  173. // 添加属性值
  174. addAtrr (i) {
  175. // 限制属性值不超过5个
  176. if (this.standData[i].attrs.length>4) {
  177. this.$message('不能超过5个')
  178. } else {
            // 存的时候是存的对象
  179. this.standData[i].attrs.push({attr: ''})
  180. }
  181. },
  182. // 删除属性值
  183. closeAtrr (a, b) {
  184. // console.log(a, b);
  185. this.standData[a].attrs.splice(b,1)
  186. },
  187. // 读取规格属性数组
  188. read () {
          // 如果后台返回的数据是这样的
  189. const arr = [
  190. '颜色:红色;尺码:M;品质:好;',
  191. '颜色:红色;尺码:S;品质:好;',
  192. '颜色:白色;尺码:M;品质:好;',
  193. '颜色:白色;尺码:S;品质:好;'
  194. ]
  195. const a = arr[0].split(';')
  196. const num =a.length-1
  197. let ss = []
  198. for (let tt = 0; tt < num; tt++){
  199. ss.push([])
  200. }
  201.  
  202. arr.forEach(item => {
  203. for (let tt = 0; tt < num; tt++){
  204. ss[tt].push(item.split(';')[tt].split(':')[1])
  205. }
  206. })
  207. ss = ss.map(item => {
  208. return Array.from(new Set(item))
  209. })
  210. for (let s = 0; s < ss.length; s++) {
  211. for (let t = 0; t < ss[s].length; t++) {
  212. ss[s][t] = {attr:ss[s][t]}
  213. }
  214. }
  215. for (let i = 0; i < num; i++) {
  216. this.standData.push({'title': a[i].split(':')[0],attrs: ss[i]})
  217. }
  218. console.log(this.standData);
  219.  
  220. }
  221.  
  222. }
  223. }
  224. </script>

结合element-ui表格自动生成sku规格列表的更多相关文章

  1. element ui 表格提交时获取所有选中的checkbox的数据

    <el-table ref="multipleTable" :data="appList" @selection-change="changeF ...

  2. vue + element ui 表格自定义表头,提供线上demo

    前言:工作中用到 vue+element ui 的前端框架,需要使用自定义表头,需要使用 re.转载请注明出处:https://www.cnblogs.com/yuxiaole/p/9710826.h ...

  3. 封装一个优雅的element ui表格组件

    现在做后台系统用vue + elementUI 的越来越多,那element ui的 el-table 组件肯定也离不开.虽然element ui的table组件很好.但是表格和分页是分离的.每次写表 ...

  4. Element UI表格组件技巧:如何简洁实现跨页勾选、跨页统计功能

    业务场景 在使用Element UI的Table组件时,常常面对这样的业务需求: 表格数据的每一项都要提供勾选框,当切换分页时,能够记忆所有页面勾选的数据,以实现批量提交不同页面勾选数据的功能.并且, ...

  5. vue2.0+Element UI 表格前端分页和后端分页

    之前写过一篇博客,当时对element ui框架还不太了解,分页组件用 html + css 自己写的,比较麻烦,而且只提到了后端分页 (见 https://www.cnblogs.com/zdd20 ...

  6. element UI表格行高、padding等设置报错问题

    element UI里面表格的行高需要自己调整高度和设置padding,直接写style是不行的,里面有 : 1.row-style (行的 style) 2.header-row-styl   (表 ...

  7. element ui表格相同内容自动合并

    一开始觉得合并单元格很困难,什么鬼,后来仔细查看api,发现是可以实现的,特此记录下,直接看代码, 项目需求是第一列和第二列还有第16列需要相同内容进行合并,所以判断条件是不同的: 实现后效果如下: ...

  8. Unity UI代码自动生成

    最近在做新项目跟同事讨论UI制作方案, 这里就说下根据节点来生成UI代码,  这个工具可以根据预设生成一个分布类.目前组件还不是很完善, 自己使用需要修改部分代码 组件功能如下: 1. 自动设置引用 ...

  9. element UI实现动态生成多级表头

    一.效果图 二.封装两个组件,分别为DynamicTable.vue和TableColumn.vue,TableColumn.vue主要是使用递归来对表头进行循环生成 DynamicTable.vue ...

随机推荐

  1. 安装了多个php版本,如何编译扩展

    cd /data/php-5.5.35/ext/mysqli  找到安装包目录下面的ext目录 ./configure --with-php-config=/usr/local/php5/bin/ph ...

  2. chrome headless

    最近才知道有这么个东西,说白了就是chrome浏览器的命令行模式,一说到命令行自然就和自动化 高效率有关系,感觉对于自动化测试和爬虫很有用啊

  3. ZROI2018提高day1t2

    传送门 分析 考场上看错了第一个条件,于是觉得是个简单贪心,随便取了每一个点的最大收益然后算了一下,就得了40pts...看来读对题很重要呀qwq.实际的正解是这样的:我们将每一个i与f[i]连一条边 ...

  4. loj10088 出纳员问题

    传送门 分析 我们设pre[i]为到第i个时段的雇佣员工的总数量,sum[i]表示时段i的可雇佣员工的总数量,r[i]表示时段i所需工人的数量.由此我们不难求出: 0<=pre[i]-pre[i ...

  5. 196D The Next Good String

    传送门 题目大意 给定n和一个字符串,求一个新字符串使得这个字符串不存在长度大于等于n的回文子串且在字典序大于原串的情况下最小. 分析 我们知道如果有一个长度为n+2的回文串,那它一定由一个长度为n的 ...

  6. WOJ 10 精英选拔

    神仙dp,膜Claris 题意:给一个长度为$n$的数列,求出不超过k次交换后的最大连续子区间和. 发现交换后的最优答案一定是这样的(0和2的长度可以为0)             0        ...

  7. 笔录---果壳中的C#第一章

    ---恢复内容开始--- 笔录---果壳中的C#第二章 2.1 第一个C#程序 1.C#语句按顺序执行,以“:”结尾. Console.WriteLine();     console 为类,Writ ...

  8. 关于css js文件缓存问题

    什么情况下,要禁止静态文件缓存:1.经常可能要改动的 js, css.比如一个js文件引用如下<script src="test.js"></script> ...

  9. C++11新标准:constexpr关键字

    一.constexpr意义 将变量声明为constexpr类型以便由编译器来验证变量是否是一个常量表达式(不会改变,在编译过程中就能得到计算结果的表达式).是一种比const更强的约束,这样可以得到更 ...

  10. c# get set 理解