自学内容网 自学内容网

前端系列-7 Vue3响应式数据

1.响应式数据和实现

响应式数据的核心是当数据模型发生变化时,与之相关(使用该数据模型)的视图或组件可以自动更新,以反映最新的数据状态。
实现原理是数据劫持、依赖收集和分发更新,数据劫持是一种AOP策略。
在vue2中通过Object.defineProperty方法为对象的每个属性设置setter和getter方法,当访问或者修改对象的属性时,进入setter/getter方法,从而实现拦截。getter方法被调用时,可以进行依赖收集,确认属性被哪些组件依赖;setter方法被调用时,则进行分发更新,将属性的更新事件发送到对应依赖的组件。
在vue3中,通过Proxy创建一个对象的代理,从而可以拦截其属性的读取、设置等操作。Proxy相对于Object.defineProperty具有更大和更灵活的数据拦截能力,并且优化了内存使用。

2.使用方式

2.1 ref

当基本类型变量或者对象通过ref函数包裹后,形成响应式数据对象,使用方式如下:

<template>
  <div>
    <p>姓名:{{name}}</p>
    <button @click="changeName">修改名字</button>
  </div>
</template>

<script setup lang="ts">
 import { ref } from 'vue';
    
    let name =ref('ewen');

    function changeName() {
        name.value = "ewens";
        console.log(name);
        console.log(name.value);    
    }
</script>

浏览器Console显示name为RefImpl类型对象,value属性存放实际的数值:

RefImpl {__v_isShallow: false, dep: Map(1), __v_isRef: true, _rawValue: "ewens", _value: "ewens"}
App.vue:8 ewens

说明:在template组件中直接使用name, 而在script中使用name.value进行取值和设值。

2.2 reactive

reactive只能用于对象和数组类型,不能用于基本类型

当对象或数组通过reactive函数包裹后,形成响应式数据对象,使用方式如下:

<template>
  <div>
      <p>姓名:{{person.name}}</p>
      <p>年龄:{{person.age}}</p>
      <button @click="changeName">修改名字</button>
      <button @click="changeAge">修改年龄</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { reactive } from 'vue'

// person 是一个Proxy类型的对象
let person = reactive({ name: 'ewen', age: 18})

function changeName() {
  person.name = 'ewens'
}
function changeAge(){
  person.age = 999
}
</script>

说明:在template组件和script块中直接使用对象.属性名进行取值和设值。

2.3 toRef与toRefs

当希望从响应式对象中提取某个属性,且希望保持这个属性的响应性,可以通过toRef和toRefs来实现。

import {reactive,toRefs,toRef} from 'vue'

let person = reactive({ name: 'ewen', age: 18})
// 使用toRef可以提取响应式对象的某个属性
const name = toRef(person, 'name');
const age = toRef(person, 'age');

//使用toRef可以一次性提取响应式对象的多个属性:
const { name, age } = toRefs(person);

在响应式属性提取之后,在template组件或者script脚本中原本需要使用person.name的地方也可以使用name替换,使用person.age的地方也可以使用age替换。


原文地址:https://blog.csdn.net/Sheng_Q/article/details/140583511

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!