vue2源码分析-数据驱动
Vue.js 一个核心思想是数据驱动。所谓数据驱动,是指视图是由数据驱动生成的,我们对视图的修改,不会直接操作 DOM,而是通过修改数据。他相比我们传统的前端开发,如使用 jQuery 等前端库直接修改 DOM,大大简化了代码量。特别是当交互复杂的时候,只关心数据的修改会让代码逻辑变得非常清晰,因为 DOM 变成了数据的映射,我们所有的逻辑都是对数据的修改
new vue 发生了什么
src/core/instance/index.js
initMixin
注册_init
方法
initLifecycle(vm)
initEvents(vm)
initRender(vm)
callHook(vm, 'beforeCreate')
initInjections(vm) // resolve injections before data/props
initState(vm)
initProvide(vm) // resolve provide after data/props
callHook(vm, 'created')
挂载vm.$mount(vm.$options.el)
mounted 里如何访问 data 里的数据initState()
-> initData()
data 也会赋值给 _data
proxy((target: Object), (sourceKey: string), (key: string)) {}
//initData方法里调 proxy()
initData(vm: Component) {
data = vm._data = typeof data === 'function'
? getData(data, vm)
: data || {}
const keys = Object.keys(data)
// ...
proxy(vm, `_data`, key)
// 数据响应式处理
observe(data ,true)
}
vue 实例挂载的实现
Vue 中我们是通过 $mount
实例方法去挂载 vm 的,$mount 方法在多个文件中都有定义src/platforms/web/entry-runtime-with-compiler.js
、src/platform/web /runtime/index.js
、src/platfrom/weex/runtime/index.js
。因为 $mount
这个方法是和平台、构建方式都相关的。接下来重点分析 compiler 版本的$mount 实现,因为抛开 webpack 的 vue-loader,我们在纯前端环境分 Vue 的工作原理,有助于我们对原理理解的深入。
complier 版本的 $mount 实现非常有意思,先来看下src/platforms/web/entry-runtime-with-compiler.js
文件中的定义
new Watcher() 渲染 watcher
定义 src/core/observer/watcher.js
调用 updateComponent
updateComponent = () => {
vm._update(vm._render(), hydrating)
}
render
vm._render
返回的是 VNode
vm.renderProxy 在生产环境就是 vm