如何解决Echarts与Element-ui中的Dialog 对话框结合却渲染不上去?

目录

背景:

解决方案:

案例:

核心代码:

解释代码:

 完整代码:

背景:

在我们前端开发的时候,想实现一个效果,当用户点击Dialog 对话框就可以弹出echarts图表。可当我们正常写代码时候会发现,Dialog 对话框并没有我们想要的效果,往往是空白一片,这是为什么呢?

在Element-ui官网中有这样一句话描述Dialog 对话框:

 这句话就告诉我们这样一个道理:在vue底层,通过document.ElementById("id")获取DOM节点时,DOM节点还未生成,所以获取不到DOM节点,图表更不会显示 。

解决方案:

既然我们知道了问题,那如何去解决这样的问题呢?

使用element-ui中dialog提供的open(Dialog 打开的回调)方法,结合定时器vue的this.$nextTick(),原理就是等dom渲染完之后,再使用echarts。

其中:this.$nextTick()的作用是将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。

我们直接上代码,这样观众老爷们,会理解的更加深透。

案例:

核心代码:

<script>


export default {
  data() {
    return {
      dialogVisible: false,
    }
  },
  methods: {
    handleClose(done) {
        this.$confirm('确认关闭?')
          .then(_ => {
            done();
          })
          .catch(_ => {});
    },
      // 弹框的触发事件
    showDialog() {
      var yearData = [
    {
      year: "2020", // 年份
      data: [
        // 两个数组是因为有两条线
        [240, 170, 101, 134, 190, 230, 210, 230, 120, 230, 210, 120],
        [130, 164, 191, 324, 290, 330, 310, 213, 180, 200, 180, 120],
        [210, 300, 70, 100, 110, 200, 230, 180, 160, 119, 120, 180],
        [200, 74, 191, 214, 290, 130, 310, 213, 120, 110, 180, 170],
        [57, 64, 91, 124, 90, 130, 110, 113, 110, 130, 100, 120],
        [340, 270, 331, 434, 290, 330, 210, 230, 120, 230, 210, 120],
        [330, 270, 121, 134, 157, 230, 210, 230, 220, 230, 118, 120],
        [112, 231, 213, 215, 261, 278, 127, 129, 139, 199, 200, 210],
        [134,131,113,115,161,178,227,229,239,199,210,200],
      ]
    }
      ];

	this.dialogVisible = true;//展示弹窗
      let diameter = this.$refs.cc//放置echarts图示的div的ref值
      const myChart = this.$echarts.init(diameter);
    let diameterOption = {
    color: ["#00f2f1", "#ed3f35","#ddd","#00ff00","#ffa500","#800080","#0000ff"],
    tooltip: {
      trigger: "axis"
    },
    legend: {
      // 如果series 对象有name 值,则 legend可以不用写data
      // 修改图例组件 文字颜色
      textStyle: {
        color: "#4c9bfd"
      },
      // 这个10% 必须加引号
      right: "10%"
    },
    grid: {
      top: "20%",
      left: "3%",
      right: "4%",
      bottom: "3%",
      show: true, // 显示边框
      borderColor: "#012f4a", // 边框颜色
      containLabel: true // 包含刻度文字在内
    },

    xAxis: {
      type: "category",
      boundaryGap: false,
      data: [
        "1月",
        "2月",
        "3月",
        "4月",
        "5月",
        "6月",
        "7月",
        "8月",
        "9月",
        "10月",
        "11月",
        "12月"
      ],
      axisTick: {
        show: false // 去除刻度线
      },
      axisLabel: {
        color: "#4c9bfd" // 文本颜色
      },
      axisLine: {
        show: false // 去除轴线
      }
    },
    yAxis: {
      type: "value",
      axisTick: {
        show: false // 去除刻度线
      },
      axisLabel: {
        color: "#4c9bfd" // 文本颜色
      },
      axisLine: {
        show: false // 去除轴线
      },
      splitLine: {
        lineStyle: {
          color: "#012f4a" // 分割线颜色
        }
      }
    },
    series: [
      {
        name: "f1",
        type: "line",
        // true 可以让我们的折线显示带有弧度
        smooth: true,
        data: yearData[0].data[0]
      },
      {
        name: "f2",
        type: "line",
        smooth: true,
        data: yearData[0].data[1]
      },{
        name: "f3",
        type: "line",
        smooth: true,
        data: yearData[0].data[2]
      },
      {
        name: "f3",
        type: "line",
        smooth: true,
        data: yearData[0].data[3]
      },{
        name: "f4",
        type: "line",
        smooth: true,
        data: yearData[0].data[4]
      },{
        name: "f5",
        type: "line",
        smooth: true,
        data: yearData[0].data[5]
      },{
        name: "f6",
        type: "line",
        smooth: true,
        data: yearData[0].data[6]
      },
      {
        name: "f7",
        type: "line",
        smooth: true,
        data: yearData[0].data[7]
      },{
        name: "f8",
        type: "line",
        smooth: true,
        data: yearData[0].data[8]
      }
    ]
      };  
      myChart.setOption(diameterOption);
},
open(){
        this.$nextTick(() => {
        //  执行echarts方法
          this.showDialog()
        })
      }

  }
}
</script>

解释代码:

dialogVisible控制这个弹窗出现的。

handleClose(done) 。弹窗自己需要的函数,不管,这里不重要,和它没有关系

showDialog()。这个就很重要了。我们在这个函数里面去实例化对象然后配置信息。我们在这里使用this.dialogVisible = true;来展示弹窗,这样就不需要去用到v-if或者v-on这样的事情了,避免麻烦。

我们知道对话框中无法加载echarts的原因是vue底层,通过document.ElementById("id")获取DOM节点时,DOM节点还未生成,所以获取不到DOM节点。那么我们只需要在对话框生成时有了dom节点时,去获取节点,那么我们就需要一个函数了,它的作用就是弹框打开的时候能够渲染ercharts.

所以在按钮上面我们继续使用showDialog()函数,虽然获取不到dom元素,因为没有生成,但是showDialog()里面有this.dialogVisible = true;我可以让弹窗出现呗。然后出现的同时,由于<el-dialog>上面有一个open事件被监听它每打开一次就会执行open()函数,所以打开的时候,又会去调用showDialog()函数,这样dom已经生成了,我们能够渲染了。

 完整代码:

<template>
  <el-container>
  <el-header> <button v-on:click="showDialog">点我</button></el-header>
  <el-main>
    <el-dialog
  title="一年票价趋势"
  :visible.sync="dialogVisible"
  width="70%"
  @open="open()"
  :before-close="handleClose">
  <div id="cc" ref="cc" style="width:500px;height:400px;padding-top:40px"></div>
  <span slot="footer" class="dialog-footer">
    <el-button @click="dialogVisible = false">取 消</el-button>
    <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
  </span>
</el-dialog>
  </el-main>
</el-container>
</template>
  
<script>


export default {
  data() {
    return {
      dialogVisible: false,
    }
  },
  methods: {
    handleClose(done) {
        this.$confirm('确认关闭?')
          .then(_ => {
            done();
          })
          .catch(_ => {});
    },
      // 弹框的触发事件
    showDialog() {
      var yearData = [
    {
      year: "2020", // 年份
      data: [
        // 两个数组是因为有两条线
        [240, 170, 101, 134, 190, 230, 210, 230, 120, 230, 210, 120],
        [130, 164, 191, 324, 290, 330, 310, 213, 180, 200, 180, 120],
        [210, 300, 70, 100, 110, 200, 230, 180, 160, 119, 120, 180],
        [200, 74, 191, 214, 290, 130, 310, 213, 120, 110, 180, 170],
        [57, 64, 91, 124, 90, 130, 110, 113, 110, 130, 100, 120],
        [340, 270, 331, 434, 290, 330, 210, 230, 120, 230, 210, 120],
        [330, 270, 121, 134, 157, 230, 210, 230, 220, 230, 118, 120],
        [112, 231, 213, 215, 261, 278, 127, 129, 139, 199, 200, 210],
        [134,131,113,115,161,178,227,229,239,199,210,200],
      ]
    }
      ];

	this.dialogVisible = true;//展示弹窗
      let diameter = this.$refs.cc//放置echarts图示的div的ref值
      const myChart = this.$echarts.init(diameter);
    let diameterOption = {
    color: ["#00f2f1", "#ed3f35","#ddd","#00ff00","#ffa500","#800080","#0000ff"],
    tooltip: {
      trigger: "axis"
    },
    legend: {
      // 如果series 对象有name 值,则 legend可以不用写data
      // 修改图例组件 文字颜色
      textStyle: {
        color: "#4c9bfd"
      },
      // 这个10% 必须加引号
      right: "10%"
    },
    grid: {
      top: "20%",
      left: "3%",
      right: "4%",
      bottom: "3%",
      show: true, // 显示边框
      borderColor: "#012f4a", // 边框颜色
      containLabel: true // 包含刻度文字在内
    },

    xAxis: {
      type: "category",
      boundaryGap: false,
      data: [
        "1月",
        "2月",
        "3月",
        "4月",
        "5月",
        "6月",
        "7月",
        "8月",
        "9月",
        "10月",
        "11月",
        "12月"
      ],
      axisTick: {
        show: false // 去除刻度线
      },
      axisLabel: {
        color: "#4c9bfd" // 文本颜色
      },
      axisLine: {
        show: false // 去除轴线
      }
    },
    yAxis: {
      type: "value",
      axisTick: {
        show: false // 去除刻度线
      },
      axisLabel: {
        color: "#4c9bfd" // 文本颜色
      },
      axisLine: {
        show: false // 去除轴线
      },
      splitLine: {
        lineStyle: {
          color: "#012f4a" // 分割线颜色
        }
      }
    },
    series: [
      {
        name: "f1",
        type: "line",
        // true 可以让我们的折线显示带有弧度
        smooth: true,
        data: yearData[0].data[0]
      },
      {
        name: "f2",
        type: "line",
        smooth: true,
        data: yearData[0].data[1]
      },{
        name: "f3",
        type: "line",
        smooth: true,
        data: yearData[0].data[2]
      },
      {
        name: "f3",
        type: "line",
        smooth: true,
        data: yearData[0].data[3]
      },{
        name: "f4",
        type: "line",
        smooth: true,
        data: yearData[0].data[4]
      },{
        name: "f5",
        type: "line",
        smooth: true,
        data: yearData[0].data[5]
      },{
        name: "f6",
        type: "line",
        smooth: true,
        data: yearData[0].data[6]
      },
      {
        name: "f7",
        type: "line",
        smooth: true,
        data: yearData[0].data[7]
      },{
        name: "f8",
        type: "line",
        smooth: true,
        data: yearData[0].data[8]
      }
    ]
      };  
      myChart.setOption(diameterOption);
},open(){
        this.$nextTick(() => {
        //  执行echarts方法
          this.showDialog()
        })
      }

  }
}
</script>

感谢观众老爷的观看,下一篇文章我将讲解如何使用three.js与vue中的Dialog 对话框结合。

  • 21
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值