最近一段时间,Vue3带来的新能力composition-api带来了比较大的轰动,虽然是灵感是源React Hook,可是在不少方面却超越了它。可是除了composition-api,其余的改动却比较少有人讨论,本篇文章就由vuejs/rfcs 这个仓库来看看其余比较让人振奋的RFC。html
RFC其实就是(Request For Comments)征求修正意见书,它不表明这个api必定会正式经过,可是却可让社区知道vuejs团队正在进行的一些工做,和一些新想法。vue
Vue的RFC分为四个阶段:node
Pending:当RFC做为PR提交时。react
Active:当RFC PR正在合并时。git
Landed:当RFC提出的更改在实际发行版中发布时。github
Rejected:关闭RFC PR而不合并时。segmentfault
本篇讨论的RFC都在Active阶段api
<!-- before -->
{{ msg | format }}
<!-- after -->
{{ format(msg) }}
复制代码
动机:app
过滤器的功能能够轻松地经过方法调用或计算的属性来复制,所以它主要提供语法而不是实用的价值。dom
过滤器须要一种自定义的微语法,该语法打破了表达式只是“ JavaScript”的假设-这增长了学习和实现成本。 实际上,它与JavaScript本身的按位或运算符(|)冲突,并使表达式解析更加复杂。
过滤器还会在模板IDE支持中增长额外的复杂性(因为它们不是真正的JavaScript)。
替代:
能够简单的利用method替换filter的能力,统一语法,Vue.filter全局注册的能力也能够用Vue.prototype全局挂载方法来实现。
目前有一个stage-1的提案pipeline-operator 能够优雅的实现方法组合。
let transformedMsg = msg |> uppercase |> reverse |> pluralize
复制代码
概览:
h如今已全局导入,而不是传递给渲染函数做为参数
渲染函数参数已更改,并使stateful组件和functional组件之间保持一致
VNode如今具备拉平的props结构
基本示例:
// globally imported `h`
import { h } from 'vue'
export default {
render() {
return h(
'div',
// flat data structure
{
id: 'app',
onClick() {
console.log('hello')
}
},
[
h('span', 'child')
]
)
}
}
复制代码
动机: 在2.x中,VNode是特定于上下文的-这意味着建立的每一个VNode都绑定到建立它的组件实例(“上下文”),
在2.x中,这样的一段代码:
{
render(h) {
return h('div')
}
}
复制代码
h实际上是经过render中的形参传入的,这是由于它须要关心是哪一个组件实例在调用它,在3.x中,文章中介绍说vnode将会成为context free
的,这意味着更加灵活的组件声明位置(不止在.vue文件中,不须要处处传递h参数)。
而且若是context free
真的实现,那么在2.x中Vue高阶组件的一些诟病也能够一同解决掉了,若是对context带来的高阶组件的bug感兴趣的话,能够查看HcySunYang大大的这篇文章:
segmentfault.com/p/121000001…
另外本篇中还提到了一个vnode的属性拉平,
// before
{
class: ['foo', 'bar'],
style: { color: 'red' },
attrs: { id: 'foo' },
domProps: { innerHTML: '' },
on: { click: foo },
key: 'foo'
}
// after
{
class: ['foo', 'bar'],
style: { color: 'red' },
id: 'foo',
innerHTML: '',
onClick: foo,
key: 'foo'
}
复制代码
目前看来,因为jsx最终会被编译成生成vnode的方法,这个改动可能会让vue中书写jsx变得更加容易,如今的一些写法能够看我写的这篇文章:
手把手教你用jsx封装Vue中的复杂组件(网易云音乐实战项目需求)
在这篇文章中能够看出,目前嵌套的vnode结构会让jsx的书写也变得很困难。
因为render函数的一些另外的细微变更,Vue3中理想的functional component的书写方式是这样的:
import { inject } from 'vue'
import { themeSymbol } from './ThemeProvider'
const FunctionalComp = props => {
const theme = inject(themeSymbol)
return h('div', `Using theme ${theme}`)
}
复制代码
是否是很像React,哈哈。
为了更好的支持tree-shaking
,Vue3把2.x中统一导出Vue的方式更改成分散导出,这样只有项目中用到的方法会被打包进bundle中,有效的减小了包的大小。
import { nextTick, observable } from 'vue'
nextTick(() => {})
const obj = observable({})
复制代码
简单的来讲,若是你项目中只用到了observable
和nextTick
,那么例如use
,reactive
等这些另外的api就不会被打包进你的项目中。
关于tree-shaking
,我特别喜欢的做者相学长有一篇文章能够看一下:
在这个仓库中,还有一些提案你们也能够自行去看一下,剩下的都是一些细节的优化,这些优化或多或少的会让Vue3更好用一些,很是期待Vue3的到来。
另外因为plugin的存在,我已经在2.x中用Vue3的composition-api作了一些尝鲜,不得不说真香!