在学习Vue3源码过程中,突然想到两个问题
- 1、Vue3 处理属性的优先级?
- 2、Vue3 和 Vue2 在属性处理的优先级,有什么不同?
一、Vue3属性的优先级
- 入口文件
core\packages\runtime-core\src\component.ts
// 第一步: initPorps 方法 处理 porps
// 第二步: applyOptions 处理 data、method 等属性
- applyOpitons 方法
// 属性处理顺序是:
// inject => methods => data => computed => watch => provide
- 最终处理顺序
porps => inject => methods => data => computed => watch => provide
// 同时会用 checkDuplicateProperties方法 在 每个属性中的字段 init 完成后,检查该属性 是否存在。如不不存在 就放入 cache 作为记录,如果存在就报警告;
/*
文件: packages\runtime-core\src\componentPublicInstance.ts
方法 exposePropsOnRenderContext 将 propsOpitons 添加 ctx 对象上, 同时将 `set` 设置为 `NOOP`
*/
注意:
applyOpitons 方法中,有一句注释
options initialization order (to be consistent with Vue 2)即 “Vue3属性选项初始化的顺序和Vue2是一致的” 这是不对的。下面将Vue2 会解释。
二、Vue2 属性的优先级
- 入口文件
src\core\instance\init.js
// Vue2 是 先处理 `inject` 再处理 其他的属性,最后处理 `provide`
// 处理顺序的差异就体现在 Vue2 先处理 inject 而 Vue3 先处理 props
initInjections(vm) // resolve injections before data/props
initState(vm) // 下面会分析内部处理顺序
initProvide(vm) // resolve provide after data/props
- initSatate 方法
// 属性处理顺序是:
props => methods => data => computed => watch => provide
- 最终处理顺序
inject => props => methods => data => computed => watch => provide
特殊场景
1、data 和 inject 冲突
Vue2 和 Vue3 表现是一致的,data 的优先级高于 inject
因为 data 中的每个属性set 方法都被设置为 NOOP
2、props 和 inject 冲突
Vue2 和 Vue3 就表现不一致了
- Vue2
inject的优先级 高于props - Vue3
props的优先级高于inject因为取值的顺序的原因
三、Vue3 属性取值顺序
- 入口文件
runtime-core/src/component.ts
// setupComponent 函数为入口,返回的结果(setupResult)就是 setup方法的返回的结果
// setupStatefulComponent 函数的中的:
instance.proxy = markRaw(new Proxy(instance.ctx, PublicInstanceProxyHandlers))
// PublicInstanceProxyHandlers 函数 决定获取结果顺序
// (1) setupState
// (2) data
// (3) props
// (4) 其他挂载到 ctx 上的属性