事关我对于Vue3的理解

318 阅读4分钟

Vue2与vue3的异同

写在前面:这是最近在学习TS+vue3的一些文档知识总结以及概括和一些个人理解,用来区别vue2和vue3的一些明显区别.

重点

1.Object.defineproperty => Proxy(更完善的响应式)

2.Option API => Composition API(更清晰的页面逻辑)

3.Vite(新的脚手架工具)

4.TypeScript(更好的支持TS)


具体

1. hooks(函数钩子)

  • 生命周期
import {ref,reactive,onMounted,onUpdated } from 'vue'

//新增
setup()
//1. 可以用来替代beforCreated;
//2. 没有this,新增两个参数,props和context,props不能结构(失去响应式),context可以.
//3. 结尾需要return一个对象
    1. 返回对象中的属性会与data函数返回对象的属性合并成为组件对象的属性
    2. 返回对象中的方法会与methods中的方法合并成功组件对象的方法
    3. 如果有重名, setup优先
    4. 不能是异步函数
    
    
//- setup(props, context) / setup(props, {attrs, slots, emit})

//- props: 包含props配置声明且传入了的所有属性的对象

//- attrs: 包含没有在props配置中声明的属性的对象, 相当于 this.$attrs

//- slots: 包含所有传入的插槽内容的对象, 相当于 this.$slots

//- emit: 用来分发自定义事件的函数, 相当于 this.$emit


//修改
onMounted()
onUpdated()
onUnmounted()
//现在能多次和多处调用,按代码顺序执行.

  • 计算属性
import { computed } from 'vue'

<!-- 只有getter -->
const data = computed(() => {
    return data1 + data2;
}) 

<!-- 有getter和setter -->
const data = computed({
    getter(){
        
    },
    setter(val){
        
    },
})

  • watch监听
import { watch,watchEffect } from 'vue'

//watch与原来一样,deep实现深度监听,首次不执行,并且需要明确监听目标,有oldval和newval
    watch(user, () => {
      fullName3.value = user.firstName + '-' + user.lastName;
    },//可以不在需要写handler
    {
      immediate: true,  // 是否初始化立即执行一次, 默认是false
      deep: true, // 是否是深度监视, 默认是false
    })
    
//watchEffect直接使用就行,不需要指定,可直接传入响应式对象,没有过多的参数,只有newval
    watchEffect(() => {
        console.log(nameObj.name);
    })

  • 自定义hooks

类似vue2中的mixin,事先封装好js/ts文件,通过引入来进行使用


2.响应式数据

//简单类型
    const data = ref<string>("abc");
    //js操作数据: data.value
    //模板使用数据:{{data}}


//复杂类型(接收一个对象)
    const data = reactive({
        name: string:"张三",
        age? :21,
        child: object:{
            son:"三儿",
            daughter:"阿奴",
        }
    })
    
//使用toRefs()分解复杂类型数据
    const stateAsRefs = toRefs(data)
            ...
    return{
        ...stateAsRefs,//可以直接在模板上使用data里面的属性
    }

响应式数据的原理

  • vue2数据双向绑定: 通过数据劫持加发布者(订阅者)模式实现的",重写了Object.defineProperty的getter和setter方法从而兼容了数组常用方法。
  1. 实现一个监听器Observer,用来劫持并监听所有data里面的属性,并使用Object.definProperty把所有的属性变成getter和setter,如果有改变就通知订阅者.(核心就是Object.defineProperty)

  2. Dep是订阅器,用来在监听器Observer和订阅者Watcher之间进行统一管理,用Dep.notify()来通知Watcher.

  3. 实现一个订阅者Watcher,可以收到属性的变化通知,然后更新视图.

  4. 实现一个指令解析器Compile,对每个节点和属性进行扫描和解析,并根据初始化模板数据以及初始化相应的订阅器

  • Vue3响应式数据原理: 通过Porxy代理模式实现(暂不明白底层)

    1. Proxy(代理),拦截对data任意属性和方法的任意操作, 包括属性值的读写, 属性的添加, 属性的删除等等.

    2. Reflect(反射),动态对被代理对象的相应属性进行特定的操作

区别:观察者模式是通过遍历data里面的数据 ,手动添加getter和setter,所以某些方法添加的数据没有触发观察者也就没有响应式,代理模式是直接监听对象,只要对象改变都会触发。


3.组件传值

  • props加emit事件

和vue2类似,只是vue3缺少了this,使用this.emit()变成了setup(props,{emit}){}的形式

  • provide(导出)和inject(引入)

爷孙传值,不经过父组件,类似于vue2的provide和inject

  • vuex

推荐TS语法,定义好全局state的类型,复用的interface,type和泛型,传入action和mutation进行注解,代码更加规范,逻辑更加严谨


4.新组件

一. Fragment(片断)

指vue3的模板可以不再需要根元素,vue2的模板需要根元素进行包裹

好处: 减少标签层级, 减小内存占用

二. Teleport(瞬移)

teleport可以让我们的子组件DOM不用嵌套在父组件的DOM中,但又可以继续访问父组件的值和方法 好处: 让子组件的dom跟父组件dom在同一级,并且能使用父组件的属性和方法

三. Suspense(不确定的)

它们允许我们的应用程序在等待异步组件时渲染一些后备内容,可以让我们创建一个平滑的用户体验 好处: 就是在异步组件没加载出来的时候用来显示的过渡展示