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

淩亂°似流年 2023-07-09 12:24 69阅读 0赞

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

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

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

  1. <!-- father -->
  2. <template>
  3. <div class="f">
  4. <son></son>
  5. </div>
  6. </template>
  7. <script>
  8. import son from './home_son'
  9. export default {
  10. name: 'home',
  11. components: { son },
  12. created() {
  13. console.log('father - created')
  14. this.$axios.get('http://localhost:3000')
  15. .then(res => {
  16. console.log('res', res)
  17. })
  18. },
  19. mounted() {
  20. console.log('father - mounted')
  21. }
  22. }
  23. </script>
  24. <!-- son-->
  25. <template>
  26. <div>
  27. <h1>son</h1>
  28. </div>
  29. </template>
  30. <script>
  31. export default {
  32. name:'homeSon',
  33. created() {
  34. console.log('son- created')
  35. },
  36. mounted() {
  37. console.log('son - mounted')
  38. }
  39. }
  40. </script>

执行顺序:

2020022821055434.png

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

解决方法:

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

  1. <template>
  2. <div :class="className" :style="{height:height,width:width}" />
  3. </template>
  4. <script>
  5. import echarts from 'echarts'
  6. export default {
  7. props: {
  8. xAxisdata: {
  9. type: Array,
  10. default() {
  11. return ['虹口店']
  12. }
  13. }
  14. },
  15. watch: {
  16. xAxisdata: {
  17. handler(newval, oldval) {
  18. if(newval) {
  19. this.initChart()
  20. }
  21. return newval
  22. },
  23. deep: true
  24. }
  25. },
  26. methods: {
  27. initChart() {
  28. this.chart = echarts.init(this.$el, 'macarons')
  29. // 绘制图表
  30. this.chart.setOption({ // ··· ···})
  31. }
  32. }
  33. }
  34. </script>

以下chart是在蒙层中:

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

element文档:

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

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

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

发表评论

表情:
评论列表 (有 0 条评论,69人围观)

还没有评论,来说两句吧...

相关阅读

    相关 vue动态渲染组件方法

    在项目中,我们会经常遇到动态加载不同组件(内容)的场景,也就是想通过一个页面,根据不同的参数或者条件,来加载不同的内容。那在vue里,给大家提供了一个很简单的方法,使用comp