Vue 的下一代版本(3.0)终于在9.18日发布正式版了,代号居然叫“One Piece”,不知海贼王粉们会作何感想... 不过终极秘宝这个定位,倒是很符合大家对这个版本的期待。去年开始,3.0版本的各种消息就一直源源不断,我只是粗略的了解了一下,只知道这个版本在性能和架构上都会有革命性的升级,因为早期的版本肯定无法直接应用到项目上,各种API和实现细节也会不断变化,我也就没有深入去了解版本升级变化的各种细节。但现在正式版已经发布了,核心生态圈的框架适配工作(vue-router 4.0,vuex4.0,Ant Design Vue 2.0等)也接近完成,现在是时候可以评估一下将3.0版本引入到实际业务开发的可行性了。
响应式机制的革新
3.0版本最重大的变化将响应式的实现机制从2.x的Object.defineProperty方式更改为使用ES2015的Proxy机制,这样不但能够提升性能,而且原来无法自动监听的对象属性的增删,数组元素和长度的变化(2.x版本需要显式调用Vue.$set方法),3.0版本可以直接自动进行监听和跟踪了。但也不是完全没有代价,Proxy在IE系列浏览器上没有被实现,所以3.0版本目前还无法兼容IE11浏览器。但似乎可以通过引入Babel-polyfill在IE11上模拟Proxy实现,这个还需要进一步确认。
Composition API
Vue 3.0现在拥有两套相互独立的组件构建方式,一个还是原来基于配置式的Option Api,代码的是通过配置项的类型来组织的,比如方法就放到methods下面,数据就放到data下面,向下面这样:
export default {
data() {
return { count: 4 }
},
created() {
this.increment();
},
methods: {
increment() {
this.count++
console.log("current count:"+this.count);
}
}
}
这套配置规则和2.x版本基本保持了一致,可以让绝大部分老用户无感的直接过渡到3.0版本。同时,为了实现对TypeScript更好的结合和支持(3.0的版本本身就是使用TypeScript开发的),并且强化组件中业务逻辑的可复用性,3.0版本还提供了一套基于类和方法的全新的Composition API,可以更加灵活的构建所需要的组件。比如把上面的例子改成Composition API的写法:
import { ref , onMounted } from 'vue'
export default {
setup(props) {
const counter = ref(0) //初始化一个响应式的数字
const increment = () => {
counter.value ++
console.log("current count:"+counter.value);
}
onMounted(increment) //这是一个生命周期方法
return {
count:counter.value,
increment
} // 这里返回的东西在整个组件中都可以通过this指针进行访问
}
// 组件的其它部分
}
其中setup是Composition API的入口函数,会在整个组件创建之前被执行。可以看出,使用Composition API我们可以完全基于编码的方式构建整个组件,并设置组件的各种特性,这样非常直观,也能很方便利用TypeScript强类型的各种好处,不像2.x版本使用TypeScript时强行利用注解来转换这么别扭。Option API中可以设置的配置项,在Composition API都能找到对应的东西,比如watch,computed,还有各种生命周期方法。不过都需要显式的import才可以使用。有几个函数需要重点关注一下:
- reactive:作用于一个对象,返回这个对象的一个响应式副本。以前只有声明在组件data配置下的属性才具备响应式特征,但通过这个新的函数我们可以给任意的数据增添响应式的特性,而且这个特性不会因为参数传递而消失。响应式转换是深度嵌套的,这个对象的任意嵌套属性也会被转换。用法如下:
const obj = reactive({ count: 0 })
obj.count ++
- ref:这个函数上面的例子也出现过,作用和reactive类似,也是为数据增加响应式特性,我的理解它更像一个包装函数,主要用于对基础数据类型(字符串,数值,布尔等等)进行封装(reactive函数无法作用于基础类型数据),返回一个引用对象,引用对象只有一个属性value,指向内部所包装的数据。如果封装的类是一个对象,则会直接使用上面的reactive函数进行嵌套转换。如果直接在template中使用ref的话,会自动进行拆箱,无需再调用value属性。用法如下:
const count = ref(0)
count.value++
- readonly:可以作用于响应式对象或普通对象,返回一个该对象的一个自读的代理对象。如果修改对象属性会失败并引发警告。
TypeScript支持:
JavaScript本身是没有编译期检查的,开发中小型应用还觉得没什么问题,但是随着项目规模的扩大,特别是后面需要重构代码的时候,修改对象的属性或者类型就需要非常小心了,稍不留意漏改了引用的地方就会引发运行错误。这个让我这种同时也使用Java这类强类型语言的人感觉非常无奈。而TypeScript主要就是解决这个问题的,TypeScript为JavaScript引入了静态类型系统,同时保留了语法上的灵活性,意味着可以在编译期提前发现更多潜在的错误,有利于开发规模更大的前端应用程序。
Vue 3.0版本本身就是使用TypeScript全新开发的,意味着对TypeScript的内置支持,不需要再像2.x版本那样需要引入第三方库才能勉强使用TypeScript的特性了。详细的变化可以参考 TypeScript Support | Vue.js
网友评论