vue2和vue3封装echarts的比较(vue3深度监听真香!!!)

959 阅读1分钟

vue2封装echarts

无法监听到option的变化

  • 我们在组件里面把option写成props,然后watch。

  • 我们在app.vue中通过button改变传入的option

  • 然后我们发现数据变了,但是没有监听到数据! 在这里插入图片描述

  • 通过log我们发现option数据是变化了的,但是没有监听到


app.vue核心代码

    <echarts :options="options" :width="width" :Echarts_data="Echarts_data">
    </echarts>
    <button @click="changeWidth">改变宽度</button>
    <button @click="changeData">改变内容</button>
    // **************************************************
    changeData () {
       console.log(this.options.series[0].data)
       this.options.series[0].data = [10, 10, 36, 10, 10, 10]
       console.log(this.options.series[0].data)
    }

echarts.vue核心代码

  props: {
    options: {
      type: Object,
      default: null
    }
  }
  // **************************************************
  watch: {
    options () {
      if (this.myChart) {
        this.myChart.setOption(this.options, {
          notMerge: true
        })
      }
    }
  }

添加一个echarts_data数据监听来解决问题

通过添加一个props直接监听数据,进入后再进行option的改变

    Echarts_data () {
      if (this.myChart) {
        this.options.series[0].data = this.Echarts_data //这里
        this.myChart.setOption(this.options, {
          notMerge: true
        })
      }
    }

vue3封装echarts

使用deep:true深度监听直接解决问题

这个就很简单了,直接加一个deep:true就可以完成深度监听了!!!

总结

vue3的deep:true很好的解决了数组深度监听的问题!

附录:代码

B站视频地址

vue2和vue3封装echarts的比较

vue2

app.vue

<template>
  <div id="app">
    <echarts :options="options" :width="width" :Echarts_data="Echarts_data">
    </echarts>
    <button @click="changeWidth">改变宽度</button>
    <button @click="changeData">改变内容</button>
  </div>
</template>
<script>
import echarts from './components/Echarts.vue'
import { options1 } from './assets/options/options'
export default {
  components: { echarts },
  name: 'App',
  data () {
    return {
      options: options1,
      width: '600px',
      Echarts_data: [5, 20, 36, 10, 10, 20]
    }
  },
  methods: {
    changeWidth () {
      if (this.width === '600px') {
        this.width = '800px'
      } else {
        this.width = '600px'
      }
      console.log(this.width)
    },
    changeData () {
      // console.log(this.options.series[0].data)
      // this.options.series[0].data = [10, 10, 36, 10, 10, 10]
      // console.log(this.options.series[0].data)
      console.log(this.Echarts_data)
      if (this.Echarts_data[0] === 10) {
        this.Echarts_data = [5, 20, 36, 10, 10, 20]
      } else {
        this.Echarts_data = [10, 10, 36, 10, 10, 10]
      }
      console.log(this.Echarts_data)
    }
  }
}
</script>
<style>
</style>

echarts.vue

<template>
  <div :id="uuid" :style="style"></div>
</template>

<script>
import * as echarts from 'echarts'
const idGen = () => {
  return new Date().getTime()
}
export default {
  props: {
    height: {
      type: String,
      default: '400px'
    },
    width: {
      type: String,
      default: '600px'
    },
    options: {
      type: Object,
      default: null
    },
    Echarts_data: {
      type: Array,
      default: null
    }
  },
  data () {
    return {
      uuid: null,
      myChart: null
    }
  },
  watch: {
    width () {
      if (this.myChart) {
        this.myChart.resize({
          animation: {
            duration: 300
          }
        })
      }
    },
    options () {
      if (this.myChart) {
        this.myChart.setOption(this.options, {
          notMerge: true
        })
      }
    },
    Echarts_data () {
      if (this.myChart) {
        this.options.series[0].data = this.Echarts_data
        this.myChart.setOption(this.options, {
          notMerge: true
        })
      }
    }
  },
  computed: {
    style () {
      return {
        height: this.height,
        width: this.width
      }
    }
  },
  created () {
    this.uuid = idGen()
    // this.options.series[0].data = this.arr
    if (this.myChart) {
      this.myChart.setOption(this.options, {
        notMerge: true
      })
    }
  },
  mounted () {
    // 官方流程
    // 基于准备好的dom,初始化echarts实例
    this.myChart = echarts.init(document.getElementById(this.uuid))
    // 指定图表的配置项和数据
    // 使用刚指定的配置项和数据显示图表。
    this.myChart.setOption(this.options)
  }
}
</script>

<style>
</style>

vue3

app.vue

<template>
  <echarts :options="option"></echarts>
  <button @click="changeData">改变数据</button>
</template>

<script lang="ts">
import { defineComponent, reactive } from "vue";
import echarts from "./components/echarts.vue";
import { options1 } from "./assets/options";
export default defineComponent({
  name: "App",
  components: {
    echarts,
  },
  setup() {
    let option = reactive(options1);
    const changeData = () => {
      if (option.series[0].data[0] != 10) {
        option.series[0].data = [10, 10, 36, 10, 10, 10];
      } else {
        option.series[0].data = [5, 20, 36, 10, 10, 20];
      }
    };
    return {
      option,
      changeData,
    };
  },
});
</script>

echarts.vue

<!--
 * @Author: 41
 * @Date: 2021-11-15 10:48:28
 * @LastEditors: 41
 * @LastEditTime: 2022-02-07 15:26:25
 * @Description:
-->

<template>
  <div :id="uuid" style="height: 400px; width: 600px"></div>
</template>

<script lang="ts">
import { defineComponent, onMounted, watch } from "vue";
import * as echarts from "echarts";
export default defineComponent({
  name: "App",
  props: {
    options: {
      type: Object,
      default: null,
    },
  },
  setup(props) {
    const idGen = () => {
      return new Date().getTime();
    };
    let uuid = idGen();
    let charts = null;
    const initEcharts = () => {
      if (!charts) {
        const dom = document.getElementById(uuid.toString());
        charts = echarts.init(dom);
      } else {
        return;
      }
      if (!props.options) return;
      charts.setOption(props.options);
    };
    watch(
      props.options,
      () => {
        if (charts) {
          charts.setOption(props.options);
        }
      },
      { deep: true }
    );
    onMounted(() => {
      initEcharts();
    });
    return {
      uuid,
    };
  },
});
</script>

<style>
</style>