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
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>