// **src/core/instance/state.js**
// 组件初始化入口
export function initState(vm: Component) {
const opts = vm.$options
if (opts.props) initProps(vm, opts.props)
}
function initProps(vm: Component, propsOptions: Object) {
const propsData = vm.$options.propsData || {}
const props = (vm._props = {})
// 创建响应式访问代理
for (const key in propsOptions) {
defineReactive(props, key, value)
// 代理到组件实例
if (!(key in vm)) {
proxy(vm, '_props', key)
}
}
}
关键流程:
defineReactive
创建响应式属性this.propName
代理到 this._props.propName
// **src/core/vdom/patch.js**
function prepatch(oldVnode: VNodeWithData, vnode: VNodeWithData) {
const options = vnode.componentOptions
const child = vnode.componentInstance = oldVnode.componentInstance
// 更新子组件 Props
updateChildComponent(
child,
options.propsData, // 新 Props
options.listeners, // 新事件
vnode, // 新 VNode
options.children // 新插槽
)
}
// src/core/instance/lifecycle.js
export function updateChildComponent(
vm: Component,
propsData: ?Object,
) {
// 更新 props
const props = vm._props
for (const key in props) {
props[key] = validateProp(key, vm.$options.props, propsData, vm)
}
}
更新触发路径:
graph TD
父组件数据变化 --> 父组件重新渲染
父组件重新渲染 --> 生成新子组件VNode
新子组件VNode --> patch过程
patch过程 --> prepatch钩子
prepatch钩子 --> 更新_props对象
_props对象更新 --> 触发响应式系统
响应式系统 --> 子组件重新渲染
// src/core/observer/index.js
export function defineReactive(
obj: Object,
key: string,
val: any,
) {
const dep = new Dep()
Object.defineProperty(obj, key, {
get: function reactiveGetter() {
if (Dep.target) {
dep.depend() // 收集依赖
}
return val
},
set: function reactiveSetter(newVal) {
val = newVal
dep.notify() // 触发更新
}
})
}
核心机制:
Dep
依赖收集器getter
收集依赖setter
触发子组件更新