vue 中 v-for 动态生成盒子换行排列布局效果

3,095 阅读3分钟

「这是我参与11月更文挑战的第6天,活动详情查看:2021最后一次更文挑战」。

前言

最近写的页面需要用 v-for 来实现一个盒子换行排列布局的效果大概如下:

捕获.PNG

数据是存储在一个数组当中,页面的样式都是动态生成的,数组定义了每一个 item 的大小,颜色,内容

问题所在

1.布局方面

最开始写静态页面的时候使用的是 flex 布局,22 盒子后面的小盒子就用一个标签包起来单独写样式。但是这样子,到了用 v-for 生成的时候明显就不可以了,因为循环里面每一个元素都是一样的,想不到什么办法去给两个元素单独包上一层标签。这样就导致22后面的那个1*1高度会被撑开,而空出来一行。

后面想到了抛弃 flex 布局的自适应宽度和高度,改用了浮动来布局,为父元素中的每一个子元素开启浮动,这样子,他就是自动变成堆起来的。可是这样子就要去为每一个盒子添加外边距来让他们分离开来,而且这样外边距就写死了,后面没办法跟着父元素的大小来改变,算是有利有弊。

2.动态生成方面

  1. 不难发现,页面是由一个整体,然后整体之中有两个大的盒子,这里我用的是两个 ul 标签,ul 内部有若干个 li 标签。

image.png

  1. 首先先来个简单的,单纯去生成一个 ul ,那就需要在li便签上绑定v-for动态生成
 <li
    v-for="(item, i) in items"
  >
  </li>

这个很简单就能实现一个ul的生成,但是现在问题来了,要怎么去生成第二个ul,按理来说,在数组当中的数据第一个ul放不下的时候,就要放到第二个ul中,第二个放不下,第三个...以此类推。

image.png

  1. 在这个问题上面,我去定义了一个方法去判断,我这个ul现在满了没有,按理来说,要去设定一个情况来判断不同li组合会在ul里面占据多少的空间,这里我暂时偷懒了,先定义li都是一个11 加上一个 12 或者反过来,这样子的话,只要8个li过后的li就都放到下一个ul里面去,以此类推。
itemSegmentation(item) {
      let splitItems = [];
      item.forEach((item, index) => {
        let idx = Math.floor(index / 8);
        if (!splitItems[idx]) splitItems[idx] = [];
        splitItems[idx].push(item);
      });
      return splitItems;
    },

将拿到的所以item传入,然后就能拿到一个分割后的数组。 就是说原本一个 [a,b,c,d] 的数组会按照你的算法分割为多个,我上面设定是8个以数组,假如说2个,那么就会变成 [[a,b],[c,d]],变成两个,按照这种方法,将 li 8个8个分割开来,当然这还不满足这个页面的要求,8个这种写死的方法很明显是不够的,但是这个暂时还没有解决,后续解决了会持续更新~

  1. 然后就是,只需要拿到分割过后的数组 splitItems 将它放在 ul 上进行一个 v-for 的循环,这样每个 li 拿到的就是固定个数的数组了

image.png

总结

上面的方法只是简单的实现了开头说的那种效果,但是暂时还没办法实现自适应每个内部的项目,毕竟要是大小不同,那么填满所需要的个数就也不同,这个之后就需要更新一个这个方法。