vue3-03-创建响应式数据的几种方法

news2024/9/22 3:30:34

响应式数据

  • 一、 ref 创建:响应式数据
      • 1)ref 创建:基本类型的响应式数据
      • 2)ref 创建:对象类型的响应式数据
      • 3)volar 插件自动添加 .value
      • 4)customRef 自定义 ref
  • 二、 reactive 创建:响应式数据
      • 1)reactive 创建对象类型的响应式数据
      • 2)reactive更新对象数据
      • 3)toRefs 与 toRef
  • 三、 ref 和 reactive 的区别
  • 四、其他补充
      • 1)shallowRef、shallowReactive
        • 1. shallowRef
        • 2. shallowReactive
        • 3. 总结
      • 2)readonly 与 shallowReadonly
        • 1. readonly
        • 2. shallowReadonly
      • 3)toRaw 与 markRaw
        • 1. toRaw
        • 2. markRaw

此总结是我看尚硅谷视频总结的,所以可能会有总结不到位或不清楚的情况
适合学过的人回来复习的时候看

一、 ref 创建:响应式数据

ref 可以定义:基本类型、对象类型的响应式数据

1)ref 创建:基本类型的响应式数据

  • vue3项目,在setup中创建的变量,例如 let num = 100 中的num默认不是响应式数据
  • 利用 ref 可以创建基本类型的响应式数据

在这里插入图片描述

2)ref 创建:对象类型的响应式数据

若 ref 接收的是对象类型,内部其实也是调用了 reactive 函数

<script lang="ts" setup name="Person111">
  import { ref } from "vue"
  // 数据
  let car = ref({ brand: '奔驰', price: 100})
  let game = ref([
    { id: 10001, name: '原神'},
    { id: 10002, name: '双人成行'},
    { id: 10003, name: '头七怪谈'}
  ])

  // 方法
  function changePrice() { // 改变汽车价格
    car.value.price += 10
    console.log(car.value.price)
  }

  function changeGame() { // 改变游戏名称
    game.value[1].name = '纸嫁衣'
  }
  
  function changeCar() { // 更改车数据
    // car.value.brand = '小电驴'
    // car.value.price = 0.3
    // 上面两行的效果等同下面的这个代码,即使把整个对象赋给car.value,car也不会失去响应式
    car.value = { '小电驴', price: 0.3 }  
  }
</script>

在这里插入图片描述

3)volar 插件自动添加 .value

vscode左下角点击设置,搜索Dot Value,勾选,如下图
在这里插入图片描述

4)customRef 自定义 ref

customRef: 创建一个自定义的ref,并对其依赖项跟踪和更新触发进行逻辑控制

举例: 想要1s后(有延迟效果)响应式数据更新
注意:下例中 clearTimeout(timer)起到防抖效果

useSumRef.ts

import { customRef } from 'vue'
export default function (initValue: string, delay: number) {
  // 使用Vue提供的customRef定义响应式数据
  // track:跟踪    trigger:触发
  let msg = customRef((track, trigger) => {
    let timer: number
    return {
      // get何时调用? -- msg被读取时
      get(){
        track() // 告诉Vue数据msg很重要,你要对msg进行持续关注,一旦msg变化就去更新
        return initValue
      },
      // set何时调用? -- msg被修改时
      set(value){
        clearTimeout(timer)
        timer = window.setTimeout(() => {
          initValue = value
          trigger() // 通知Vue数据msg变化了
        }, delay)
      }
    }
  })
  return { msg }
}

App.vue

<template>
  <div class="app">
    <h2>{{ msg }}</h2>
    <input type="text" v-model="msg">
  </div>
</template>

<script setup lang="ts" name="App">
  import {ref} from 'vue'
  import useMsgRef from './useMsgRef'
  // 使用Vue提供的默认ref定义响应式数据,数据一变,页面就更新
  // let msg = ref('你好')

  // 使用useMsgRef来定义一个响应式数据且有延迟效果
  let {msg} = useMsgRef('你好',1000)
</script>

二、 reactive 创建:响应式数据

  • reactive 只能创建对象类型的响应式数据
  • 在JS中可以直接操作对象类型数据,不需要.value

1)reactive 创建对象类型的响应式数据

在这里插入图片描述

<template>
  <div class="person">
    <h2>汽车信息:一辆{{ car.brand }}品牌的车,价格为{{ car.price }}</h2>
    <button @click="changePrice">改变汽车价格</button>
    <h2>游戏信息列表</h2>
    <ul>
      <li v-for="item in game" :key="item.id">{{ item.name }}</li>
    </ul>
    <button @click="changeGame">改变游戏名称</button>
    <h4>深层次{{ shen.a.b.id }}</h4>
    <button @click="changeShen">测试</button>
  </div>
</template>

<script lang="ts" setup name="Person111">
  import { reactive } from "vue"
  // 数据
  let car = reactive({ brand: '奔驰', price: 100})
  let game = reactive([
    { id: 10001, name: '原神'},
    { id: 10002, name: '双人成行'},
    { id: 10003, name: '头七怪谈'}
  ])
  let shen = reactive({
    a: {
      b: {
        id: 4
      }
    }
  })

  // 方法
  function changePrice() {
    car.price += 10
    console.log(car.price)
  }

  function changeGame() {
    game[1].name = '纸嫁衣'
  }

  function changeShen() {
    shen.a.b.id = 100
  }
</script>

2)reactive更新对象数据

注意: reactive重新分配对象 ,会失去响应式

场景:

<button @click="changeCar">点击修改车数据</button>
...
let car = ref({ brand: '奔驰', price: 100})
...
function  changeCar()  {
// { brand: '小电驴', price: 0.3 } ,要更新这个信息给car
}

方法一:手动赋值

function  changeCar()  {
// { brand: '小电驴', price: 0.3 } ,要更新这个信息给car
// 弊端:从后端返回的数据可以一个对象里有很多属性,一个一个赋值也太麻烦了
    Person.name = 'lisi'
    Person.age = 20
}

方法二:对象整体赋值

function  changeCar()  {
    // { brand: '小电驴', price: 0.3 } ,要更新这个信息给car

    // 下面这个写法页面可以更新, 而且这个写法car不会失去响应式更新
    Object.assign(car, { brand: '小电驴', price: 0.3})
    
    // 下面是两种错误写法
    // car = { brand: '小电驴', price: 0.3} // 这么写,数据更新了,页面不更新,不是响应式的了
    // car = reactive({ brand: '小电驴', price: 0.3}) // 这么写页面不更新的
}

3)toRefs 与 toRef

在这里插入图片描述

<template>
  <div class="box">
    <div>姓名:{{ person.name }}</div>
    <div>年龄:{{ person.age }}</div>
    <br>
    <button @click="changeName">点击修改姓名</button>
    <button @click="changeAge">点击修改年龄</button>
    <div>叫啥:{{ test }}</div>
  </div>
</template>

<script lang="ts" setup name="Person111">
  import { ref, reactive, toRefs, toRef } from "vue"

  // 数据
  let person = reactive({
    name: '张三',
    age: 18
  })
  let { name, age } = toRefs(person)
  console.log(name)  // 转换为了ref基本数据类型的响应式数据
  console.log(age)   // 相当于是把每一项都拆开了,但是每一项都还是ref响应式的
  let test = toRef(person, 'name') // 这个当然也是响应式的

  function changeName() {
    // person.name = 'zhang-san'
    name.value = 'zhang-san'
  }

  function changeAge() {
    // person.age += 1
    age.value += 1
  }

</script>

<style>
  .box {
    padding: 20px;
    background-color: skyblue;
    box-shadow:  0 0 10px;
    border-radius: 20px;
  }
  button {
    margin-right: 20px;
  }
</style>

三、 ref 和 reactive 的区别

在这里插入图片描述

四、其他补充

1)shallowRef、shallowReactive

1. shallowRef

在这里插入图片描述

举例:
在这里插入图片描述

运行效果:只有 “sum+1” 和 “修改整个人” 的功能能用,另外两个无效

在这里插入图片描述

2. shallowReactive

在这里插入图片描述

举例:
在这里插入图片描述

运行效果:只有 “修改品牌” 和 “修改整个车” 功能能用,另外两个无效

在这里插入图片描述

3. 总结

在这里插入图片描述

2)readonly 与 shallowReadonly

1. readonly

效果:

  • original显示什么,readOnlyCopy就显示什么,original修改,readOnlyCopy也会跟着修改
  • original可以修改自己的值,readOnlyCopy什么都不能修改,只能读

在这里插入图片描述

2. shallowReadonly

效果:

  • original显示什么,shallowReadOnlyCopy就显示什么,original修改shallowReadOnlyCopy也会跟着修改
  • original可以修改自己的值,shallowReadOnlyCopy第一层数据不能修改,但是深层次(第二层、第三层…)数据能够修改

举例:

  • shallowReadOnlyCopy不能修改“name”和“hobby整体”,但能修改hobby.eat和hobby.sport的值
    在这里插入图片描述
    在这里插入图片描述

3)toRaw 与 markRaw

1. toRaw

在这里插入图片描述

使用示例:
在这里插入图片描述

2. markRaw

在这里插入图片描述

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

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

相关文章

联想2025校招 技术研究方向试卷

目录 1. 第一题2. 第二题 ⏰ 时间&#xff1a;2024/08/16 &#x1f504; 输入输出&#xff1a;ACM格式 ⏳ 时长&#xff1a;1.5h 本试卷还有选择题部分&#xff0c;但这部分比较简单就不再展示。 1. 第一题 题目描述 小明正在神奇苹果园里工作。这个苹果园里一共有 n n n 棵…

C#堆排序算法

前言 堆排序是一种高效的排序算法&#xff0c;基于二叉堆数据结构实现。它具有稳定性、时间复杂度为O(nlogn)和空间复杂度为O(1)的特点。 堆排序实现原理 构建最大堆&#xff1a;将待排序数组构建成一个最大堆&#xff0c;即满足父节点大于等于子节点的特性。将堆顶元素与最后…

海康VisionMaster使用学习笔记4-快速匹配模块

快速匹配模块 快速匹配包括基本参数,特征模板,运行参数,结果显示 基本参数 可以修改图像源和模块的ROI区域. 特征模版 可以配置管理所有的模版,点击创建可以新增模版,也可以通过载入加载本地的模型 建立新模版 点击创建,可以选择当前图像或本地图像进行建模 模版存图按…

【ASFF】《Learning Spatial Fusion for Single-Shot Object Detection》

arXiv-2019 https://github.com/GOATmessi7/ASFF 文章目录 1 Background and Motivation2 Related Work3 Advantages / Contributions4 Method4.1 Strong Baseline4.2 Adaptively Spatial Feature Fusion4.2.1 Feature Resizing4.2.2 Adaptive Fusion 4.3 Consistency Propert…

DVWA | CSRF(LowMedium)攻击的渗透实践

目录 概述 Low Medium 概述 CSRF&#xff08;Cross-Site Request Forgery&#xff0c;跨站请求伪造&#xff09; 是一种网络攻击方式。 通过伪造当前用户的行为&#xff0c;让目标服务器误以为请求由当前用户发起&#xff0c;并利用当前用户权限实现业务请求伪造。 例如&a…

如何将excel以文本形式储存的数字一键转换为数字

有时候一些软件给出的数据格式很恶心&#xff0c;为了方便计算常常以数字粘贴到新表&#xff0c;但随之而来新问题&#xff0c;以文本储存的公式无法用公式计算&#xff0c;怎么办啊 方法一&#xff1a;使用“转换为数字”功能 (对数字少时用&#xff09; 当Excel检测到某个单…

得到任务式 大模型应用开发学习方案

根据您提供的文档内容以及您制定的大模型应用开发学习方案&#xff0c;我们可以进一步细化任务式学习的计划方案。以下是具体的任务式学习方案&#xff1a; 任务设计 初级任务 大模型概述&#xff1a;阅读相关资料&#xff0c;总结大模型的概念、发展历程和应用领域。深度学…

STM32定时器输入捕获功能

用于测频率测占空比 IC(Input Capture)输入捕获 输入捕获模式下&#xff0c;当通道输入引脚出现指定电平跳变&#xff08;上升沿/下降沿&#xff09;时&#xff0c;会让当前CNT的值将被锁存到CCR中&#xff0c;可用于测量PWM波形的频率、占空比、脉冲间隔、电平持续时间等参数…

数字化转型底座-盘古信息IMS OS,可支撑构建MES/WMS/QCS/IoT等工业软件

在当今这个数字化浪潮汹涌的时代&#xff0c;众多企业纷纷踏上数字化转型之路。对于部分想自研工业软件的企业来说&#xff0c;一个强大、灵活且可扩展的数字化底座显得尤为重要。盘古信息IMS OS&#xff0c;&#xff0c;正是这样一款能够支撑构建MES&#xff08;制造执行系统&…

SystemUI下拉框新增音量控制条

Android产品下拉框一直只有亮度条没有音量控制条。 为了方便控制音量&#xff0c;普遍都是底部导航栏添加音量加减按钮&#xff0c;在Android10以后&#xff0c;大家普遍用上了手势导航&#xff0c;去掉底部导航栏。 目前需要再下拉框中可以直接控制音量。 文章目录 前言需求及…

Git使用方法(三)---简洁版上传git代码

1 默认已经装了sshWindows下安装SSH详细介绍-CSDN博客 2 配置链接github的SSH秘钥 1 我的.ssh路径 2 进入路径cd .ssh 文件 3 生成密钥对 ssh-keygen -t rsa -b 4096 (-t 秘钥类型 -b 生成大小) 输入完会出现 Enter file in which to save the key (/c/Users/Administrator/…

webrtc学习笔记3

Nodejs实战 对于我们WebRTC项目而言&#xff0c;nodejs主要是实现信令服务器的功能&#xff0c;客户端和服务器端的交互我们选择websocket作为通信协议&#xff0c;所以以websocket的使用为主。 web客户端 websocket WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行…

IIS发布打包后文件

1.打开IIS软件 2 添加网站&#xff0c; 自定义网站名称-选择要放置的资源路径-选择IP地址 3.打开放置的资源目录放置打包后文件 4.选择浏览 搜索不到IIS可进行一下操作 控制面板-程序和功能-启用或关闭windows功能-勾选IIS

Axios请求使用params参数导致后端获取数据嵌套

问题重述&#xff1a; 首先看前端的axios请求这里我使用params参数将data数据传给后端 let data JSON.stringify(this.posts);axios.post("/blog_war_exploded/insertPost", {params: {data: data}}).then((res) > {if (res.data "success") {alert(…

在Windows11强制开启copilot

在 Windows 11 上启用自带的基于 GPT-4 的 Copilot 功能。以下是具体步骤&#xff1a; 更新系统&#xff1a; 确保你的 Windows 11 系统已经更新到最新版本&#xff08;23H2 或更高版本&#xff09;。你可以在“设置” > “Windows 更新”中检查并安装最新更新。 更改区域和…

盒子模型

1. 盒子模型&#xff08;Box Model&#xff09;组成 2.边框&#xff08;border&#xff09; 表格的细线边框 边框会影响盒子实际大小 3.内边距&#xff08;padding&#xff09; 内边距会影响盒子实际大小 应用场景---导航栏&#xff08;不设宽高度&#xff09; 4.外边距&#x…

并发系统的 CSP+PAT 形式化建模与验证方法(以Kafka系统为例)

消息队列中间件是分布式系统的重要组成部分。它允许应用程序仅关注数据本身&#xff0c;而无需关心数据传输的具体细节。这一特性有效解决了消息异步传输、应用程序解耦以及流量削峰等问题。Kafka是一个开源的分布式消息系统&#xff0c;它基于发布-订阅模型构建。Kafka具有低延…

软考高级:数据库- 候选键、主键、外键

在数据库设计中&#xff0c;候选键、主键和外键是三个非常重要的概念。为了更好地理解它们&#xff0c;我们可以用通俗的例子来帮助说明。 通俗示例 假设我们在一个学校里管理学生的信息。每个学生都有一个独一无二的学号、名字、身份证号和手机号。这些信息都可以用来唯一标…

Cat1智能电表:技术优势与应用注意事项

Cat.1(Category1)智能电表&#xff0c;作为新一代智能计量解决方案&#xff0c;其核心优势在于低功耗广域网络(LPWAN)技术的应用&#xff0c;特别是4GLTECat.1蜂窝网络标准的集成。这不仅提升了数据传输的稳定性和安全性&#xff0c;还优化了远程管理能力&#xff0c;为电力行业…

WPF打印控件内容

当我们想打印控件内容时&#xff0c;如一个Grid中的内容&#xff0c;可以用WPF中PrintDialog类的PrintVisual()方法来实现 界面如下&#xff1a; XAML代码如下 <Grid><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition Width"300"…