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
}

以上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/134047.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Texlive安装

下载4.8G的iso文件 解压 或 装载后,以管理员身份运行(.bat)文件。 运行以下两句代码进行Texlive相关升级 tlmgr option repository otan tlmgr update --self --all 运行以下三行代码,检查是否安装成功 latex -v xelatex -v pdflatex -v 如果有异常…

安全防御——三、网络安全理论知识

安全防御 一、安全防御1、网络安全常识及术语资产网络安全网络空间(Cyberspace)漏洞0day1day后门exploit攻击安全策略安全机制社会工程学APT(最新) 2、为什么会出现网络安全问题3、什么样的网络是安全的? 二、威胁模型…

基于单片机的智能扫地机设计

概要 本文主要设计一个简单的智能扫地机。该扫地机的核心控制元器件是stc89c52,具有编写程序简单,成本普遍较低,功能较多,效率特别高等优点,因此在市场上得到很大的应用。除此之外,该扫地机能够自动避开障碍…

【Java 进阶篇】JSP EL 详解

在 Java Web 开发中,JavaServer Pages(JSP)是一种强大的技术,用于创建动态 Web 应用程序。JSP 的一个关键方面是 Expression Language(EL)表达语言,它允许您在 JSP 页面中嵌入 Java 代码&#x…

关于卷积神经网络的多通道

多通道输入 当输入的数据包含多个通道时,我们需要构造一个与输入通道数相同通道数的卷积核,从而能够和输入数据做卷积运算。 假设输入的形状为n∗n,通道数为ci​,卷积核的形状为f∗f,此时,每一个输入通道都…

记CVE-2022-39227-Python-JWT漏洞

文章目录 前言影响版本漏洞分析Newstar2023 Week5总结 前言 在Asal1n师傅的随口一说之下,说newstar week5出了一道祥云杯一样的CVE,于是自己也是跑去看了一下,确实是自己不知道的一个CVE漏洞,于是就从这道题学习到了python-jwt库…

机器视觉 opencv 深度学习 驾驶人脸疲劳检测系统 -python 计算机竞赛

文章目录 0 前言1 课题背景2 Dlib人脸识别2.1 简介2.2 Dlib优点2.3 相关代码2.4 人脸数据库2.5 人脸录入加识别效果 3 疲劳检测算法3.1 眼睛检测算法3.2 打哈欠检测算法3.3 点头检测算法 4 PyQt54.1 简介4.2相关界面代码 5 最后 0 前言 🔥 优质竞赛项目系列&#x…

在MacBook上实现免费的PDF文件编辑

之前我想对PDF文件进行简单处理(比如删页面、添空白页、调整页面顺序),要么是开wps会员【花钱贵】,下载(盗版)Adobe Acrobat【macOS不好下载】,要么用福昕阅览器登陆学生账号(学校买…

[React] React-Redux 快速入门

文章目录 1.安装 Redux Toolkit 和 React Redux2.创建 Redux Store3.为 React 提供 Redux Store​4.创建 Redux State Slice5.添加 Slice Reducers 到 Store6.在 React 组件中使用 Redux State 和 Actions​7.总结 1.安装 Redux Toolkit 和 React Redux npm install reduxjs/t…

软考 系统架构设计师系列知识点之系统架构评估(8)

接前一篇文章:软考 系统架构设计师系列知识点之系统架构评估(7) 所属章节: 第8章. 系统质量属性与架构评估 第2节. 系统架构评估 8.2.2 系统架构评估方法 相关试题 7. 架构权衡分析方法(Architecture Tradeoff Analy…

常见笔试题-泛型擦除

了解泛型吗? 参考文章:https://blog.csdn.net/qq_43546676/article/details/128790980 泛型就是在编译时检查类型安全,并且不需要强制进行类型转换 泛型擦除了解吗? 泛型擦除即在编译生成的字节码中,所有声明泛型的…

KaiOS APN配置文件apn.json调试验证方法(无需项目全编)

1、KaiOS 的应用就类似web应用,结合文件夹路径webapp字面意思理解。 2、KaiOS APN配置文件源代码在apn.json, (1)apn.json可以自定义路径,通过配置脚本实现拷贝APN在编译时动态选择路径在机器中生效。 (…

集合框架:List系列集合:特点、方法、遍历方式、ArrayList,LinkList的底层原理

目录 List集合 特有方法 遍历方式 1. 使用普通 for 循环: 2. 使用增强型 for 循环(foreach): 3. 使用迭代器(Iterator): 4. 使用 Java 8 的流(Stream)API&#xff…

Softing新版HART多路复用器现支持图尔克excom和西门子ET 200iSP等远程I/O

Softing工业自动化最近升级了用于访问配置和诊断数据的smartLink SW-HT软件,现在该软件可支持访问图尔克excom和西门子ET 200iSP等远程I/O。 (smartLink SW-HT支持访问配置和诊断数据) 越来越多的新型远程I/O选择使用以太网来替代PROFIBUS连接…

系列十一、拦截器(二)#案例演示

一、案例演示 说明&#xff1a;如下案例通过springboot的方式演示拦截器是如何使用的&#xff0c;以获取Controller中的请求参数为切入点进行演示 1.1、前置准备工作 1.1.1、pom <dependencies><!-- spring-boot --><dependency><groupId>org.spring…

cstring函数

string 1.char str[]类型 fgets(s,10000,stdin) cin.getline(cin,10000) strlen(str) sizeof 求静态数组长度 2.string类型 getline(cin,a) cin.getline(cin,10000) str.lenth() str.size() cin 遇到空格就停止 3.gets 函数 char str[20]; gets(str); 4.puts 函…

分享一下怎么做小程序营销活动

小程序营销活动已经成为现代营销的必备利器&#xff0c;它能够帮助企业提高品牌知名度、促进产品销售&#xff0c;以及加强与用户的互动。然而&#xff0c;要想成功地策划和执行一个小程序营销活动&#xff0c;需要精心设计和全面规划。本文将为您介绍小程序营销活动的策划和执…

OpenSign 开源 PDF 电子签名解决方案

OpenSign 是一个开源文档电子签名解决方案&#xff0c;旨在为 DocuSign、PandaDoc、SignNow、Adobe Sign、Smartwaiver、SignRequest、HelloSign 和 Zoho Sign 等商业平台提供安全、可靠且免费的替代方案。 特性&#xff1a; 安全签名&#xff1a;利用最先进的加密算法来确保…

easyHttp -- 轻量级的 HTTP 客户端工具包

easyHttp gitte地址:easy-http 介绍 easyHttp 是一个轻量级的 HTTP 客户端工具包&#xff0c;专为 Java 设计&#xff0c;使得基本的 HTTP 请求变得异常简单。该库主要针对常见的 HTTP 请求提供了简洁的 API&#xff0c;使得开发者无需面对复杂的设置。当前版本已支持基本的请…

私有化部署大模型:5个.Net开源项目

从零构建.Net前后端分离项目 今天一起盘点下&#xff0c;10月份推荐的5个.Net开源项目&#xff08;点击标题查看详情&#xff09;。 1、BootstrapBlazor企业级组件库&#xff1a;前端开发的革新之路 BootstrapBlazor是一个用于构建现代Web应用程序的开源框架&#xff0c;它基…