vue3-响应式函数

​🌈个人主页:前端青山

🔥系列专栏:Vue篇

🔖人终将被年少不可得之物困其一生

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

目录

[ref 响应式函数](#ref 响应式函数)

引言:

[ref 函数](#ref 函数)

[reactive 函数](#reactive 函数)

[Reactive 与 ref 对比](#Reactive 与 ref 对比)

vue3响应式原理

1、vue3响应式原理

ref 响应式函数

引言:

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

javascript 复制代码
<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 监听函数,如下图:

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

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

javascript 复制代码
<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中引入
javascript 复制代码
<script>
import { reactive } from "vue";
...
</script>
  • 代码如下:
javascript 复制代码
<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 中的问题了。
javascript 复制代码
<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 中的问题了。
javascript 复制代码
<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的作用。

javascript 复制代码
// 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 反射对被代理对象的属性进行操作。

javascript 复制代码
    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)
        }
    })
相关推荐
玖釉-4 分钟前
解决PowerShell执行策略导致的npm脚本无法运行问题
前端·npm·node.js
Larcher38 分钟前
新手也能学会,100行代码玩AI LOGO
前端·llm·html
徐子颐1 小时前
从 Vibe Coding 到 Agent Coding:Cursor 2.0 开启下一代 AI 开发范式
前端
小月鸭1 小时前
如何理解HTML语义化
前端·html
jump6801 小时前
url输入到网页展示会发生什么?
前端
诸葛韩信1 小时前
我们需要了解的Web Workers
前端
brzhang2 小时前
我觉得可以试试 TOON —— 一个为 LLM 而生的极致压缩数据格式
前端·后端·架构
yivifu2 小时前
JavaScript Selection API详解
java·前端·javascript
这儿有一堆花2 小时前
告别 Class 组件:拥抱 React Hooks 带来的函数式新范式
前端·javascript·react.js
十二春秋2 小时前
场景模拟:基础路由配置
前端