这是一道典型的布局题目,2行N列很容易让人想到的就是电商平台的百宝箱,或者哪个推广平台的类目模块。因为当前手机屏幕可能只局限于展示4列或者5列,其余的要展示到屏幕外面去,通过用户滑动再出现。如果还不明白,我截个图,类似于京东手机版的这个百宝箱。

一、实现背景

        

adapter android girdView 多行多列 web多行多列布局_性能优化

        这些内容呢肯定是服务端获取的,给了一个list数组,而且用户是需要从左往右滑动的,所以展示的顺序肯定是一列一列的。比如这个list数组给了单数的元素,那么最后那一列要只展示一个

二、实现思路

        1、最基本的典型思路

        先想到的就是通过js进行二维数组的布局,给到的list数据应该大致如此:

data () {
    return {
      list: [
        {title: '一'},
        {title: '二'},
        {title: '三'},
        {title: '四'},
        {title: '五'},
        {title: '六'},
        {title: '七'},
        {title: '八'},
        {title: '九'},
        {title: '十'},
      ],
      boxList: [], // 预定义2列数据的数据容器
    }
  },

        然后再通过前端将这个list数组转为一个二维数组

mounted() {
    // 得到一个二维数组
    let boxList = [];
    for (let i=0;i<this.list.length;i++) {
      let indexCeil = Math.floor(i/2);
      if (!boxList[indexCeil]) {
        boxList[indexCeil] = [this.list[i]];
      } else {
        boxList[indexCeil].push(this.list[i]);
      }
    }
    this.boxList = boxList;
    console.log(boxList);
  },

        打印boxList得到的数据是这样的,一个二维数组

adapter android girdView 多行多列 web多行多列布局_javascript_02

         然后就是通过二位数组,双层循环的方式进行模板绑定

<div class="box">
    <div v-for="(oItem, oIndex) in boxList" :key="oIndex" class="o-box">
      <div v-for="(tItem, tIndex) in oItem" :key="tIndex" class="t-box">
        {{ tItem.title }}
      <div>
    </div>
</div>
<style scoped>
.box {
  display: flex;
  width: 100%;
}
.o-box {
  width: 20%;
}
.t-box {
  width: 100%;
  height: 50px;
  border: 1px solid red;
  text-align: center;
  line-height: 50px;
}
</style>

        最终排版如图:

        

adapter android girdView 多行多列 web多行多列布局_面试题_03

        这是一种典型的前端思路,既然是2行N列,很明显就是一个二维数组嘛,将数据处理一下,就开始排版,基本没有问题。

2、采用CSS3的方式

        去除上一步的数据处理,不需要做二维数组的转换。但CSS部分需要做修改,而且模板部分也不用做二次遍历v-for的处理,依然可以实现效果

<div v-for="(oItem, oIndex) in list" :key="oIndex" class="o-box">
      {{ oItem.title }}
</div>
<style scoped>
.box {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
  width: 100%;
  height: 108px;
}
.o-box {
  width: 20%;
  height: 50px;
  text-align: center;
  line-height: 50px;
  border: 1px solid blue;
}
</style>

 3、你觉得哪种方式更好?

        我们知道vue最终被打包,打出对应的主js和css文件,而我们看见的页面渲染内容,是浏览器解析js css 然后再组装dom模板树,再组装css,最终渲染出来的。所以猛地一看这2种方式都无伤大雅,因为最终哪怕是第二种CSS3的实现方式,也脱离不开这种浏览器的规则,因为vue模板,数据最终都会打到js文件里。

        但如果你想更细化的去纠结一下,会发现第一种方式处理数据做了遍历,而模板处也对应做了双层遍历。代码片段对于循环这种实现是非常耗时的,更何况有一个双层遍历。所以第二种CSS3的实现会更优一些些。因为这里数据量小,是看不出对比数据的。可以考量一下如果更多的数据是否会有影响。

4、感悟

        我们做性能优化,几乎每过一段时间运营商都会提网速,几乎每过一段时间手机厂商都会提硬件质量,由于运营商的手机厂商的不断努力,所以我们性能优化这块,很多时候可能已经做了很大的改进,指标上收效可能却是微乎其微的。但我想说一句:性能优化,勿以善小而不为吧