vue3-响应式函数

news2024/12/29 12:38:16

​🌈个人主页:前端青山
🔥系列专栏:Vue篇
🔖人终将被年少不可得之物困其一生

依旧青山,本期给大家带来vue篇专栏内容:vue3-响应式函数

目录

ref 响应式函数

引言:

ref 函数

reactive 函数

Reactive 与 ref 对比

vue3响应式原理

1、vue3响应式原理

ref 响应式函数

引言:

如下代码:当点击执行changeFn函数,修改setup中定义的变量时,发现页面中的name和age的数据并没有修改,说明该数据不是响应式数据

<template>
  <div>111</div>
  <p>{{ name }}--{{ age }}</p>
  <button @click="changeFn">changeFn</button>
</template>
​
<script>
export default {
  name: "App",
  setup() {
    //定义变量
    let name = "张三";
    let age = 20;
    // 定义方法
    function changeFn() {
      name = "李四";
      age = 30;
    }
    return {
      //setup函数返回值为一个对象
      name,
      age,
      changeFn,
    };
  },
};
</script>
ref 函数
  • 它是 vue3中的一个函数,一般用于将基本类型数据处理成响应式数据。

  • 作用:定义一个基本类型的响应式的数据,只有数据成为响应式数据,这样当数据变化时,才能被监测到。

  • 使用时需要从vue中引入

  • 语法:const xxx =ref(数据变量);结果 返回一个 RefImpl 的引用对象,获取时为 xxx.value

  • 在页面模板中使用数据直接 使用插值表达式,不需要加value <p>姓名:{{ name }}</p>,因为vue3会自动帮你.value,所以可以拿到值

  • ref 函数实现数据响应式的原理还是利用了vue2的Object.defineProperty() 给数据设置 get set 监听函数,如下图:

    image-20211130230403826

  • 接收的数据类型可以是基本类型(实现响应式原理为Object.defineProperty()),也可以是对象类型(当为对象时,实现响应式的原理就是Proxy不是Object.defineProperty())

点击如下change事件,修改name 和age

<template>
  <div>
    <!--name这个ref 引用对象在使用时不需要加value,vue3会自动帮你加value,所以可以拿到值-->
    <p>{{ name }}--{{ age }}</p>
    <p>{{ job.type }}--{{job.salary}}</p>
    <p @click="change">说话</p>
  </div>
</template>
<script>
import { ref } from "vue"; // 引入响应式函数ref
export default {
  name: "App",
  setup() {
    let name = ref("张三"); //返回一个 ref 引用对象
    let age = ref(20);
    console.log(name)
    // 当ref传的参数为对象时
    let job = ref({
      type: "前端工程师",
      salary: "20k",
    });
    function change() {
      name.value = "李四"; // ref对象.value 修改其值
      age.value = 30;
      job.value.type = "后端开发工程师";
      job.value.salary = "30k";
    }
    return {
      name,
      age,
      change,
      job
    };
  },
};
</script>

reactive 函数

1.定义一个对象类型的响应式数据,返回一个Proxy 实例对象,不能用于基本数据类型,否则报错。(基本类型响应式数据使用ref)。

语法:const 代理对象= reactive(源对象) ,接收一个对象或数组,返回一个代理对象(即Proxy源对象

  • 使用时先从vue中引入

<script>
import { reactive } from "vue";
...
</script>
  • 代码如下:

<template>
  <p>{{ job.type }} --{{ job.salary }}--{{ job.like.a.b }}--{{job.content}}</p>
  <p v-for="(item, index) in foodArr" :key="index">{{ item }}</p>
  <button @click="changeFn">changeFn</button>
</template>
​
<script>
import { reactive } from "vue";
export default {
  name: "App",
  components: {},
  setup() {
    //定义对象
    let job = reactive({
      type: "前端工程师",
      salary: "20k",
      like:{
          a:{
              b:'不告诉你'
          }
      }
    });
    console.log(job);
    //定义数组
    let foodArr = reactive(["刷抖音", "敲代码"]);
    console.log(foodArr);
    // 定义方法
    function changeFn() {
      job.type = "后端开发工程师";
      job.salary = "30k";
      job.content = "写代码"; // 给对象添加属性
      foodArr[0]='买包包' // 通过下标修改数组
    }
    return {
      //setup函数返回值为一个对象
      job,
      changeFn,
      foodArr
    };
  },
};
</script>
  • vue3中使用proxy 实现的数据响应去掉了vue2中不能检测到对象添加属性和通过下标修改数组而无法检测的情况。

Reactive 与 ref 对比

1、数据定义角度对比:

  • ref用来定义:基本数据类型

  • reactive 用来定义: 对象或数组类型数据

    注意:ref也可以定义对象或数组类型数据,它内部还是通过reactive转换成代理对象

2、原理角度对比:

  • ref通过Object.defineProperty() 的get和set 实现数据的响应式 即(数据劫持)

  • reactive 通过Proxy 实现数据响应式的,并通过Reflect 来操作源对象数据的。

3、从使用角度对比:

  • ref 定义的数据操作时需要使用 .value, 而插值表达式中使用时,不需要使用 .value

  • reactive 定义的数据操作都不需要 .value

vue3响应式原理

  • 对象数据新增属性和删除属性,不存在vue2.x 中的问题了。

<template>
  <div>
    <p>{{ person.name }}</p>
    <p>{{ person.age }}</p>
    <p>{{ person.sex }}</p>
    <button @click="addSex">添加属性</button>
    <button @click="deleteSex">删除属性</button>
  </div>
</template>
​
<script>
import { reactive } from "vue";
export default {
  name: "App",
  components: {},
  setup() {
    let person = reactive({
      name: "张三",
      age: 20,
    });
    console.log(person);
    //定义添加属性
    function addSex() {
      person.sex = "男";
      console.log(person);
    }
    // 定义删除属性
    function deleteSex() {
      delete person.sex;
      console.log(person);
    }
    return {
      person,
      addSex,
      deleteSex,
    };
  },
};
</script>
  • 数组数据直接通过修改下标,修改数组,不存在vue2.x 中的问题了。

<template>
  <div>
    <p v-for="(item, index) in person.like" :key="index">{{ item }}</p>
    <button @click="change">修改数组的值</button>
  </div>
</template>
​
<script>
import { reactive } from "vue";
export default {
  name: "App",
  components: {},
  setup() {
    let person = reactive({  
      name: "张三",
      age: 20,
      like: ["打球", "敲代码"],
    });
    console.log(person); // proxy 实例对象
    function change() {
      person.like[0] = "打台球";
    }
    return {
      person,
      change,
    };
  },
};
</script>

1、vue3响应式原理

首先说一下Reflect的作用。

// Reflect是window下的一个内置对象
// 1. 使用reflect 访问数据
    let obj = {
        name: '张三',
        age: 20
    }
    console.log(Reflect.get(obj, 'name')); // 张三
// 2.使用Reflect 修改数据
    Reflect.set(obj, 'age', 50)
    console.log(obj);
​
//3.使用Reflect删除数据
    Reflect.deleteProperty(obj, 'name') 
    console.log(obj);

vue3响应原理代码

通过Proxy代理,拦截对象中任意属性的变化,包括属性的读取,修改、设置、删除。

通过Reflect 反射对被代理对象的属性进行操作。

    let data = {
        name: "张三",
        age: 30
    }
    console.log(Proxy);
    // 使用p 对象代理data, Proxy为window 下的内置代理函数
    let p = new Proxy(data, {
        // 读取属性
        get(target, propName) {
            // target 就是 data
            console.log(`读取p上个${propName}属性`);
            return Reflect.get(target, propName)
        },
        // 修改和设置属性
        set(target, propName, value) {
            // value 为赋的值
            console.log(`修改p的${propName}属性`);
            // target[propName] = value
            Reflect.set(target, propName, value)
​
        },
        //删除属性
        deleteProperty(target, propName) {
            console.log(`删除p上的${propName}属性`);
            // return delete target[propName]
            return Reflect.deleteProperty(target, propName)
        }
    })

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

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

相关文章

阿里云优惠券如何领取(阿里云在哪领取优惠券)

阿里云优惠券是阿里云为了回馈广大用户而推出的一种优惠活动&#xff0c;可以帮助用户在购买阿里云产品和服务时享受一定的优惠&#xff0c;本文将为大家介绍如何领取阿里云优惠券。 1、通过阿里云官网活动页面领取 阿里云会不定期举办一些优惠活动&#xff0c;例如双十一、双…

import.meta.glob() 如何导入多个目录下的资源

import.meta.glob() 如何导入多个目录下的资源 刚开始用 vite&#xff0c;在做动态路由的时候遇到了这个问题&#xff0c;看到其它教程上都是只引用了一个目录层级的内容&#xff0c;比如这样&#xff1a; let RouterModules import.meta.glob("/src/view/*/*.vue"…

单链表OJ题——11.随机链表的复制

11.随机链表的复制 138. 随机链表的复制 - 力扣&#xff08;LeetCode&#xff09; /* 解题思路&#xff1a; 此题可以分三步进行&#xff1a; 1.拷贝链表的每一个节点&#xff0c;拷贝的节点先链接到被拷贝节点的后面 2.复制随机指针的链接&#xff1a;拷贝节点的随机指针指向…

数组扩展方法(一)

Array.prototype.forEach MDN解释forEach()方法是对数组的每个元素执行一个给定的函数&#xff0c;换句话来说就是在调用forEach()方法的时候&#xff0c;需要传入一个回调函数callback&#xff0c;循环每个数组内部元素时都会执行一次传入的回调函数callback forEach()方法的…

单链表OJ题——10.环形链表2

10.环形链表2 142. 环形链表 II - 力扣&#xff08;LeetCode&#xff09; /* 解题思路&#xff1a; 如果链表存在环&#xff0c;则fast和slow会在环内相遇&#xff0c;定义相遇点到入口点的距离为X,定义环的长度为C,定义头到入口的距离为L,fast在slow进入环之后一圈内追上slow…

ArmSoM-RK3588编解码之mpp编码demo解析:mpi_enc_test

一. 简介 [RK3588从入门到精通] 专栏总目录mpi_enc_test 是rockchip官方编码 demo本篇文章进行mpi_enc_test 的代码解析&#xff0c;编码流程解析 二. 环境介绍 硬件环境&#xff1a; ArmSoM-W3 RK3588开发板 软件版本&#xff1a; OS&#xff1a;ArmSoM-W3 Debian11 三. …

并行与分布式 第7章 体系结构 下

文章目录 并行与分布式 第7章 体系结构 下7.3 互连结构7.3.1 网络拓扑的基本概念7.3.2 互连网络分类7.3.3 典型静态网络7.3.4典型动态互连网络 7.4 性能评测7.4.1 工作负载7.4.2 峰值速度7.4.3 并行执行时间7.4.4 性能价格比7.4.5多处理器性能定律 并行与分布式 第7章 体系结构…

Linux免密登录——A登录B密钥设置(SSH SCP)

密钥登录 密钥登录比帐号密码方式更安全、更方便&#xff0c;并提供了更多的自动化和批处理选项。 安全性&#xff1a;使用非对称加密算法&#xff0c;公钥存在服务器&#xff0c;私钥存在本地计算机&#xff0c;私钥不在网络传输&#xff0c;降低被黑客截获风险。强密码&#…

2023年亚太杯数学建模思路 - 案例:最短时间生产计划安排

文章目录 0 赛题思路1 模型描述2 实例2.1 问题描述2.2 数学模型2.2.1 模型流程2.2.2 符号约定2.2.3 求解模型 2.3 相关代码2.4 模型求解结果 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 最短时…

Pyside6/PyQt6的QTreeWidget如何添加多级子项,如何实现选中父项,子项也全部选中功能,源码示例

文章目录 📖 介绍 📖🏡 环境 🏡📒 使用方法 📒📝 数据📝 源码📖 介绍 📖 在UI开发中经常会需要展示/让用户多层级选择,这篇文章记录了一个QTreeWidget如何添加多级子项,如何实现选中父项,子项也全部选中/取消选中功能的源码示例,大家可以举一反三实现自…

私有化敏感词检测API服务wordscheck

之前有网友在找敏感词检测的应用&#xff0c;这个应该能满足他的需求&#xff1b; 什么是 wordscheck &#xff1f; wordscheck 是敏感词检测 API&#xff0c;提供文本识别、智能鉴黄、涉政检测、谩骂等等敏感词检测过滤服务。 简介 敏感词库从大量样本库整理出来&#xff0c;…

数据结构(超详细讲解!!)第二十四节 二叉树(上)

1.定义 二叉树&#xff08;Binary Tree&#xff09;是另一种树型结构。 二叉树的特点&#xff1a; 1&#xff09;每个结点至多只有两棵子树&#xff08;即二叉树中不存在度大于2的结点&#xff09;&#xff1b; 2&#xff09;二叉树的子树有左右之分&#xff0c;其次序…

关于AssetBundle禁用TypeTree之后的一些可序列化的问题

1&#xff09;关于AssetBundle禁用TypeTree之后的一些可序列化的问题 2&#xff09;启动Unity导入变动的资源时&#xff0c;Singleton ScriptableObject 加载不到 3&#xff09;Xcode15构建Unity 2022.3的Xcode工程&#xff0c;报错没有兼容的iPhone SDK 这是第361篇UWA技术知识…

EPSon打印机更换色带

1、打印机色带拆装视频 打印机色带更换 2、色带盒四周有多个卡扣&#xff0c;需从右到左依次轻微用力掰开&#xff0c;使盖板与盒体脱离&#xff0c;注意不要掰断卡扣。 3、如何将色带放入打印机色带盒&#xff1f; A、色带放入盒体时不可打乱打结&#xff0c;以免卡带&#x…

图解Spark Graphx基于connectedComponents函数实现连通图底层原理

原创/朱季谦 第一次写这么长的graphx源码解读&#xff0c;还是比较晦涩&#xff0c;有较多不足之处&#xff0c;争取改进。 一、连通图说明 连通图是指图中的任意两个顶点之间都存在路径相连而组成的一个子图。 用一个图来说明&#xff0c;例如&#xff0c;下面这个叫graph…

合理运用ChatGPT使用Python编写一个桌面便签应用

ChatGPT的编程能力也不差&#xff0c;本次我就一步一步提要求&#xff0c;让ChatGPT根据我的要求&#xff0c;编写出一个可用的&#xff0c;可打包运行的桌面便签。 代码 import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QMenu, QAction, QSystemTrayIco…

通信原理板块——时分复用

微信公众号上线&#xff0c;搜索公众号小灰灰的FPGA,关注可获取相关源码&#xff0c;定期更新有关FPGA的项目以及开源项目源码&#xff0c;包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 1、基本概念 复用的目的是为了扩大…

宏集新闻 | 虹科传感器事业部正式更名为宏集科技

致一直支持“虹科传感器”的朋友们&#xff1a; 为进一步整合资源&#xff0c;给您带来更全面、更优质的服务&#xff0c;我们非常荣幸地宣布&#xff0c;虹科传感器事业部已正式更名为宏集科技。这一重要的改变代表了虹科持续发展进程中的新里程碑&#xff0c;也体现了我们在传…

GitHub 报告发布:TypeScript 取代 Java 成为第三受欢迎语言

GitHub发布的2023年度Octoverse开源状态报告发布&#xff0c;研究围绕AI、云和Git的开源活动如何改变开发人员体验&#xff0c;以及在开发者和企业中产生的影响。报告发现了三大趋势&#xff1a; 1、生成式AI的广泛应用&#xff1a; 开发人员大量使用生成式AI进行构建。越来越…

智能座舱架构与芯片- (14) 测试篇 上

一、 验证平台概要 1.1 测试软件方法论 “软件定义汽车” 的时代&#xff0c;软件在整车制造中的重要性日渐凸显。但不同于其他行业的软件开发&#xff0c;汽车行业有自己独特的软件开发要求。首先是需求严谨、需求层次复杂、需要通过专业的工具进行管理&#xff1b;其次开发…