Vue3响应式核心API 使用注意点

编程入门 行业动态 更新时间:2024-10-20 11:48:42

Vue3响应式<a href=https://www.elefans.com/category/jswz/34/1769673.html style=核心API 使用注意点"/>

Vue3响应式核心API 使用注意点

目录

  • 1,和 vue2 的对比
  • 2,核心 API 介绍
    • 1,reactive 和 readonly
    • 2,ref
    • 3,监听数据
      • watchEffect
      • watch
    • 4,判断和转换
      • 判断
      • 转换

1,和 vue2 的对比

vue2 的响应式原理通过 defineProperty 实现,vue3 通过 Proxy 实现。

但这里不讨论原理,讨论的是 vue3 新增 API 的使用和注意点。因为 vue3 将响应式 API 暴露了出来,是一套独立的数据响应式系统,和组件没有关系,这样也就能够实现单一状态管理。

  • vue2 的响应式数据放在 data(){} 中,最终会被注入到组件实例上。
  • vue3 的响应式数据,是通过暴露出的响应式API来实现的,最终通过 setup() 返回。

2,核心 API 介绍

vue3 中的响应式数据,有2种格式:

  1. reactive 返回的 Proxy 对象,可直接访问属性。
  2. refcomputed 返回的 Ref 对象,需要通过 .value 访问属性。

1,reactive 和 readonly

官网参考

先说几点重要的:

  1. 都只能用于对象类型。
  2. 返回的代理对象和原始对象不相等。
  3. vue3 为保证访问代理的一致性,对同一个原始对象调用 reactive() 会总是返回同样的代理对象,而对一个已存在的代理对象调用 reactive() 会返回其本身(下面有例子说明)。
  4. readonly 的唯一区别是返回的代理对象是只读的,修改属性会报错。

看下面的例子

import { reactive, readonly } from 'vue'const origin = { a: 1, b: 2 }
const state = reactive(origin)
console.log(state === reactive(origin)) // true 相同的代理对象
console.log(state === reactive(state)) // true 返回自身const stateOnly = readonly(state)
console.log(stateOnly === state) // falsestate.a++
console.log(stateOnly.a) // 2

虽然 stateOnly 是只读的。但因为代理的是 state,所以当 state 被修改时 stateOnly 也会被修改。

另外,stateOnly 代理–> state 代理–> { a: 1, b: 2 },所以 stateOnly !== state

简单应用

import { readonly, reactive } from 'vue'/*** 返回1个对象和2个方法,* 对象是是响应式的,不允许直接修改。只能通过提供的方法修改指定属性。* @returns Object*/
function useUser() {const userOrigin = reactive({})const user = readonly(userOrigin)const setUserName = (name) => {userOrigin.name = name}const setUserAge = (age) => {userOrigin.age = age}return {user,setUserName,setUserAge}
}const { user, setUserName, setUserAge } = useUser()console.log(user)
setUserName('下雪天的夏风')
setUserAge(18)
console.log(user)

2,ref

官网参考

可以代理任何数据,因为它是把这些数据都放到了一个对象的 .value 属性上,并返回这个对象。

注意,这个对象不是 Proxy 对象,而是 Ref 对象。区别在上面已经说明了。

如果 ref() 的参数是Proxy 对象,则直接将它放到 .value 属性上。

const state = reactive({ a: 1, b: 2 })
const stateRef = ref(state)console.log(stateRef.value === state) // true

使用 .value 的原因是,无法直接检测到普通变量的访问或修改。所以通过 gettersetter 方法来拦截对象属性的 get 和 set 操作。

ref 的大致原理如下:ref 原理参考

const myRef = {_value: 0,get value() {// 触发依赖收集,重新渲染track()return this._value},set value(newValue) {this._value = newValue// 通知依赖它的对象更新trigger()}
}

3,监听数据

watchEffect

官网参考

这个函数会立即运行,同时响应式地追踪其依赖,并在依赖更改时重新执行。

也就是说,可以同时监听多个。只要该函数中使用到的响应式数据被修改了,这个函数就会重新执行。

在 vue3 中,大多数情况下监听数据使用 watchEffect() 就够了。

watch

官网参考

watch 的使用方式和 vue2 中差别不大,和 watchEffect 的区别是:

  1. watch 默认是懒侦听,即仅在侦听源发生变化时才执行回调函数,可以指定配置项 { immediate: true }来立即执行一次。
  2. 可以获取到旧值。
  3. 可以更加明确的知道,是哪个状态的修改导致了 watch 的重新执行。

注意点:

watch 不能监听普通数据,监听来源只能是下面4种:

  1. 一个函数,返回一个值
  2. 一个 ref
  3. 一个响应式对象
  4. 由以上类型的值组成的数组

看下面的例子:

import { reactive, watch } from 'vue'const state = reactive({ a: 1, b: 2 })
watch(state.a, () => {console.log('变化了')
})state.a++ // watch 函数并不会执行。

state.a 是普通的数据,不是响应式的,所以无法监听。

import { reactive, watch } from 'vue'const state = reactive({ a: 1, b: 2 })
watch(() => state.a, () => {console.log('变化了')
})state.a++ // 变化了

如果 watch 的第一个参数是函数,则会调用该函数来收集依赖。也就是说,用到的 state.a 中的 state 是响应式数据,所以能被监听到了。

但如果是监听的是 const count = ref(0) ,就可以直接监听 count 而不使用函数的方式返回。因为传递的是对象。所以可以监听到 value 的值。

4,判断和转换

判断

API含义
isProxy判断数据是否reactivereadonly 创建的
isReactive判断数据是否reactive创建的
isReadonly判断数据是否readonly创建的
isRef判断数据是否是ref对象

转换

更多参考工具函数

1,unref()

如果参数是 ref,则返回内部值,否则返回参数本身。

val = isRef(val) ? val.value : val

2,toRefs

这个比较重要。

toRefs 会将一个响应式对象的所有属性转换为 ref 格式,然后包装到一个普通对象中返回。

看下面的例子:

import { reactive, toRefs } from 'vue'const state = reactive({ a: 1, b: 2 })
const stateRef = toRefs(state)
console.log(stateRef) // {a: refObj, b:refObj},所以将 stateRef 展开也是响应式的。
console.log(stateRef.a.value) // 1

应用

当使用方法返回的是代理对象时,可以解构而不失去响应式

import { reactive, toRefs } from "vue";// composition function
function usePos(){const pos = reactive({x:0, y:0});return pos;
}setup(){const {x, y} = usePos(); // lost reactivityconst {x, y} = toRefs(usePos()); // reactivity
}

以上。

更多推荐

Vue3响应式核心API 使用注意点

本文发布于:2023-11-16 02:41:10,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1611687.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:核心   API

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!