vue 3初体验以及和vue 2的区别

前言 经过了漫长的迭代,Vue 3.0终于在上2020-09-18发布了,带了翻天覆地的变化,使用了Typescript 进行了大规模的重构,带来了Composition API RFC版本,类似React Hook 一样的写Vue,可以自定义自己的hook ,让使用者更加的灵活,接下来总结一下vue 3.0 带来的部分新特性以及和vue 2.0的区别在哪里
vue 3的新特性

1,setup() 2,ref 、toRef、 toRefs 3,reactive() 4,computed() 5,watch、watchEffect 6,函数组件 7,other

vue 3 和vue 2的区别 1,生命周期的变化
Vue2.x Vue3
beforeCreate 使用 setup()
created 使用 setup()
beforeMount onBeforeMount
mounted onMounted
beforeUpdate onBeforeUpdate
updated onUpdated
beforeDestroy onBeforeUnmount
destroyed onUnmounted
errorCaptured onErrorCaptured
整体来看其实变化不大,使用setup代替了之前的beforeCreate和created,其他生命周期名字有些变化,功能都是没有变化的
2,使用proxy代替defineProperty 我们知道vue 2双向绑定的核心是:Object.defineProperty()。但是vue 2对数组对象的深层监听无法实现,因为组件每次渲染都是将data里的数据通过defineProperty进行响应式或者双向绑定上,之前没有后加的属性是不会被绑定上,也就不会触发更新渲染。我们看下语法
Object.defineProperty( Obj, 'name', { enumerable: true, //可枚举 configurable: true, //可配置 // writable:true, //跟可配置不能同时存在 // value:'name',//可写死直 get: function () { return def }, set: function ( val ) { def = val } } )

我们再来看下Proxy的语法
//两个参数,对象,13个配置项 const handler = { get: function(obj, prop) { return prop in obj ? obj[prop] : 37; }, set:function(){ }, ...13个配置项 }; const p = new Proxy({}, handler); p.a = 1; p.b = undefined; console.log(p.a, p.b); // 1, undefined console.log('c' in p, p.c); // false, 37

我们可以明显的看出defineProperty只能响应首次渲染时候的属性,而Proxy需要的是整体,不需要关心里面有什么属性
备注:defineProperty兼容到IE8,其他浏览器会有些许问题,但是Proxy除了IE,其他浏览器全部兼容,其实IE应该基本没人用了。
3,Diff算法的提升 vue 2提供类似于HTML的模板语法,它是将模板编译成渲染函数来返回虚拟DOM树。Vue框架通过递归遍历两个虚拟DOM树,并比较每个节点上的每个属性,来确定实际DOM的哪些部分需要更新所以会出现DOM的更新仍然涉及许多不必要的CPU工作
vue3对这个问题进行了3个方面的优化:

首先,在DOM树级别。我们注意到,在没有动态改变节点结构的模板指令(例如v-if和v-for)的情况下,节点结构保持完全静态。如果我们将一个模板分成由这些结构指令分隔的嵌套“块”,则每个块中的节点结构将再次完全静态。当我们更新块中的节点时,我们不再需要递归遍历DOM树 - 该块内的动态绑定可以在一个平面数组中跟踪。这种优化通过将需要执行的树遍历量减少一个数量级来规避虚拟DOM的大部分开销

其次,编译器积极地检测模板中的静态节点、子树甚至数据对象,并在生成的代码中将它们提升到渲染函数之外。这样可以避免在每次渲染时重新创建这些对象,从而大大提高内存使用率并减少垃圾回收的频率。

在元素级别。编译器还根据需要执行的更新类型,为每个具有动态绑定的元素生成一个优化标志。例如,具有动态类绑定和许多静态属性的元素将收到一个标志,提示只需要进行类检查。运行时将获取这些提示并采用专用的快速路径。
总结:这些技术大大改进了我们的渲染更新基准,Vue 3有时占用的CPU时间不到Vue 2的十分之一
4,typeScript的支持 vue3 借鉴了react hook实现了更自由的编程方式,提出了Composition API,Composition API不需要通过指定一长串选项来定义组件,而是允许用户像编写函数一样自由地表达、组合和重用有状态的组件逻辑,同时提供出色的TypeScript支持
解决了vue2.没有类型系统这个概念以及对于规模很大的项目,没有类型声明,后期维护和代码的阅读都是头疼的事情。
5,打包体积的变化 vue2:运行时打包是23k,但这只是没安装依赖的时候,随着依赖包和框架特性的增多,有时候不必要的,未使用的代码文件都被打包了进去,所以后期项目大了,打包文件会特别多还很大。
vue3: 通过将大多数全局API和内部帮助程序移动到Javascript的module.exports属性上实现这一点。这允许现代模式下的module bundler能够静态地分析模块依赖关系,并删除与未使用的module.exports属性相关的代码。模板编译器还生成了对树抖动友好的代码,只有在模板中实际使用某个特性时,该代码才导入该特性的帮助程序。
尽管增加了许多新特性,但Vue 3被压缩后的基线大小约为10 KB,不到Vue 2的一半
6,其他API和功能的改动 注释:这些小改动就不做更细的说明,只列举下。 详细使用看vue2的迁移部分
vue3整体梳理 组件基本结构分析

!!!computed也在代码中使用了,具体用法请看注释(后面不再详细讲解)
生命周期的使用 【vue 3初体验以及和vue 2的区别】生命周期命名改变了更有语义化了,使用方法也改变,使用前需要我们在组合Api里获取。

vue 3初体验以及和vue 2的区别
文章图片

虽然代码顺序打乱,但是执行顺序还是和以前一样的
组件Api的使用 setup
setup替代了以前的 beforeCreate 和 created ,类似于初始化的功能
//props 接收的父组件传的参数,这就有点像react的props了 //ctx 这个参数表示的当前对象实例,也就个是变相的this setup(props,ctx){ console.log(props.msg, ctx); }

props为父组件传过来的参数,ctx为组件上下文
vue 3初体验以及和vue 2的区别
文章图片

如果你还想要更多当前组件相关的属性,还可以从组合Api 里引用 getCurrentInstance
import {getCurrentInstance } from "@vue/composition-api"; constall= getCurrentInstance() console.log(all);

vue 3初体验以及和vue 2的区别
文章图片

ref 、toRef、 toRefs
import { ref , toRef , toRefs } from '@vue/composition-api' setup(){ const obj = {age:12} //初始化设置个响应式变量tor,函数中读取值要tor.value let tor = ref(0) //这里将对象转化成响应性,并设置key值,函数中读取值要toR._object let toR = toRef(obj,'toR') const state = reactive({ num:1, name:'baby张' }) return { tor, roR, //toRefs针对的是使用了reactive的响应式对象,可以理解为将对象拆分成多个ref并进行双向绑定,外界可以读取到响应式的所有属性 ...toRefs(state) } }

ref 就当作简单的双向绑定变量 toRef 就是把不是响应式的对象转化成响应式 toRefs 就是把响应式的reactive对象,分解成无数的 ref 双向绑定
备注:ref 双向绑定的数据,在函数里读取的时候需要 .value获取 2. dom里不需要我们+value 框架替我们自动解构了 3. 组件return的时候将 reactive的对象 toRefs ,可以使代码更简洁,又不会丢失双向绑定
reactive
1,reactive 内部是可以使用计算属性等各种方法,它只是把数据双向绑定了而已
2,reactive 后return 的数据最好是用toRefs 转化一下
3,跟 ref 混合使用时候可以用isRef 判断类型
watch、watchEffect
//这里的watchEffect只要里面的变量发生了改变就会执行,并且第一次渲染会立即执行,没有变化前后返回参数,无法监听整个reactive watchEffect(() => { refnum.value = https://www.it610.com/article/state.count; console.log(state,"watchEffect"); s }); //watch里第一个参数是监听需要的变量,第二个是执行的回调函数, watch(refnum,(a,b)=>{ console.log(a,b,'watch,a,b') })

1.watch 需要具体监听参数,watchEffect 不需要传入监听参数
2.watch 的回调函数跟以前一样有前后对比的参数,watchEffect 啥都没有
3.watch 只有监听属性变化才执行,watchEffect 第一次会立即执行
4.watch 和 watchEffect 都无法监听未被双向绑定的属性
5.watch 可以直接监听 ref 和 reactive 绑定的对象,watchEffect 不可以(ref的值要.value,reactive的值要具体到内部属性),只会执行第一次
Typescript的支持 TS的支持也是Vue3的重中之重,在vue2版本ts里应该好多人用过vue-property-decorator 或者Facebook的Flow,来写vue里的TS,有些装饰器器和属性也比较难以理解,比如:@Emit @Inject @Provice @Prop @Watch @Model Mixins 都需要一些学习,才能下手
Other 面我主要在大的方向给大家做了介绍,其实还有好多细节的改动。请移步
一步组件、指令、solt、过度class…更多更改看官网Vue2迁移

    推荐阅读