一次 Vue 业务组件封装的思考

1,816 阅读2分钟

在一次业务组件封装中,碰到了一个这样的问题:

背景介绍

key-metrics 块展示了一些指标的整体数据,其中红框中的数据由后台返回,蓝框的显示和选择的时间有关,每个指标都可以点击选中。项目中这块出现多次,所以打算封装成 key-metric & key-metric-group 组件。

后台返回的数据格式如下:

data: {
  sales: {
    chain_ratio: 
    value: 
  },
  orders: {
    chain_ratio: 
    value: 
  },
  sales_per_order: {
    chain_ratio: 
    value: 
  },
  conversion_rate: {
    chain_ratio: 
    value: 
  },
  visitors: {
    chain_ratio: 
    value: 
  },
  page_views: {
    chain_ratio: 
    value: 
  }
}

封装组件

前端针对每个页面的 key-metrics 块会定义一个指标数组常量 metrics ,id 对应后台返回的属性,title & tip 代表指标名称和解释,selected 代表指标是否选中。

const metrics = [
  {
    id: 'sales',
    title: 'psd_sales',
    tip: 'psd_tooltip_sales',
    selected: true,
  },
  {
    id: 'orders',
    title: 'psd_orders',
    tip: 'psd_tooltip_orders',
    selected: true,
  },
  {
    id: 'sales_per_order',
    title: 'psd_sales_per_order',
    tip: 'psd_tooltip_sales_per_order',
    selected: false,
  },
  {
    id: 'orders',
    title: 'psd_conversion_rate',
    tip: 'psd_tooltip_conversion_rate',
    selected: false,
  },
  {
    id: 'orders',
    title: 'psd_visitors',
    tip: 'psd_tooltip_visitors',
    selected: false,
  },
  {
    id: 'orders',
    title: 'psd_page_views',
    tip: 'psd_tooltip_page_views',
    selected: false,
  },
]

当我开始写 key-metric-group 组件时,不确定 metrics 和后台返回的 data 是作为两个 props 还是一个,我们先来看看作为一个的效果:

props: {
  metricData: { // 指标常量 & 后台返回数据组装
    type: Array,
    default: () => []
  }
  shortcut: { // 选择的时间
    type: Number,
    default: 0
  }
}

一开始什么都没有,大概半秒之后 key-metrics 块的框架和数据才一起出现,这是为什么呢?

我们知道父子组件钩子的执行顺序如下:

父beforeCreate -> 父created[request1] -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted -> request1_callback

在父created 中发送请求后,请求的 callback 在第一次组件挂载完毕之后才去执行,所以第一次挂载时,传递给 key-metric-group 的 metricData 为空,所以页面上什么都没有。等到后台返回 data,在 callback 中赋值给 metricData 后,key-metrics 块的框架和数据才一并显示出来。

当 metrics & data 分别作为 props (如下)传入 key-metric-group 的时候,效果如下:

props: {
  metrics: { // 前端定义的指标数组常量
    type: Array,
    default: () => []
  },
  data: { // 后台返回的数据
    type: Object,
    default: () => ({})
  },
  shortcut: { // 选择的时间
    type: Number,
    default: 0
  }
}

可以看出,key-metrics 块的框架首次就渲染出来了,只是在数据位显示的是 -,不到半秒 - 就被替换成了真实的数据。这是因为 metrics 在第一次渲染时已经有值,所以首次能渲染出 key-metrics 块的框架,等到后台返回 data,在 callback 中赋值给 props.data 后,数据位就显示了真实的数据。这种方式在一开始就向用户展示了页面的基本框架,而后展示了数据部分,即使在请求出现问题的情况下,页面不至于什么都没有,所以这种呈现方式更加友好。