大屏可视化之组件层级设置

随笔,前端技巧 2019-08-15 420 次浏览 次点赞

前言

最近在进行大屏可视化产品的技术调研,主要是调研 网易有数 和 datav

在组件层级排列这块,两者的实现是不一样的

  • datav:组件均在同级(z-index都是一样的),后定义的属于高层。调整层级就需要移动dom节点位置
  • 有数:根据z-index去设置,调整层级就需要调整自身z-index以及其他受影响的图表 z-index

通过分析vue上两者的实现,比较两者的优缺点

datav

Dashbox 是层级控件

<template>
  <Dashbox
    v-for="dashbox in dashboxs"
    :key="dashbox.id"
    :dashbox="dashbox"
  ></Dashbox>
</template>
<script>
  data(){
    return {
      dashboxs:[{...},{...}]
    }
  }
</script>

当调整层级时,我们调用方法

move:(type,id)=>{
  let index = this.dashboxs.findIndex(dashbox=>dashbox.id===id)
  switch(type){
    //上移一层
    case 'up':{
      let dashbox = this.dashboxs.splice(index,1)
      this.dashboxs.splice(index+1,0,dashbox[0])
      break;
    }
    //下移一层
    case 'down':{
      let dashbox = this.dashboxs.splice(index,1)
      this.dashboxs.splice(index - 1 >= 0 ? index - 1 : 0, 0,dashbox[0])
      break;
    }
    //置顶
    case 'top':{
      let dashbox = this.dashboxs.splice(index,1)
      this.dashboxs.push(dashbox)
      break;
    }
    //置底
    case 'bottom':{
      let dashbox = this.dashboxs.splice(index,1)
      this.dashboxs.unshift(dashbox)
      break;
    }
  }
}

每个 dashbox 有key值,根据 diff 算法同级组件之间更改位置还是很高效的

优点:

  1. 层级调整方法实现简单
  2. dashbox 数据不用带z-index参数,节省空间

缺点:

  1. dom 节点移动会产生Layout,不过这里用的绝对定位,所以影响很小,测试Layout耗时在1ms左右(Performance中无红色提示)

有数

Dashbox 是层级控件 组件的 zIndex 值从1开始,不断递增且不中断

<template>
  <Dashbox
    v-for="dashbox in dashboxs"
    :key="dashbox.id"
    :dashbox="dashbox"
    style="z-index:`${dashbox.zIndex}`"
  ></Dashbox>
</template>
<script>
  data(){
    return {
      dashboxs:[{...},{...}]
    }
  }
</script>

当调整层级时,我们调用方法

move:(type,id)=>{
  let dashbox = this.dashboxs.find(dashbox=>dashbox.id===id)
  let maxz = this.dashboxs.length
  let curz = dashbox.zIndex
  switch(type){
    //上移一层
    case 'up':{
      if(curz<maxz){
        this.dashboxs.find(d=>d.zIndex===curz+1).zIndex = curz
        dashbox.zIndex = curz +1
      }
      break;
    }
    //下移一层
    case 'down':{
      if(curz>1){
        this.dashboxs.find(d=>d.zIndex===curz-1).zIndex = curz
        dashbox.zIndex = curz - 1
      }
      break;
    }
    //置顶
    case 'top':{
      if(curz!==maxz){
        this.dashboxs.forEach(v=>v.zIndex>curz&&v.zIndex=v.zIndex-1)
        dashbox.zIndex = maxz
      }
      break;
    }
    //置底
    case 'bottom':{
      if(curz!==0){
        this.dashboxs.forEach(v=>v.zIndex<curz&&v.zIndex=v.zIndex+1)
        dashbox.zIndex = 0
      }
    }
  }
}

优点:

  1. 利用z-index仅重绘,不产生回流

缺点:

  1. 层级调整方法相对复杂
  2. 组件过多时z-index不可控,可能影响其他同层级非dashbox组件的层级显示(比如同层级有一个划框,其z-index就绝对要在最高层)
  3. 数据增加z-index字段,略微增加了空间

参考

  1. 不同渲染引擎在不同样式变动下的Layout/Paint/Composite(渲染层合并)情况

本文由 GaHingZ 创作,采用 署名-非商业性使用-相同方式共享 3.0,可自由转载、引用,但需署名作者且注明文章出处。

如果对您有用,您的支持将鼓励我继续创作!