在一次业务组件封装中,碰到了一个这样的问题:
背景介绍
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 后,数据位就显示了真实的数据。这种方式在一开始就向用户展示了页面的基本框架,而后展示了数据部分,即使在请求出现问题的情况下,页面不至于什么都没有,所以这种呈现方式更加友好。