medium.com/swlh/what-y… 原文连接html
如今 VueJS 是最热的框架之一,它在2019的周下载量翻了一倍。vue
2020年Vue3发布时,它将更加流行。react
如今Vue团队的重点在使它可以适合全部开发者,新版本将更强大、更有效率。同时有不少的内部优化将让咱们用的更爽。git
Vue3也给开发者更多的控制方法(若是你想要),它让咱们可以使用直接暴露的Vue响应式API准确控制咱们项目,编写自定义编译和渲染方法。github
下面是一些重大变化,来自尤雨溪的几回演讲和RFC(request for comments)Github 仓库api
响应式是VueJS的核心,它须要数据有依赖,观察、更新数据来反应任何变化。数组
Vue2使用 Object.defineProperty 去建立getters 和 setters 实现响应式。缓存
使用 Object.defineProperty 这里有两个主要的问题,事实上,他们足够了,甚至在官方文档中也提到了框架
// 经过下标设置数组元素 - 非响应式
vm.items[itemOfItem] = newVal
// 修改数组长度 - 非响应式
vm.items.length = newLength
复制代码
Vue3的解决方案是基于 Proxy 的观察者,避免了原来的功能限制。异步
老版本和新版本的关键区别,Vue2中Object.defineProperty改变原始数据可是Proxy没有。它使用虚拟化的目标数据,设置不一样的处理方法来监听数据的getters和setters。
这个新的方式意味着响应式属性可以在不使用vm.$set的状况下添加、删除属性。它也消除了Vue2中关于数组的无效极端状况。
根据尤雨溪在 Medium Post的最好的总结,基于Proxy的观察者可以支持一下方面:
在VueMaster有一份关于如何实现基于Proxy的观察者的很棒的总结。
在Vue3中这是迄今为止最著名的变化,它可以帮助咱们组织、重用代码。
如今若是你在工做中使用Vue,你应该应该用过 Options Api,Options API经过:data、computed、methods等等属性来组织咱们的代码。
这是一个很是直观的系统,吸引了成千上万的人尝试VueJS,可是它让维护一个巨大的组件很是困难。针对一个功能的代码被分散到几个地方,每一个地方相隔数百行。
可维护性、可读性变成了主要的问题
让咱们看下 Composition API 是如何工做的。
import { reactive, computed } from 'vue'
export default {
setup(){
// vue composition api 暴露vue的核心响应式能力
let state = reactive({
input: '',
groceries: [],
groceriesLeft: computed(() => groceries.length)
});
function addGrocery() {
state.groceries.push(state.input);
state.input = '';
}
function deleteGrocery(index) {
state.groceries,splice(index, 1);
}
return {
state,
addGrocery,
deleteGrocery
}
}
}
复制代码
让咱们逐步分解发生了什么
import { reactive, computed } from 'vue'
复制代码
Vue Composition API暴露了Vue中的不少核心能力,好比响应式、组件方法,因此咱们来引入他们。
export default {
setup() {
复制代码
setup方法是Vue3中最大的变化之一,本质上,它可以让咱们肯定将哪些传递给模板,不管返回什么均可以在模板中访问。
咱们可以设置响应式数据、生命周期钩子、计算属性、定义方法,返回任何咱们想要的东西。
let state = reactive({
input: '',
groceries: [],
groceriesLeft: computed(() => groceries.length)
});
复制代码
经过将全部数据包装在响应式方法里,内部全部的都变成了响应式的。这个状态模式来自 Composition API 文档。
一个值得注意的是咱们声明 groceriesLeft 变量的方式,你能看到,它是一个计算属性,而且定义在setup方法中。再也不有分开声明的计算属性了。
function addGrocery() {
state.groceries.push(state.input);
state.input = '';
}
function deleteGrocery(index) {
state.groceries,splice(index, 1);
}
复制代码
这是典型的函数,惟一独特的事咱们须要经过状态对象访问全部定义在状态对象中的响应式数据。可是这不是Vue3特有的,它就是普通JavaScript对象。
return {
state,
addGrocery,
deleteGrocery
}
复制代码
最后,咱们想要在setup方法返回这些函数,这让属性和方法可以在模板中被访问。谢天谢地,模板还和原来同样,没啥变化。
第一次据说这些时,有不少反对声音,由于人们不想被迫从新考虑他们的开发策略。然而咱们据说这将是纯净的添加,人们仍然能够没有任何问题的使用Options API。
若是你想上手实践一下,你能够在你的项目中使用 Vue Composition API
Suspense是React的功能,如今Vue3中也能使用。它能让你在页面准备好且页面载入完成后,在你的组件中展现后备内容。
当你在setup方法中异步载入内容是颇有用的。看一下Vue-Next仓库,看起来setup是一个异步方法而且返回Promise。这个Promise可以被Suspense组件捕获,渲染后备内容直到它返回。
Suspense可以用来:
这可能实现起来很简单,你要作的所有就是将你的代码包裹在Suspense组件中,定义你的主要内容和后备内容。
<Suspense>
<template >
<Suspended-component />
</template>
<template #fallback>
Fallback Content
</template>
</Suspense>
复制代码
若是你想了解更多关于Suspense的内容,或者你想使用它,查看VueSchool 文章
片断(Fragments)是没有根元素的组件。Vue2中,每个组件必须有且仅能有一个根元素。
这可能让人头疼。
在一些用例中,使一个组件返回几个子元素是很简单的事情。例如,让咱们用React举个例子,表格结构有一个叫Column的自定义组件。
<table>
<tr>
<Columns />
</tr>
</table>
复制代码
为了是编译的HTML有效,Columns组件须要返回元素。可是目前,做为Vue的组件须要一个单独的根元素。
Columns组件的模板可能像这样,这会引发问题。
<div>
<td>Hello</td>
<td>World</td>
</div>
复制代码
这个时候片断(Fragments)就派上用场了,它容许你返回多个元素从而让上面的问题可以很简单的解决。
在Vue3中片断(Fragments)组件可能像下面这样。
<Fragment>
<td>Hello</td>
<td>World</td>
</Fragment>
复制代码
而后,由于这将返回两个元素,因此表格将显示正常。
<table>
<tr>
<td>Hello</td>
<td>World</td>
</tr>
</table>
复制代码
完美!
如今,有一个非官方的Vue 片断(Fragments)组件库,它使用内部指令获取了组件的全部子元素而后移动到合适的位置。
Portals 是React原生包含的另外一个功能,如今计划在Vue3中实现。
Portals 容许你跨组件传递内容,这意味着你可以在当前组件的做用域以外编辑内容。
当你在向popup、sidebar或者其余相似组件发送内容时这是很是有帮助的。
和片断(Fragments)同样,也有一个非官方的Vue版本 Portal 库,它在Vue2中带来了这个功能。根据 vue-next repo,Portals将包含在Vue3中。
这是一个来自 protal-vue 文档中的举例的代码截图。
<template>
<div> <div> <p> 下面的内容渲染在PortalVue实现的右侧红色的容器中 </p> <Portal to="right-baisc"> <p class="red"> 这是左侧绿色容器的内容。 最酷的是,他可以跨组件,因此你可以向任何地方传递内容。 </p> <Portal> </div> </div> </template> 复制代码
Vue3中Portals的语法和使用方式如今任然不明确,可是应该会和这个类似。
Vue3中很大一块工做就是使它更快、更有效率。实际上,根据尤雨溪在多伦多VueConf上的演讲,内部测试代表模板样式在Vue3中比Vue2速度提高了120%。
有两个关键的优化帮助提高了Vue3的渲染速度:
让咱们详细说说上面的两点。
使用虚拟DOM渲染有一个天然的瓶颈,由于每一个组件要跟踪本身的依赖。
观察这些依赖很是慢,由于它递归的检查整个元素树去监测变化。
Vue团队注意到在组件中的一件事,一个节点结构中大多数是静态的。若是一个某个部分其实是动态的(由于v-if或者v-for指令),那么它内部的许多内容时静态的。
由此,Vue3将模板划分为静态和动态部分。如今渲染器知道哪些节点是动态的,它不会浪费时间去检查静态节点的变化。
这真的减小了大量须要去被动观察的元素的数量。
结合全部的节点去建立一个块级树,或者一个模板根据指令(v-if/v-for)划分为节点块。
在块级树中,每一个节点有如下:
这消除了须要去递归的检查每一个元素的需求,大大改善了运行时。
静态树提高并非新提出的(Vue2中已经存在),Vue3有更多颠覆性(aggressive ^_^)技术去提高项目速度。正如名字说表达,静态书提高不会从新渲染没有任何依赖的静态节点。相反,它会重用相同节点。
这极大的减小了虚拟DOM的工做,同时节省了大量项目开销,主要是垃圾收集方面。
在Vue3中,静态缓存更有颠覆性,以便尽量高效的工做。
另外一个变化是,Vue的代码库使用Typescript从新写了一遍。再次重申,一个主要的问题是强制用户学习Typescript将提升Vue3的上手门槛。
因此Vue团队让他对咱们来讲很简单,若是你想要Typescript,使用他。若是你不想要,仍然可使用JavaScript。两种均可以。
若是你像我同样,你可能会问“为何用Typescript”。
先不说其余,Typescript容许你给变量添加类型信息。这可以极大的帮助你维护一个长期运行的项目。
再者,当你工做的IDE支持Typescript,在开发过程当中可以自动补全和展现类型信息。
这都有你决定,事实上使用Typescript写Vue库开发者将受益,即便他们继续使用JavaScript。
自重新的Vue代码库使用Typescript,即便你使用JavaScript,自动补全、类型信息和最终文档都可以从IDE中获得。这将节省你屡次访问Vue文档的时间。
如今,VueJS已经很是小(gzip后20Kb),可是Vue团队面临一个问题,不管用户是否使用,新功能将增长构建包的大小。
为了修复这个问题,Vue3将更加模块化。固然这将增长你在开发时import的次数,这确保了你的项目中没有不使用的库。
多亏了Tree shaking(消除非重要代码),Vue3中减小的代码大概有gzip后10Kb。固然,许多库将被从新引入,可是不要紧,咱们并不会被强迫使用全部东西。
实际上,开发者不用为他们从不使用的功能付出代价。
老实说,我认为Vue核心团队在听取社区反馈上和经过官方文章提供不断的更新一些学习Vue3的最佳地方这点作的很棒。
在写这篇文章时,我花了大量时间在RFC(Request For comment)和 Vue-next(官方Vue3)仓库。
Vue Mastery —— Vue 3 Essentials —— 这是一个很棒的课程介绍了Vue3的一些关键功能,例如 Composition API
vuejsdevelopers.com/ —— 我最喜欢的一个VueJS社区,有许多很棒的教程
“Vue 3.0 的设计原则” —— 这个演讲中,做者尤雨溪讨论了许多Vue 3.0 的设计选项。讲的很棒。
若是你有Vue开发经验,很明显,Vue3将要到来的更新将使它更可用、更强大。
从渲染优化到帮助开发者写更可读、可维护的代码,Vue3彷佛要改善Vue2在体验上的不少痛点。
但愿这篇文章很好地解释Vue3的变化和如何工做。在Vue3官方推出以后,我将必定会更新这篇文章。
感谢你阅读到这里,翻译的很差的地方,还请指点。但愿个人内容能让你受用,再次感谢。by llccing 千里