Vue.js : 是一套构建用户界面的渐进式框架。
一、什么是框架?
在最初前端开发中,为了完成某个任务,我们首先利用js从html文件中获取dom元素,随后添加事件,最后进行一系列的js编程操作,这种开发方式暂且称为“don流”,在现实开发中需求变化,复杂的业务逻辑和巨大的代码量是“dom流”无法承受的,
对应以上问题,衍变出了把js代码划分为三个板块:数据,视图,逻辑控制,数据版块只含有数据内容,视图板块只负责更改样式,逻辑控制负责联系视图板块和数据版块和相应的逻辑。这样代码结构变得清晰易懂,因需求而改动代码程度变小。
其实这种开发方式,就是我们常说的MV模式,而MVC、MVVM、 MVP[2]等都是MV的衍生物
而这种MV*的代码组织方式,渐渐的就演变成了所谓的框架。
Vue的核心定位并不是一个框架,设计上也没有完全遵循MVVM模式,可以看到在图中只有State和View两部分, Vue的核心功能强调的是状态到界面的映射,对于代码的结构组织并不重视, 所以单纯只使用其核心功能时,它并不是一个框架,而更像一个视图模板引擎,这也是为什么Vue开发者把其命名成读音类似于view的原因。
二、对渐进式的理解:
如下图所示,这里包含了Vue的所有部件,在声明式渲染(视图模板引擎)的基础上,我们可以通过添加组件系统、客户端路由、大规模状态管理来构建一个完整的框架。更重要的是,这些功能相互独立,你可以在核心功能的基础上任意选用其他的部件,不一定要全部整合在一起。可以看到,所说的“渐进式”,其实就是Vue的使用方式,同时也体现了Vue的设计的理念
以上参考 (http://blog.csdn.net/crazy_banana/article/details/71079925)
Vue.js是一个提供MVVM数据双向绑定的库,专注于UI层面,核心思想是:数据驱动、组件系统。
三、核心内容
【1】、Vue渲染逻辑
===============Render函数===============
$mount方法就是整个渲染过程的起始点
在渲染过程中,提供了三种渲染模式,自定义Render函数、template、el均可以渲染页面,也就是对应我们使用Vue时,三种写法:
2、3这两种都属于声明式渲染
1. 自定义Render函数
1.Vue.component('anchored-heading', {
2. render: function (createElement) {
3. return createElement(
4. 'h' + this.level, // tag name 标签名称
5. this.$slots.default // 子组件中的阵列
6. )
7. },
8. props: {
9. level: {
10. type: Number,
11. required: true
12. }
13. }
14.})
2. template写法
1.var vm = new Vue({
2. data: {
3. // 以一个空值声明 `msg`
4. msg: ''
5. },
6. template: '<div>{{msg}}</div>'
7.})
3. el写法(这个就是入门时最基本的写法)
1.var app = new Vue({
2. el: '#app',
3. data: {
4. message: 'Hello Vue!'
5. }
6.})
这三种渲染模式最终都是要得到Render函数。只不过用户自定义的Render函数省去了程序分析的过程,等同于处理过的Render函数,而普通的template或者el只是字符串,需要解析成AST,再将AST转化为Render函数。
===============虚拟DOM&patch方法===============
Virtual DOM有多种实现方式,但基本思路都是一样的,分为两步:
1.Render函数生成Virtual DOM
VNode对象是什么?
VNode就是Vue.js 2.0中的Virtual DOM,在Vue.js 2.0中,相较Vue.js 1.0引入了Virtual DOM的概念
在Vue.js 2.0中Javascript模拟DOM模型树就是VNode,Render函数执行后都会返回VNode对象,为下一步操作做准备。
2.Virtual DOM通过DOM Diff算法查找差异,将差异转为真正DOM节点
Render函数执行生成了VNode,而VNode只是Virtual DOM,我们还需要通过DOM Diff之后,来生成真正的DOM节点。在Vue.js 2.0中,是通过/src/core/vdom/patch.js中的patch(oldVnode, vnode ,hydrating)方法来完成的。
其主要逻辑为当VNode为真实元素或旧的VNode和新的VNode完全相同时,直接调用createElm方法生成真实的DOM树,当VNode新旧存在差异时,则调用patchVnode方法,通过比较新旧VNode节点,根据不同的状态对DOM做合理的添加、删除、修改DOM(这里的Diff算法有兴趣的读者可以自行阅读patchVnode方法,鉴于篇幅不再赘述),再调用createElm生成真实的DOM树。
===============Watcher & 数据驱动 & 依赖追踪===============
2、什么是数据驱动
数据驱动是vuejs最大的特点。在vuejs中,所谓的数据驱动就是当数据发生变化的时候,用户界面发生相应的变化,开发者不需要手动的去修改dom。
vuejs是如何实现这种数据驱动的呢?
Vuejs的数据驱动是通过MVVM这种框架来实现的。MVVM框架主要包含3个部分:model、view和 viewmodel。
Model:指的是数据部分,对应到前端就是javascript对象
View:指的是视图部分,对应前端就是dom
Viewmodel:就是连接视图与数据的中间件
数据(Model)和视图(View)是不能直接通讯的,而是需要通过ViewModel来实现双方的通讯。当数据变化的时候,viewModel能够监听到这种变化,并及时的通知view做出修改。同样的,当页面有事件触发时,viewMOdel也能够监听到事件,并通知model进行响应。Viewmodel就相当于一个观察者,监控着双方的动作,并及时通知对方进行相应的操作。
vuejs是通过在实现一个观察者来实现的数据驱动。
如何实现数据驱动的?
首先,vuejs在实例化的过程中,会对遍历传给实例化对象选项中的data 选项,遍历其所有属性并使用 Object.defineProperty 把这些属性全部转为 getter/setter。
同时每一个实例对象都有一个watcher实例对象,他会在模板编译的过程中,用getter去访问data的属性,watcher此时就会把用到的data属性记为依赖,这样就建立了视图与数据之间的联系。当之后我们渲染视图的数据依赖发生改变(即数据的setter被调用)的时候,watcher会对比前后两个的数值是否发生变化,然后确定是否通知视图进行重新渲染。
这样就实现了所谓的数据对于视图的驱动。
3、vue响应式原理---依赖追踪
Vue的依赖追踪通过ES5的 Object.defineProperty 方法实现。
比如,我们给它一个原生对象,Vue会遍历这个数据对象的属性,然后进行属性转换。每一个属性会被转换为一个 getter 和一个 setter。同时每个组件会有一个对应的 watcher 对象,这个对象的职责就是在当前组件被渲染的时候,记录数据上面的哪些属性被用到了。
例如,在渲染函数里面用到A.B的时候,这个就会触发对应的 getter。整个渲染流程具体要点如下:
当某个数据属性被用到时,触发 getter,这个属性就会被作为依赖被 watcher 记录下来。
整个函数被渲染完的时候,每一个被用到的数据属性都会被记录。
相应的数据变动时,例如给它一个新的值,就会触发 setter,通知数据对象对应数据有变化。
此时会通知对应的组件,其数据依赖有所改动,需要重新渲染。
对应的组件再次调动渲染函数,生成 Virtual DOM,实现 DOM 更新。
在Vue里面由于依赖追踪系统的存在,当任意数据变动的时,Vue的每一个组件都精确地知道自己是否需要重绘,所以并不需要手动优化。用Vue渲染这些组件的时候,数据变了,对应的组件基本上去除了手动优化的必要性。
核心关键的几步流程还是非常清晰的:
1、new Vue,执行初始化
2、挂载$mount方法,通过自定义Render方法、template、el等生成Render函数
3、通过Watcher监听数据的变化
4、当数据发生变化时,Render函数执行生成VNode对象
5、通过patch方法,对比新旧VNode对象,通过DOM Diff算法,添加、修改、删除真正的DOM元素
至此,整个new Vue的渲染过程完毕。
render流程:
1、创建虚拟DOM
2、真实DOM 连接 虚拟DOM
3、视图更新
4、计算 [ 新虚拟DOM ] 和 [ 旧虚拟DOM ] 的差异 ( diff )
5、根据计算的 差异, 更新真实DOM ( patch )
这里牵涉到两个词语 diff 和 patch,稍后再解释,这里简单理解为 [计算差异]和[应用差异]。
【2】、组件系统
核心思想都是一样,把UI结构映射到恰当的组件树
在Vue中,父子组件之间的通信是通过 props 传递。从父向子单向传递;而如果子组件想要在父组件作用里面产生副作用,就需要去派发事件。这样就形成一个基本的父子通信模式,在涉及大规模状态管理的时候会有额外的方案,这个后面会提到。
组件+构建工具==> 单文件组件概念
在同一个Vue文件里,可以同时写 template, script 和 style,三个东西放在一个里面。这样的好处是有了一个构建的机会,可以对这些单文件组件做更多的分析处,在每一个语言块里可以单独使用不同的处理器
以上参考
http://blog.csdn.net/generon/article/details/72482844
https://www.cnblogs.com/caizhenbo/p/6418284.html
https://www.tuicool.com/articles/6nEjAjb
https://cn.vuejs.org/v2/guide/reactivity.html