项目场景:
我在项目里面封装了一个echarts组件,组件接收一个来自外部的option,然后我用了一个watch函数去监听这个option的变化,option变化之后,销毁,然后再新建一个charts表
碎碎念
问题如标题所示,这篇文章屯了蛮久了,其实我也不太记得大概是啥问题了,但感觉解决方法挺有意思的,暂时就先记录一下吧。记得当时排查问题,这个还有个啥其他的问题,但是被我解决了,
基本上这种类似的问题,都可以通过注释或者报错定位,慢慢排查错误来源,当然浏览器debug也可以,不过我对自己的代码比较熟悉,而且层级嵌套也不深,所以一般用不到debug
解决方案:
这里提供两种方案供大家解决
方法1:watch 的第一个参数改为 ()=> props.option
type Prop = {
option: EChartsOption | null;
};
const props = defineProps<Prop>();
const echarts = inject(myInjectionEcharts);
let mycharts;
watch(
() => props.option,
() => {
if (props.option) {
window.removeEventListener("resize", mycharts.__resize);
echarts.dispose(mycharts);
initCharts(props.option);
}
},
);
方法2:将这个props用toRefs包裹之后再把option结构出来,watch 去监听这个option
type Prop = {
option: EChartsOption | null;
};
const props = defineProps<Prop>();
const { option } = toRefs(props);
const echarts = inject(myInjectionEcharts);
let mycharts;
watch(
option,
() => {
if (props.option) {
window.removeEventListener("resize", mycharts.__resize);
echarts.dispose(mycharts);
initCharts(props.option);
}
},
);
理解与排查思路
首先,我们要明确watch的使用(本来想给大家翻找一下vue3中文文档的,笑死,今天他好像崩了),
watch 的定义如下:监视一个或多个反应性数据源,并在源发生更改时调用回调函数。
他的第一个参数,只能是下面这些:
翻译来说: 1. 返回一个值的getter方法,2.ref 3. reactive 4. 由上面这几种组成的数组?
总的来说就是,他只监听响应式的数据。
而我之前的错误写法,如下:
type Prop = {
option: EChartsOption | null;
};
const props = defineProps<Prop>();
const echarts = inject(myInjectionEcharts);
let mycharts;
watch(
props.option,
() => {
if (props.option) {
window.removeEventListener("resize", mycharts.__resize);
echarts.dispose(mycharts);
initCharts(props.option);
}
},
);
这个Prop是响应式的,好像是类似reactive包裹的一个对象(有点不记得了,明天我验证一下),
而我这个props.option 这个响应式里面的对象是不带响应式的,所有可以用到如官网所示的一种方法,把他变成一个getter的写法
而第二种则是借助到 toRefs()
toRefs() 批量处理对象中的所有属性,第一层,变成响应式
toRef() 需要传参,且只能将一个属性变成响应式
如官网所示,这种将响应式对象的内部熟悉变为响应式,再解构出来的方法,倒也是蛮常规的。
就是上面的方法2 。
求关注啦,求点赞啦,每次写这种解决bug的文章都没啥人愿意给我点个小赞,哭死,呜呜呜