vue 使用动态ref动态显示echarts图坑总结
需求vue项目中动态给div赋予ref属性,以达到动态显示echarts图数量的目的。坑首先说下最开始的实现思路:在页面挂载的时候调用接口获取需要图形化展示的参数列表,以及展示图形的数量在接口数据接收完毕后调用画echarts图的方法步骤并不复杂,但是其中涉及到了vue生命周期的坑,分析如下:我们是动态给div赋予ref的:<template slot="body"><el-ro
·
需求
vue项目中动态给div赋予ref属性,以达到动态显示echarts图数量的目的。
坑
首先说下最开始的实现思路:
- 在页面挂载的时候调用接口获取需要图形化展示的参数列表,以及展示图形的数量
- 在接口数据接收完毕后调用画echarts图的方法
步骤并不复杂,但是其中涉及到了vue生命周期的坑,分析如下:
-
我们是动态给div赋予ref的:
<template slot="body"> <el-row class="echarts_box" :gutter="76"> <el-col v-for="item in count" :span="6" class="rel"> <div :ref="'chart'+item" class="echarts_item"></div> </el-col> </el-row> </template>
也就是说我们在上边的第一步接收完接口的数据后,会根据接收到的count数量更新DOM内容。
接下来如果立即执行画echarts图的方法,打印refs内容如下图所示,发现refs内容为空。
此时我们需要使用
this.$nextTick
方法,在该方法中回调画echarts图的方法,该方法的作用就相当于延迟调用方法,在DOM更新的时候不会立即执行回调函数,在DOM更新完毕后会执行回调函数。这样我们就可以在画echarts图的方法中获取ref内容。
-
当DOM更新完毕后在获取ref内容的时候不能使用
this.$refs[refName]
的方式获取,如下图此方式获取的是对应的ref后的数组,我们需要获取的是数组内的内容,所以要使用this.$refs[refName][0]
的方式获取。
完整代码实现
<template>
<CardBox title="智能测试库平台-四川移动" height="100%">
<template slot="body">
<el-row class="echarts_box" :gutter="76">
<el-col v-for="item in count" :span="6" class="rel">
<div :ref="'chart'+item" class="echarts_item"></div>
</el-col>
</el-row>
</template>
</CardBox>
</template>
<script>
import CardBox from '@/components/common/CardBox'
import api from "../../../service/api";
import {getCookie} from "../../../service/cookie";
export default {
components: {
CardBox
},
mounted() {
this.product_name = JSON.parse(this.$route.query.info).product_name;
this.area = JSON.parse(this.$route.query.info).area;
this.get_param_map()
},
data () {
return {
count: 0,
loading: false,
product_name: '',
area: '',
param_list: []
}
},
methods: {
// 画柱状图
drawLine (id, title, xdata, data) {
// 基于准备好的dom,初始化echarts实例
let myChart = this.$echarts.init(id)
// 绘制图表
myChart.setOption({
title: {
text: title,
textStyle: {
color: '#333',
fontSize: 14
}
},
grid: {
x: 0,
x2: 0,
y: '20%',
y2: 0,
containLabel: true
},
tooltip: {},
xAxis: {
data: xdata,
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
color: '#333',
textStyle: {
fontSize: 12
}
}
},
yAxis: {
axisLabel: {
color: '#333',
textStyle: {
fontSize: 12
}
},
splitLine: {
lineStyle: {
type: 'dashed',
color: '#ccc'
}
},
axisLine: {
show: false
},
axisTick: {
show: false
}
},
series: [
{
name: title,
type: 'bar',
barWidth: 16,
label: {
show: true,
position: 'outside',
formatter: '{c}',
fontSize: 12,
textStyle: {
color: '#333'
}
},
itemStyle: {
normal: {
barBorderRadius: 30,
color: params => {
// console.log('params', params)
if (params.data > 80 && params.seriesName.indexOf('状态') > -1){
return '#db0505'
}else {
return '#05c9db'
}
}
}
},
data: data
}
]
})
},
// 获取需要展示的参数
get_param_map() {
let data = {
area: this.area,
product_name: this.product_name,
user_id:getCookie('user_id')
}
api.operate_data_api.testLib_busniss_platform(data).then(response =>{
if (response.status === 0) {
console.log(response.info)
this.count = response.info.length
this.param_list = response.info
this.handle_draw_bar()
}else {
this.$message.error('系统异常,请联系管理员!')
}
})
},
// 将获取的参数画柱状图
handle_draw_bar() {
this.$nextTick(() => {
console.log('this.$refs', this.$refs)
this.param_list.forEach((item, index) => {
let chart = 'chart' + (index + 1)
let title = item.title + '(' + item.unit + ')'
let data = item.data
this.drawLine(
this.$refs[chart][0],
title,
['上月', '当月', '当月目标'],
data
)
})
})
}
}
}
</script>
<style lang="scss" scoped>
.echarts_item{
width: 100%;
}
.tips_icon{
right: 38px;
}
</style>
效果图展示
动态显示echarts图数量和内容。
更多推荐
已为社区贡献1条内容
所有评论(0)