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也在代码中使用了,具体用法请看注释(后面不再详细讲解)

生命周期的使用

生命周期命名改变了更有语义化了,使用方法也改变,使用前需要我们在组合Api里获取。



vue 3初体验以及和vue 2的区别_第1张图片
虽然代码顺序打乱,但是执行顺序还是和以前一样的

组件Api的使用

setup

setup替代了以前的 beforeCreate 和 created ,类似于初始化的功能

//props 接收的父组件传的参数,这就有点像react的props了
//ctx 这个参数表示的当前对象实例,也就个是变相的this
setup(props,ctx){
 console.log(props.msg, ctx);
}

props为父组件传过来的参数,ctx为组件上下文
vue 3初体验以及和vue 2的区别_第2张图片
如果你还想要更多当前组件相关的属性,还可以从组合Api 里引用 getCurrentInstance

     import {getCurrentInstance } from "@vue/composition-api";
     const  all  = getCurrentInstance()
     console.log(all);

vue 3初体验以及和vue 2的区别_第3张图片

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 = 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迁移

你可能感兴趣的:(vue)