Vuejs中 watch computed属性与生命周期之间的关系与执行顺序(详细)
前言
在工作中频繁遇到Vue的生命周期与watch
、computed
之间联系紧密的逻辑,所以特地起了一个项目专门研究他们之间的关系和执行顺序。
本项目页面分成两个组件,父组件和其包含的子组件,分别定义其各个生命周期钩子函数,函数作用是输出执行时机,以此来判断执行顺序。
接下来直接做验证:
初始化
- 如果只有单个组件,在Vue初始化时的组件执行顺序如下
beforeCreate
>watch
(?立即监听) >created
>beforeMount
>computed
>mounted
- 如果父组件中
- 页面中关联了
computed
计算属性,但与watch
无关联
- 页面中关联了
父组件
beforeCreate
> 父组件watch
(?立即监听) > 父组件created
> 父组件beforeMount
> (父组件computed
) > 子组件beforeCreate
> 子组件watch
(?立即监听) > 子组件created
> 子组件beforeMount
>(子组件computed
) > 子组件mounted
> 父组件mounted
- 如果父组件中
watch
中关联了computed
属性,但未与页面关联
父组件
beforeCreate
> 父组件watch
(?立即监听) > (父组件computed
> 父组件watch
(?立即监听)) > 父组件created
> 父组件beforeMount
> 子组件beforeCreate
> 子组件watch
(?立即监听) >(子组件computed
> 子组件watch
(?立即监听)) > 子组件created
> 子组件beforeMount
> 子组件mounted
> 父组件mounted
- 如果父组件中
watch
中关联了computed
属性,又与页面
关联
与(watch
中关联了computed
属性,但未与页面
关联)执行顺序相同
Tips: 以上watch都是配置了immediate=true的情况 且做了标注,如果为false,则不会立即执行
运行时
- 执行组件
methods
中的方法使组件中与页面相关联的data
发生变化执行顺序如下
watch
>beforeUpdate
>computed
>updated
- 执行父组件
methods
中的方法使子组件中与页面相关联的data
发生变化(有传值给子组件)- 页面中关联了
computed
计算属性,但与watch
无关联
- 页面中关联了
父组件
watch
> 父组件beforeUpdate
> (父组件computed
) > 子组件watch
> 子组件beforeUpdate
> (子组件computed
) > 子组件update
> 父组件updated
- 执行父组件
methods中
的方法使子组件中与页面相关联的data发生变化(有传值给子组件)watch
中关联了computed
属性,但未与页面关联
父组件
watch
> (父组件computed
> 父组件watch
) > 父组件beforeUpdate
> 子组件watch
> (子组件computed
> 子组件watch
) > 子组件beforeUpdate
> 子组件update
> 父组件updated
- 执行父组件
methods
中的方法使子组件中与页面相关联的data发生变化(有传值给子组件)watch
中关联了computed
属性,又与页面关联
与(watch
中关联了computed
属性,但未与页面
关联执行顺序)相同
结论
- computed计算属性在首次初始化时在beforeMount和mounted之间会执行一次。
- 初始化时,只要与computed关联的watch设置了立即监听,computed总是会在create钩子执行之前提前执行(可能是因为watch侦听属性如果设置了immdiate属性为true,那么在初始化时会在beforeCreate和created之间执行一次,会导致computed强制提前)。
- 组件中data、props值改变后,首先是关联的watch执行回调,然后在beforeUpdate和updated之间关联的computed会执行回调,如果此时有watch与computed有关联,那么watch会再次执行。