vue3初了解笔记

84 阅读5分钟

defineComponent重载函数

它并没有实现任何的逻辑,只是把接收的 Object 直接返回

它的存在是完全让传入的整个对象获得对应的类型

它的存在就是完全为了服务 TypeScript 而存在的。

defineComponent函数,只是对setup函数进行封装,返回options的对象;

defineComponent最重要的是:在TypeScript下,给予了组件 正确的参数类型推断

setup

1、setup函数是处于 生命周期函数 beforeCreate 和 Created 两个钩子函数之间的函数

2、setup函数是 Composition API(组合API)的入口

3、在setup函数中定义的变量和方法最后都是需要 return 出去的 不然无法再模板中使用

Reactive

Vue 3的根基。返回对象的响应式副本,响应式转换是“深层”的——它影响所有嵌套property。返回Proxy对象,不等于原始对象。建议只操作Proxy对象,不要操作原始对象。

官方建议,对来自于服务器的数据或者注定要响应式的数据执行reactive之前,最好不要用临时变量储存原始数据,因为没有意义,而且两个变量容易让初学者引起误操作。

ref

ref说白了就是reactive({value: 原始数据})。下方代码如果打印r对象,会得到RefImpl(ref)对象,它有一个value属性指向基础类型值30

<template>

  <button @click="r++">count is: {{ r }}</button>

</template>

<script>

import { ref } from "vue";

export default {

  setup() {

    let r = ref(30);

    return {

      r,

    };

  },

};

</script>

```js

为什么似乎Proxy已经解决所有问题,还要有ref API呢?

因为ES的Proxy API是为引用数据类型服务的,它无法为基本数据类型提供代理。如果强行代理,Vue会有提示:value cannot be made reactive: 30。

那么为什么Vue2的defineproperty并没有区分基本数据类型和引用数据类型呢?

因为defineproperty就是Object的静态方法,它只是为对象服务的,甚至无法对数组服务,因此Vue 2弄了一个data根对象来存放基本数据类型,这样无论什么类型,都是根对象的property,所以也就能代理基本数据类型。

而Proxy能对所有引用类型代理,Vue 3也不再用data根对象,而是一个个的变量,所以带来了新问题,如何代理基本数据类型呢?并没有原生办法,只能构建一个{value: Proxy Object}结构的对象,这样Proxy也就能代理了。

问题来了,同样是响应式结构,ref跟reactive的区别是什么?

ref与reactive的区别

对比refreactive
返回数据类型RefImpl对象(也叫ref对象)Proxy对象
传入基本类型返回{value: 基本类型}禁止这么做
传入引用类型返回{value: Proxy对象}Proxy对象
两者分别适用场合:

ref可以为基本类型添加响应式,也可以为引用类型添加响应式,reactive只能为引用类型添加响应式。

对于引用类型,什么时候用ref,什么时候用reactive?

简单说,如果你只打算修改引用类型的一个属性,那么推荐用reactive,如果你打算变量重赋值,那么一定要用ref

使用组合式API的话,请一定了解“重赋值自身”和“重赋值自身属性”的区别

想在组合式API中让数据具备响应式,必须用ref,因为ref又对Proxy包装了一层,修改ref其实是修改它的value,它的value一定是响应式的,因此视图就正常更新了。

再多说一点,如果数据是服务器返回的LIST数据,而且只显示、不变更,那么最好是使用shallowRef来包装数据,可以节能。如果会有变更,那么应该用ref。

现在好像ref把引用数据类型也管起来了,到底啥时候才适合用reactive呢?很简单啊,如果你确信你只可能去改引用类型数据的属性,那么一定要用reactive,如果还有可能要整体重赋值,那还得用ref。

所以说:需要在组合式API里给变量重赋值的话,无论什么数据类型都必须用ref,不可以用reactive。

toRef / toRefs

toRef 和 toRefs 可以用来复制 reactive 里面的属性然后转成 ref,而且它既保留了响应式,也保留了引用,也就是你从 reactive 复制过来的属性进行修改后,除了视图会更新,原有 ractive 里面对应的值也会跟着更新,如果你知道 浅拷贝 的话那么这个引用就很好理解了,它复制的其实就是引用 + 响应式 ref

toRef 与toRefs的区别

toRefs可以看做批量版本的toRef。

toReftoRefs
用法toRef(Proxy, 'xxprop')toRefs(Proxy)
返回ObjectRefImpl对象同左
作用创建变量到Proxy属性的响应式连接创建变量每个属性到Proxy每个属性的响应式连接
连接关系一对一多对多

 

toRefs的一大用途是变相解构Proxy。首先了解一个常识,Proxy如果解构,基本数据会丢失响应式。现在我既想要解构Proxy,又不想丢失响应式,怎么办?可以使用toRefs。

为什么Vue3中声明响应式对象一般用const

因为 Vue 的响应式系统是通过属性访问进行追踪的(响应式数据对象的属性的副作用函数的订阅),因此我们必须始终保持对该响应式对象的相同引用。 防止响应式被替换丢失链接

let state = reactive({ count: 0 })
// 上面的引用 ({ count: 0 }) 将不再被追踪(响应性连接已丢失!)
state = reactive({ count: 1 })

而如果使用const进行声明的话,state不允许被重新赋值。可以用声明变量上方式响应式链接丢失。防止原响应式对象在WeakMap中失去。