数据驱动
相信大家都知道,Vue.js 一个核心思想是数据驱动。所谓数据驱动,是指视图是由数据驱动生成的,我们对视图的修改,不会直接操作 DOM,而是通过修改数据。它相比我们传统的前端开发,如使用 jQuery 等前端库直接修改 DOM,大大简化了代码量。 在 Vue.js 中我们可以采用简洁的模板语法来声明式的将数据渲染为 DOM:
<div id="app">
{{ message }}
</div>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
})
最终它会在页面上渲染出 Hello Vue,了解真正的原理那我们从源码入口开始看吧
new Vue 的执行过程发生了什么
小源码分析
从入口代码开始分析,我们先来分析 new Vue 背后发生了哪些事情。我们都知道,new 关键字在 Javascript 语言中代表实例化是一个对象,而 Vue 实际上是一个类,类在 Javascript 中是用 Function 来实现的,来看一下源码,在src/core/instance/index.js 中。
function Vue (options) {
if (process.env.NODE_ENV !== 'production' &&
!(this instanceof Vue)
) {
warn('Vue is a constructor and should be called with the `new` keyword')
}
this._init(options)
}
initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)
其实这里就可以看到它的庐山真面目,这里vue实例的时候就是执行原型上的inti方法,问题来了,原型的上面是什么时候挂载上去的呢,其实下面的initMixin,**Mixin等,就是定义vue的原型方法,其实我们项目中经常见的emit$off就是在这个时候挂载在vue原型上面的,
我们这次的主角是_init,我们来继续看看初始化方法到底做了什么
Vue 初始化主要就干了几件事情,合并配置,初始化生命周期,初始化事件中心,初始化渲染,初始化 data、props、computed、watcher 等等。
if (vm.$options.el) {
vm.$mount(vm.$options.el)
}
init方法最终的目标就是走mount方法在文件entry-runtime-with-compiler.js以及定义了,下一讲我们会着重分析这个$mount方法,看看它是怎么实现的,解开他的神秘面纱。
小总结
Vue 的初始化逻辑写的非常清楚,把不同的功能逻辑拆成一些单独的函数执行,让主线逻辑一目了然,这样的编程思想是非常值得借鉴和学习的。
由于我们这一章的目标是弄清楚模板和数据如何渲染成最终的 DOM,所以各种初始化逻辑我们先不看。在初始化的最后,检测到如果有 el 属性,则调用 vm.$mount 方法挂载 vm,挂载的目标就是把模板渲染成最终的 DOM,那么接下来我们来分析 Vue 的挂载过程。