Vue简史

题记

“谁掌握了过去,谁就掌握了将来”——乔治.奥威尔javascript

前言

发端于2013年的我的项目,已然成为全世界三大前端框架之一,在中国大陆更是前端首选。html

它的设计思想、编码技巧也被众多的框架借鉴、模仿。前端

学习研究Vue的演进,对于前端同窗来讲,是提升自身认识和水平的法门。vue

纪略

Ø 2013年,在Google工做的尤雨溪,受到Angular的启发,从中提取本身所喜欢的部分,开发出了一款轻量框架,最初命名为Seed。java

Ø 同年12月,这粒种子发芽了,改名为Vue,版本号是0.6.0。react

Ø 2014.01.24,Vue正式对外发布,版本号是0.8.0。git

Ø 发布于2014.02.25的0.9.0,有了本身的代号:Animatrix,这个名字来自动画版的《骇客帝国》,此后,重要的版本都会有本身的代号。es6

Ø 0.12.0发布于2015.06.13,代号Dragon Ball(龙珠),这一年,Vue迎来了大爆发,Laravel 社区(一款流行的 PHP 框架的社区)首次使用 Vue(我也是在这个论坛上认识Vue的),Vue在JS社区也打响了知名度。github

Ø 1.0.0 Evangelion(新世纪福音战士)是Vue历史上的第一个里程碑。同年,vue-router(2015-08-18)、vuex(2015-11-28)、vue-cli(2015-12-27)相继发布,标志着 Vue从一个视图层库发展为一个渐进式框架。不少前端同窗也是从这个版本开始成为Vue的用户。vue-router

Ø 2.0.0 Ghost in the Shell(攻壳机动队)是第二个重要的里程碑,它吸取了React的Virtual Dom方案,还支持服务端渲染。

Ø 就在不久前,Vue发布了2.6.0 Macross(超时空要塞),这是一个承前启后的版本,由于在它以后,3.0.0也呼之欲出了。

1.0

Vue最初的目标是成为大型项目的一个良好补充。设计思想是一种“渐进式框架”,淡化框架自己的主张下降框架做为工具的复杂度,从而下降对使用者的要求。

相较于以前的版本,1.0的主要改进点是:

1. 提供指令的缩写

针对v-bind和v-on提供缩写形式:

<!-- full syntax -->
<a v-bind:href="url"></a>
<!-- shorthand -->
<a :href="url"></a>

<!-- full syntax -->
<button v-bind:disabled="someDynamicCondition">Button</button>
<!-- shorthand -->
<button :disabled="someDynamicCondition">Button</button>复制代码

<!-- full syntax -->
<a v-on:click="doSomething"></a>
<!-- shorthand -->
<a @click="doSomething"></a>复制代码

2. 清理精简所提供的接口

此时Vue的目标仍是但愿做为轻量级框架,成为大型项目的补充(这些大型项目也许已经有本身的前端框架了,如Angular)。

首先清理的固然是那些基本不用的API。

3. 提升初始化的渲染效率

将v-repeat指令换成了v-for指令。同时优化了这个指令的渲染,效率提高了一倍。

4. 两个官方工具的加强:vue-loadervueify

除了这些,咱们还知道,Vue中数据绑定采用的是数据劫持的方式,使用Object的defineProperty方法。和当时主流的Angular使用的事件触发的脏检查是不一样的。


这类作法将开发者与直接的DOM操做隔离开来,使得开发者可以更专一于业务逻辑,同时也改变了开发者的思惟方式。

2.0

2016年10月1日发布的2.0版本对Vue作了大幅度的重构,性能有了很大的提升,也为往后的跨端发展打下了基础。

1. Virtual DOM

在1.0的时候,Vue和Angular同样,都是把template扔给浏览器解析渲染,而后遍历DOM树,提取节点,绑定数据。

用过1.0版本的同窗可能还有印象,若是你使用了Moustache语法来展现内容,会在页面上看到一闪而过的”{{…}}”

2.0借鉴了React的作法,先将template编译为render函数,render函数返回Virtual DOM对象,而后再交由patch函数,调用浏览器接口,渲染出DOM。

Virtual DOM并不能保证渲染效率必定高于直接调用原生DOM接口(例如innerHTML),还须要配合diff,尽可能缩小刷新的范围。

除了渲染效率,这种作法还为Vue可以扩展到多端打下了基础。Virtual DOM实际上可视为一种通用的数据格式,若是小学生能看懂VDOM的话,你可让他们在操场上用团体操摆出个网页来

2. Render函数

前面已经提到了Render函数的做用,这里再也不赘述。不过我以为Render函数最大的意义在于:

a) 经过Vue提供的构建工具,将template的编译从运行时放到了编译时,提升了运行时的效率

b) 能够只使用Vue的runtime版本,减少文件体积。

3. 服务端渲染

服务端渲染的目的主要有两点:

a) 更好的SEO,因为搜索引擎爬虫抓取工具能够直接查看彻底渲染的页面。

b) 更快的首屏渲染速度。特别是对于网路速度慢或者运行缓慢的设备,无需等待全部的js都下载和解析完成才渲染页面,而是在服务端渲染好直接发送给客户端渲染页面。


2.6

在2.6发布以前的很长一段时间,Vue核心团队都在忙着vue-cli3.0的开发,积攒了很多需求,一直到2019.02.04,发布了2.6版本。

这个版本主要的改动涉及:语法更新,性能提高,以及向计划中的3.0靠拢。

1. slot语法更新

提供了一个新的指令:v-slot,用来代替slot组件,以统一slot和scoped slot。

2. 异步错误处理

和2.5相比,errorCaptured 钩子和全局的 errorHandler 配置项如今也会处理 v-on 侦听函数中抛出的错误了。另外,若是组件的生命周期钩子或事件handler中有异步操做,那么能够经过返回一个 Promise 的方式来让 Vue 处理可能存在的异步错误。

3. 动态指令参数

参看官网的例子,如今指令的参数能够是动态值,若是参数值为 null,则绑定和监听器会被移除。

<!-- full syntax -->
<a v-bind:href="url"> ... </a>

<!-- shorthand -->
<a :href="url"> ... </a>

<!-- shorthand with dynamic argument (2.6.0+) -->
<a :[key]="url"> ... </a>复制代码

<!-- full syntax -->
<a v-on:click="doSomething"> ... </a>

<!-- shorthand -->
<a @click="doSomething"> ... </a>

<!-- shorthand with dynamic argument (2.6.0+) -->
<a @[event]="doSomething"> ... </a>复制代码

4. 编译器警告位置信息

2.6 版本开始,大多数模板编译警告消息如今都带有源码位置信息:


5. 显式建立独立的响应式对象

2.6 引入了一个新的全局 API,能够用来显式地建立响应式对象

constreactiveState =Vue.observable({  count:0})复制代码

生成的对象能够直接用在计算属性和 render 函数中,在被改动时触发相应的更新。

6. 新 ES 模块构建,可直接导入使用

<script type="module">
import Vue from 'https://unpkg.com/vue/dist/vue.esm.browser.js'
  
new Vue({
  // ...
})
</script>复制代码

7. 让 nextTick 恢复使用 Microtask

在 2.5 版本中,开发团队作出了一个内部调整:若是更新是在 v-on 事件处理程序中触发的,则会致使 nextTick 使用 Macrotask(而不是 Microtask)来让更新进入队列。最初这么作是为了修复一些浏览器的边界状况,但反过来又致使了不少其余问题。在 2.6 版本中,开发团队为原始问题找到了一个更简单的修复方案,这样咱们就能够在任何状况下恢复 nextTick 使用 Microtask。

8. this.$scopedSlots 函数统一返回数组

在 render 函数中,scoped slot 经过 this.$scopedSlots 暴露为函数。在以前版本,调用 scoped slot 函数会根据父组件传入内容返回单个 VNode 或 VNode 数组。这种设计其实是一种疏忽,由于它返回值的类型不肯定,可能会致使意外的边界状况。

在 2.6 版本,scoped slot 函数确保只返回 VNode 数组或 undefined。

3.0

3.0是很是大的重构,源码使用TypeScript重写,而且还有许多使人期待的新特性:

1. Virtual DOM彻底重构

编译器承担了更多的责任,将以前一些在runtime时作的工做挪了过来:

a) 组件快速路径+单一类型+子类型检测:


b) 优化slot的编译,避免无谓的父/子节点重渲染

普通的 slot 是在父组件的渲染函数中生成的,所以当一个普通的 slot 所依赖的数据发生变化时,首先触发的是父组件的更新,而后新的 slot 内容被传到子组件,触发子组件更新。

相比之下,scoped slot 在编译时生成的是一个函数,这个函数被传入子组件以后会在子组件的渲染函数中被调用。这意味着 scoped slot 的依赖会被子组件收集,那么当依赖变更时就只会直接触发子组件更新。

c) 静态内容和静态属性提取

当编译器发现这些静态属性的时候,就会直接提取这部分的静态属性做为实例属性的一部分,在后面的数据比较中直接忽略这部分静态属性,以提高性能。


d) 内联事件函数的提取

2. 使用Proxy代替defineProperty

defineProperty监听不到对象属性的增删、数组元素和长度的变化,同时会在vue初始化的时候把全部的Observer都创建好,才能观察到数据对象属性的变化。

而proxy能够作到监听对象属性的增删和数组元素和长度的修改,还能够监听Map、Set、WeakSet、WeakMap,同时还实现了惰性的监听,不会在初始化的时候建立全部的Observer,而是会在用到的时候才去监听。

3. 使用TypeScript重构

由于Flow烂尾了,而TypeScript又愈来愈好。

4. 自定义的Renderer API

这一点是为了向多端扩展,咱们知道,如今Weex适配Vue采起的是fork的方式。3.0以后,这些native的适配层就能够经过自定义渲染器的方式来扩展了。

5. 支持Time Slicing

目前时间切片还处于实验阶段。

Vue运行在浏览器的主线程,若是运行了一个很是耗费时间的操做,那么浏览器会中止对用户操做的响应,直到计算完毕。显然这种用户体验是很是糟糕的,用户还觉得浏览器已经挂掉了。在有了Time Slicing支持后,Vue将会限制本身的执行时间,只在一个时间片断内运行,这个时间片断被称为“帧”,默认状况下一帧的时间是16ms,对于小型计算任务来讲基本足够了,而一秒钟能够运行62.5帧,有60帧左右的刷新率,浏览器对用户的响应将会是比较顺滑的了。

参考资料

维基百科:Vue.js

State of Vue.js report 2017 中文版

vuejs.org/2015/10/26/…

Vue 2.0 is Here!

The Progressive Framework

Vue2.0 中,“渐进式框架”和“自底向上增量开发的设计”这两个概念是什么?

Vue做者尤雨溪:Vue 2.0,渐进式前端解决方案

javascript实现数据双向绑定的三种方式

网上都说操做真实 DOM 慢,但测试结果却比 React 更快,为何?

Vue 服务端渲染技术

ES6入门:Proxy

ES6入门:Reflect

ES6黑科技实践--proxy,reflect

VUE3.0的这些改进你会期待吗

全面改革:解读 Vue 3.0 的变化

实现双向绑定Proxy比defineproperty优劣如何

Time Slicing Demo

如何评价React的新功能Time Slice 和Suspense?

学习React Fiber架构,理解如何实现时间分片(Time Slicing)和 Suspense.

彻底理解React Fiber

扩展阅读

中译名

一句话介绍

Animatrix

骇客帝国动画版

锡安究竟是不是真的

Blade Runner

银翼杀手

影史最佳科幻片,催生了赛博朋克这一科幻流派的产生

Cowboy Bebop

星际牛仔

由于东京电视台单方面认为动画存在较大的尺度问题而并无让这部动画如期播完。

Dragon Ball

龙珠/七龙珠

鸟山明的表明做

Evangelion

新世纪福音战士

日本动画史上的里程碑,被公认为日本历史中最伟大的动画之一

Ghost in the shell

攻壳机动队

故事设定在2029年,快来了

Hunter x Hunter

全职猎人

连载二十年,休刊无数次

Initial D

头文字D

仍是周杰伦演的好看

JoJos Bizarre Adventure

JOJO的奇妙冒险

我尽可能避免战斗,可是我从不逃避

Kill la Kill

斩服少女

Level E

灵异E接触

开启了富坚义博休刊习惯的罪恶之源

Macross

超时空要塞

作工精良的精品

相关文章
相关标签/搜索