起因:想封装一个hooks实现echarts图表随屏幕大小resize并且组件销毁时移除监听。结果在组件里面调用这个hooks,有个告警提示 [Vue warn]: onBeforeUnmount is called when there is no active component instance to be associated with. Lifecycle injection APIs can only be used during execution of setup(). If you are using async setup(), make sure to register lifecycle hooks before the first await statement.
意思是,在没有活跃组件实例可关联的情况下调用了onBeforeUnmount
。生命周期注入API只能在setup()
执行期间使用。如果您使用了异步setup()
,请确保在第一个await
语句之前注册生命周期钩子。
因为在页面上面,是先调用了async/await来获取接口数据,获取到数据之后再绘制图表,调用useEcharts hooks
useEcharts 里面是这样写的
开始思考,咦?不能在await之后再调用生命周期,那不是不能写hooks了?没道理吧?咦,等一下,那vueuse里面的hooks怎么写的,他不是有节流防抖的hooks吗,那必然用到setTimeout这种,咦,那她难道不用调用生命周期函数来清除定时器?遂去看vueuse
大概是先获取生命周期实例,判断该实例是否存在,若存在,调用vueDemi的onMounted方法,将具体的实现方法传入。
那vueDemi是个啥嘞?onMounted的第二个参数target 又是个啥嘞?
嗷,是个辅助兼容vue2和vue3的包。那导出的onMounted就是生命周期钩子,那第二参数target是干啥的?看看vue源码
先调用createHook生成hook,入参是type,应该是vue内部自定义的一些字符串标识,看起来像是取首字母,类似onMounted 取m,onBeforeMount取bm。然后createHook接收两个参数,type 和 target = currentInstance,盲猜currentInstance是组件实例,但不确定,再看看
咦,getCurrentInstance() 不就是获取组件实例嘛,破案了友友们。 那就好办了
测试一下,可以在组件里面调用相同的生命周期钩子,console.log一下看看是否都有输出