vue3-响应式函数

​🌈个人主页:前端青山
🔥系列专栏: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)
        }
    })

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

详解python淘宝秒杀抢购脚本程序实现

文章目录 前言一、官网下载火狐浏览器二、下载geckodriver&#xff0c;并解压到火狐浏览器文件夹根目录三、添加火狐浏览器根目录到系统环境变量四、下载并安装python及pycharm开发工具五、进入淘宝六、使用Pycharm运行脚本&#xff0c;新建python文件&#xff0c;将代码复制到…

英语六级范文模板

目录 现象解释 观点选择 问题解决 六级只考议论文&#xff0c;我们将从现象解释&#xff0c;观点选择&#xff0c;问题解决三个角度给出范文&#xff1a; 多次使用的句子&#xff0c;就可以作为模板记下来~~ 现象解释 In the contemporary world, the ability to meet cha…

单链表OJ题--9.环形链表

9.环形链表 141. 环形链表 - 力扣&#xff08;LeetCode&#xff09; /* 解题思路&#xff1a; 定义快慢指针fast,slow, 如果链表确实有环&#xff0c;fast指针一定会在环内追上slow指针。 */typedef struct ListNode Node; bool hasCycle(struct ListNode *head) {Node* slow …

程序员指南六:数据平面开发套件

PORT HOTPLUG FRAMEWORK 端口热插拔框架为DPDK应用程序提供在运行时附加和分离端口的能力。由于该框架依赖于PMD实现&#xff0c;PMD无法处理的端口超出了该框架的范围。此外&#xff0c;在从DPDK应用程序分离端口后&#xff0c;该框架不提供从系统中移除设备的方法。对于由物…

【代码随想录】刷题笔记Day32

前言 实在不想做项目&#xff0c;周末和npy聊了就业的焦虑&#xff0c;今天多花点时间刷题&#xff01;刷刷刷刷&#xff01; 93. 复原 IP 地址 - 力扣&#xff08;LeetCode&#xff09; 分割startindex类似上一题&#xff0c;难点在于&#xff1a;判断子串合法性(0~255)、&…

锯木棍

题目描述 有一根粗细均匀长度为 L 的木棍&#xff0c;先用红颜色刻度线将它 m 等分&#xff0c;再用蓝色刻度线将 其 n 等分&#xff08; m>n &#xff09;&#xff0c;然后按所有刻度线将该木棍锯成小段&#xff0c;计算并输出长度最长的木棍的长度和根数。 输入格式…

移动机器人,开启智能柔性制造新篇章

智能制造是当今工业发展的必然趋势&#xff0c;而柔性制造则是智能制造的重要组成部分。在这个快速变革的时代&#xff0c;如何提高生产效率、降低成本、增强灵活性成为了制造业的关键挑战。富唯智能移动机器人应运而生&#xff0c;为柔性制造注入了新的活力。 基于富唯智能AI-…

泛型边界的问题

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 我们花了两篇文章讲述了…

40、Flink 的Apache Kafka connector(kafka source的介绍及使用示例)-1

Flink 系列文章 1、Flink 部署、概念介绍、source、transformation、sink使用示例、四大基石介绍和示例等系列综合文章链接 13、Flink 的table api与sql的基本概念、通用api介绍及入门示例 14、Flink 的table api与sql之数据类型: 内置数据类型以及它们的属性 15、Flink 的ta…

【开源】基于Vue和SpringBoot的智能教学资源库系统

项目编号&#xff1a; S 050 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S050&#xff0c;文末获取源码。} 项目编号&#xff1a;S050&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 课程档案模块2.3 课…

Rockchip平台rk3588源码下载编译(基于Android13)

Rockchip平台rk3588源码下载编译(基于Android13) 源码下载 下载地址 repo init --repo-url https://gerrit.rock-chips.com:8443/repo-release/tools/repo -u https://gerrit.rock-chips.com:8443/Android_T/manifests.git -m Android13.xml服务器镜像下载 repo init --rep…

PCS7中如何实现DB块变量的自动上传

问题:如何实现PCS7中DB块中变量的自动上传? 解答:PCS7下,所有CFC中的变量都通过编译的方式自动上传的OS项目中,针对自定义的DB块同样也可以通过设置相关属性自动上传的OS中,具体操作如下: 插入一个全局数据块。 注意:数据块号必须符合要求,可以参考PCS7中定义的预留DB…

5-2计算pi

#include<stdio.h> #include<math.h>int main(){int sign1;//数值的符号int count0;//累计计算循环的次数double pi0.0;double n1;//分母double term1.0;//当前项的数while(fabs(term)>1e-6){//fabs(trem)|term|pipiterm;nn2;sign-sign;termsign/n;count;}pipi*…

vue3的单组件的编写(二)--通过对比vue2来讲解

&#x1f42f; 单组件的编写(二) 主要讲了 &#x1f308; 响应式数据的变化 响应式数据是MVVM数据变驱动编程的特色&#xff0c; VUE的设计也是受 MVVM模型的启发&#xff0c;大部分开发者选择MVVM框架都是因为数据驱动编程比传统的事件驱动编程来的方便。而选择vue&#xff…

“index“ should always be multi-word

vue报错&#xff1a;Component name “index” should always be multi-word 分析&#xff1a;组件名要以驼峰格式命名&#xff0c;自定义的要以loginIndex.vue等这种方式命名&#xff0c;防止和html标签冲突&#xff0c;所以命名index.vue 会报错 解决&#xff1a;在.eslint…

PG数据中DBeaver上传csv文件作为数据表

DBeaver 是一个开源的数据库工具&#xff0c;还是蛮好用的&#xff0c;有时候需要我们上传数据做表&#xff0c;数据为CSV格式的&#xff0c;DBeaver本身自带有功能实现的。 可打开连着的数据库&#xff0c;找到模式&#xff0c;点到下面的表里&#xff0c;选择一个表直接导入…

已完结7个,再启动1个新项目,嘎嘎强!

作者&#xff1a;小傅哥 博客&#xff1a;https://bugstack.cn 沉淀、分享、成长&#xff0c;让自己和他人都能有所收获&#xff01;&#x1f604; 大家好&#xff0c;我是技术UP主小傅哥。 &#x1f490;又到了启动新项目的时候&#xff0c;死鬼开心嘛。小傅哥的星球&#xf…

Rust可空类型Option

文章目录 Option基础模式匹配unwrap Rust基础教程&#xff1a;初步⚙所有权⚙结构体和枚举类⚙函数进阶⚙泛型和特征⚙并发和线程通信⚙cargo包管理 Rust进阶教程&#xff1a;用宏实现参数可变的函数⚙类函数宏 Option基础 在一些编程语言中&#xff0c;允许存在空值&#xf…

Linux环境下安装部署单机RabbitMQ(离线)

摘要 本文档适用于在Linux系统下部署单体RabbitMQ&#xff0c;是在无网的情况下部署的。涉及的任何操作都是通过手动下载安装包然后上传到服务器上进行安装&#xff0c;因此也遇到一些问题&#xff0c;并在此文档中记录。 实际操作环境&#xff1a;Kylin V10&#xff0c;实际…

java疫情期间社区出入管理系统-计算机毕业设计源码21295

摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对疫情期间社区出入管理等问题&#xff0c;对…