reactive()和ref()的区别、使用和转换

1,224 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情

reactive

在vue3中,普通数据是可以被直接修改的,但是视图不会被驱动着改变。所以,要将普通数据变成响应式数据。

reactive可以将对象,数组等复杂类型数据转化为响应式数据,但是通常来讲,reactive用来转化“对象”类型的数据。

示例代码:

<template>
  <h2>name:{{person.name}}</h2>
  <h2>age:{{person.age}}</h2>
  <button @click="updatePerson">change</button>
</template>

<script>
import { reactive } from "vue";
export default {
  name: "App",
  setup() {
    // 声明一个响应式的对象类型的变量person
    const person = reactive({
      name: "harry",
      age: 28
    });

    // 定义一个修改person变量的方法
    function updatePerson() {
      person.name += "kun";
      person.age += 1;
    }

    return {
      // 将上面两个返回出去,以于在模板中拿到
      person,
      updatePerson
    };
  }
};
</script>

<style>
</style>

toRef

当有一个使用了reactive的响应式数据对象时,但是模板只需要使用其中一个属性值时,可以使用toRef。

<template>
  <h2>name:{{person.name}}</h2>
  <h2>age:{{person.age}}</h2>
  <button @click="updateName">changeName</button>
</template>

<script>
import { reactive, toRef } from "vue";
export default {
  name: "App",
  setup() {
    const person = reactive({
      name: "harry",
      age: 28
    });
    console.log(person); // Proxy {name: 'harry', age: 28}

    // 从响应式数据中解构出的数据不再是响应式了,不可以再次修改
    // let { name } = person;
    // console.log(name); // harry

    // 通过toRef来将响应式对象中的某一项拿出来,保证拿出来的数据还是响应式
    const name = toRef(person, "name");
    console.log(name);
    // ObjectRefImpl {_object: Proxy, _key: 'name', _defaultValue: undefined, __v_isRef: true}

    // 修改name
    function updateName() {
      // 这里修改ref包裹的值所对应的变量,要通过“.value”来修改
      // 如果没有,会报一个应使用let代替const的错误。且修复了也没有效果
      name.value = "iKun";
    }

    return {
      person,
      updateName
    };
  }
};
</script>

<style>
</style>

注意:

  • 从响应式数据中解构出的数据不再是响应式了,不可以再次修改
  • 通过toRef来将响应式对象中的某一项拿出来,保证拿出来的数据还是响应式
  • 读写值的时候,要通过"value"属性来读写

toRefs

对对象使用reactive,需要在模板中使用的“对象名.属性名”的形式来获取属性值。

通过toRrfs将一个对象里的属性都完全解构出来,在模板中直接使用“属性名”就可以获取属性值了。

实例代码:

<template>
  <div>name:{{name}}</div>
  <div>age:{{age}}</div>
  <button @click="updatePerson">change</button>
</template>

<script>
import { toRefs, reactive } from "vue";
export default {
  name: "App",
  setup() {
    const person = reactive({
      name: "harry",
      age: 28
    });

    const newp = toRefs(person); // 需要在return中解构一下newp
    console.log(newp); // {name: ObjectRefImpl, age: ObjectRefImpl}

    function updatePerson() {
      newp.name.value += "!";
      person.age += 1;
      // person和new的数据相通,所以修改谁的都可以
      // 但是注意使用ref相关的函数后,都要通过value属性读写值
      // 使用reactive可以直接读写
    }
    return {
      ...newp,
      updatePerson
    };
  }
};
</script>

<style>
</style>

ref

使用ref定义响应式数据,一般用于简单数据类型。

注意在setup()中读写ref函数相关的值时,要通过“.value”的形式,但是在模板中不用!

ref和reactive的使用场景

一般来说,当明确知道一个响应式数据的类型是一个对象的时候,就用reactive。其它,就用ref。