initState
// core/instance/state.js
export function initState(vm: Component) {
vm._watchers = []
const opts = vm.$options
if (opts.props) initProps(vm, opts.props)
if (opts.methods) initMethods(vm, opts.methods)
if (opts.data) initData(vm)
else observe((vm._data = {}), true /* asRootData */)
if (opts.computed) initComputed(vm, opts.computed)
if (opts.watch && opts.watch !== nativeWatch) {
initWatch(vm, opts.watch)
}
}
_wathers存放实例的new Watch实例
1. initProps
function initProps(vm: Component, propsOptions: Object) {
const propsData = vm.$options.propsData || {}
const props = (vm._props = {})
const keys = (vm.$options._propKeys = [])
const isRoot = !vm.$parent
if (!isRoot) toggleObserving(false) // 与vm._isVue类似控制observe函数
for (const key in propsOptions) {
keys.push(key)
const value = validateProp(key, propsOptions, propsData, vm)
defineReactive(props, key, value)
if (!(key in vm)) {
proxy(vm, `_props`, key)
}
}
toggleObserving(true)
}
$options的数据包装响应至_prop,并代理(proxy)至vmvalidateProp()getTypeIndex()判断是否为Boolean (或[Boolean]) 返回true/falsevalue === undefined=> 取默认值- return value
2. initMethods
function initMethods(vm: Component, methods: Object) {
const props = vm.$options.props
for (const key in methods) {
//省略...检查function、props属性冲突、保留字冲突
vm[key] = typeof methods[key] !== 'function' ? noop : bind(methods[key], vm)
}
}
vm属性指向methodbind()=>Function.prototype.bind绑定vm=>this
3. initData
function initData(vm: Component) {
let data = vm.$options.data
data = vm._data = typeof data === 'function' ? getData(data, vm) : data || {}
if (!isPlainObject(data)) {
data = {}
}
// proxy data on instance
const keys = Object.keys(data)
const props = vm.$options.props
const methods = vm.$options.methods
let i = keys.length
while (i--) {
const key = keys[i]
if (props && hasOwn(props, key)) {
// ...检查警告
} else if (!isReserved(key)) {
proxy(vm, `_data`, key)
}
}
// observe data
observe(data, true /* asRootData */)
}
getData()取值,同时pushTarget()以停止dep收集- getData 调用
data.call(vm, vm),绑定 this 并传入 vm
- getData 调用
- 查重并代理
observe()包裹响应性new Dep()def(value, '__ob__', this)挂载__ob__- 如果是Array则在原型链上插入
arrayMethods追踪inserted,并触发__ob__.dep.notify() - 否则常规
Object.keys=>defineReactive()
4. initComputed
function initComputed(vm: Component, computed: Object) {
const watchers = (vm._computedWatchers = Object.create(null))
for (const key in computed) {
const userDef = computed[key]
const getter = typeof userDef === 'function' ? userDef : userDef.get
if (!(key in vm)) {
defineComputed(vm, key, userDef)
}
}
}
-
vm._computedWatchers=>watchers[key] = new Watcher()生成WatchercomputedWatcherOptions = { lazy: true }
-
for (const key in computed)=>defineComputed()=>createComputedGetter() -
watcher.depend()=> 主动依赖 -
return
computedGetter()-
watcher.dirty=>watcher.evaluate() -
return
watcher.value
-
5. initWatch
function initWatch(vm: Component, watch: Object) {
for (const key in watch) {
const handler = watch[key]
if (Array.isArray(handler)) {
for (let i = 0; i < handler.length; i++) {
createWatcher(vm, key, handler[i])
}
} else {
createWatcher(vm, key, handler)
}
}
}
createWatcher()=>vm.$watch()- 如果watch属性是对象,专业对象到
options,并取出handler key=>handler = vm[handler]取出以上代理属性并触发依赖depend()new Watchervm._watchers.push(this)
- return
unwatchFn()
- 如果watch属性是对象,专业对象到