关于在vue中动态渲染echart组件,渲染失败的问题

以下chart是在正常页面中(不在蒙层中): 

用echart组件时,渲染数据多数情况下会是动态添加,也就是前台获取数据,通过props传递给echart组件。对于vue生命周期函数执行顺序不熟悉的小伙伴儿,会碰到数据渲染失败的问题,原因如下:

下边是父组件father, 引入了子组件son, 来看下执行顺序:

<!-- father -->
<template>
  <div class="f">
    <son></son>
  </div>
</template>
<script>
import son from './home_son'
export default {
  name: 'home',
  components: { son },
  created() {
    console.log('father - created')
    this.$axios.get('http://localhost:3000')
        .then(res => {
          console.log('res', res)
        })
  },
  mounted() {
    console.log('father - mounted')
  }
}
</script>
<!-- son-->
<template>
    <div>
        <h1>son</h1>
    </div>
</template>
<script>
export default {
    name:'homeSon',
    created() {
        console.log('son- created')
    },
    mounted() {
        console.log('son - mounted')
    }
}
</script>

执行顺序:

父组件 created先执行,但是紧接着子组件 created - mounted执行了,最后是后台返回的数据,所以,你想把后台数据渲染到页面,结果令人失望!

解决方法:

在echart组件中,用watch去监听父级传来的属性,只有在新的值newval传过来才可以初始化chart:

<template>
  <div :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
export default {
  props: {
    xAxisdata: {
      type: Array,
      default() {
        return ['虹口店']
      }
    }
  },
  watch: {
    xAxisdata: {
      handler(newval, oldval) {
        if(newval) {
          this.initChart()
        }
        return newval
      },
      deep: true
    }
  },
  methods: {
    initChart() {
      this.chart = echarts.init(this.$el, 'macarons')
      // 绘制图表
      this.chart.setOption({ // ··· ···})
    }
  }
}
</script>

 

以下chart是在蒙层中: 

以element Dialog 对话框为例,chart图表组件作为子组件被引用,组件标签在蒙层中,显示蒙层时chart组件渲染不显示时有发生,具体原因因为 Dialog 对话框:

element文档:

Dialog 的内容是懒渲染的,即在第一次被打开之前,传入的默认 slot 不会被渲染到 DOM 上。因此,如果需要执行 DOM 操作,或通过 ref 获取相应组件,请在 open 事件回调中进行。

所以,chart图标嵌套在Dialog 中被打开之前是不会渲染的,但是我们通过ref来获取到chart组件的话,需要在open事件回调中来获取:

</template>
  </div>  
     <!-- 蒙层 -->
    <el-dialog :visible.sync="dialogVisible" title="详情" width="70%" @open="openFn">
      <!--如果加上v-if,图表会不断的销毁与创建-->
      <bar-chart v-if="dialogVisible" ref="bchart" :x-axisdata="chart.xAxisdata" seriesname="总销量" :seriesdata="chart.seriesdata" />
    </el-dialog>
  </div>
</template>
<script>
export default {
// ···
  methods: {
    openFn() {
      this.$nextTick(() => {
        this.$refs.bchart.initChart() // 获取到组件 执行初始化方法,此时在chart组件中就不需要执行初始化工作了,在这里执行即可!
      })
    }
  }
}
</script>

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值