【Vue3响应式】ref、reactive,以及toRefs 函数

Vue3的ref和reactive区别

  • 一、 ref
    • ref的作用
    • ref的代码示例
  • 二、reactive
    • reactive的作用
    • reactive的代码示例
      • reactive的基础例子
      • reactive包含嵌套对象和数组的例子
  • 三、ref和reactive的区别
  • 四、toRefs 函数
    • 什么是 toRefs 函数?
    • 如何使用 toRefs 函数?
    • 注意事项
  • 五、面试可能会问的问题

Vue3中的ref和reactive都是响应式数据的实现方式。在Vue3中,我们可以使用ref来将基本数据类型包装为一个响应式对象,使用reactive将对象包装为响应式对象。本文将介绍这两种响应式数据的实现方式以及它们之间的区别。

一、 ref

ref的作用

ref是Vue3提供的一种用于包装基本数据类型的响应式对象的实现方式。在Vue3中,使用ref可以将基本数据类型(如字符串、数字、布尔值等)包装为响应式对象。当这些基本数据类型的值发生变化时,Vue3会自动更新视图中相应的内容。

ref的代码示例

下面是一个使用ref的示例:

<template>
  <div>
    <p>{{ message }}</p>
    <button @click="updateMessage">更新</button>
  </div>
</template>

<script>
import { ref } from 'vue';

export default {
  setup() {
    const message = ref('Hello, World!');
    
    const updateMessage = () => {
      message.value = 'Hello, Vue3!';
    };
    
    return {
      message,
      updateMessage
    };
  }
};
</script>

在这个例子中,我们使用了ref来包装一个字符串类型的数据。在setup函数中,我们将ref返回的响应式对象作为组件实例的一个属性,同时也将updateMessage函数返回给模板。当updateMessage函数被调用时,message的值会被更新为’Hello, Vue3!’,并且视图中显示的内容也会被更新。

需要注意的是,在使用ref包装基本数据类型时,我们需要通过.value来访问这个值。这是因为ref返回的是一个包含.value属性的响应式对象,而不是一个基本数据类型的值。

二、reactive

reactive的作用

reactive是Vue3提供的一种用于包装对象的响应式对象的实现方式。在Vue3中,使用reactive可以将对象包装为一个响应式对象。当这个对象的属性发生变化时,Vue3会自动更新视图中相应的内容。

reactive的代码示例

reactive的基础例子

下面是一个使用reactive的例子:

<template>
  <div>
    <p>{{ user.name }}</p>
    <button @click="updateUserName">更新</button>
  </div>
</template>

<script>
import { reactive } from 'vue';

export default {
  setup() {
    const user = reactive({
      name: 'John Doe',
      age: 30
    });
    
    const updateUserName = () => {
      user.name = 'Jane Doe';
    };
    
    return {
      user,
      updateUserName
    };
  }
};
</script>

在这个例子中,我们使用了reactive来包装一个包含name和age两个属性的对象。在setup函数中,我们将reactive返回的响应式对象作为组件实例的一个属性,同时也将updateUserName函数返回给模板。当updateUserName函数被调用时,user对象的name属性会被更新为’Jane Doe’,并且视图中显示的内容也会被更新。
需要注意的是,在使用reactive包装对象时,所有的属性都会被包装为响应式对象,包括嵌套的对象和数组。这意味着当嵌套对象或数组的属性发生变化时,也会触发相应的视图更新。
下面是一个包含嵌套对象和数组的例子:

reactive包含嵌套对象和数组的例子

<template>
  <div>
    <p>{{ user.name }}</p>
    <p>{{ user.address.city }}</p>
    <ul>
      <li v-for="hobby in user.hobbies" :key="hobby">{{ hobby }}</li>
    </ul>
    <button @click="updateUser">更新</button>
  </div>
</template>

<script>
import { reactive } from 'vue';

export default {
  setup() {
    const user = reactive({
      name: 'John Doe',
      age: 30,
      address: {
        city: 'New York',
        country: 'USA'
      },
      hobbies: ['reading', 'swimming', 'hiking']
    });
    
    const updateUser = () => {
      user.name = 'Jane Doe';
      user.address.city = 'San Francisco';
      user.hobbies.push('yoga');
    };
    
    return {
      user,
      updateUser
    };
  }
};
</script>

在这个例子中,我们使用reactive来包装一个包含嵌套对象和数组的对象。在setup函数中,我们将reactive返回的响应式对象作为组件实例的一个属性,同时也将updateUser函数返回给模板。当updateUser函数被调用时,user对象的name属性、address对象的city属性和hobbies数组的内容都会被更新,并且视图中显示的内容也会被更新。

三、ref和reactive的区别

在使用ref和reactive时,需要注意它们之间的区别。ref适用于包装基本数据类型,而reactive适用于包装对象。此外,ref返回的是一个包含.value属性的响应式对象,而reactive返回的是一个包装后的响应式对象。

下面是一个使用ref和reactive的区别的例子:

<template>
  <div>
    <p>{{ message }}</p>
    <p>{{ user.name }}</p>
    <button @click="updateData">更新</button>
  </div>
</template>

<script>
import { ref, reactive } from 'vue';

export default {
  setup() {
    const message = ref('Hello, World!');
    const user = reactive({
      name: 'John Doe',
      age: 30
    });
    
    const updateData = () => {
      message.value = 'Hello, Vue3!';
      user.name = 'Jane Doe';
    };
    
    return {
      message,
      user,
      updateData
    };
  }
};
</script>

在这个例子中,我们同时使用了ref和reactive。当updateData函数被调用时,我们使用ref更新了message的值,同时也使用reactive更新了user对象的name属性的值。需要注意的是,在更新message的值时,我们需要使用.value来访问它的值,而在更新user对象的name属性的值时,我们直接使用了对象的属性访问方式。

四、toRefs 函数

Vue 3 中的 toRefs 函数是一个非常有用的工具,它可以将一个响应式对象转换为一组响应式属性。这个函数可以用于将父组件中的响应式对象传递给子组件,并在子组件中以单独的响应式属性的形式使用它们。

什么是 toRefs 函数?

在 Vue 3 中,我们可以使用 ref 和 reactive 来创建响应式数据。ref 可以用于创建单个值的响应式数据,而 reactive 则可以用于创建包含多个属性的响应式对象。

但是,在某些情况下,我们希望将一个响应式对象的属性单独作为响应式属性使用,而不是将整个对象作为一个响应式数据使用。这时就可以使用 toRefs 函数。

toRefs 函数的作用是将一个响应式对象转换为一个对象,该对象的属性均为单独的响应式属性,这些属性与原始响应式对象的属性具有相同的响应式性质。

如何使用 toRefs 函数?

下面是一个示例,演示了如何使用 toRefs 函数将一个响应式对象转换为一组响应式属性:

<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">Increment</button>
    <ChildComponent :propsData="toRefs(childData)" />
  </div>
</template>

<script>
import { reactive, toRefs } from 'vue';
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent,
  },
  setup() {
    const data = reactive({
      count: 0,
      message: 'Hello!',
    });

    const childData = reactive({
      name: 'Child',
      age: 10,
    });

    const increment = () => {
      data.count++;
    };

    return {
      ...toRefs(data),
      childData,
      increment,
    };
  },
};
</script>

在这个例子中,父组件的 data 对象包含一个 count 属性,表示一个计数器。父组件通过 toRefs 函数将这个对象转换为一组响应式属性,并将这些属性传递给了子组件。子组件可以像使用普通的响应式属性一样使用这些属性。

注意事项

需要注意的是,toRefs 函数返回的对象中的属性并不是响应式的,而是与原始响应式对象的属性具有相同的响应式性质。这意味着,如果原始响应式对象的属性被更新了,返回的对象中的属性也会被更新。但是,如果返回的对象中的属性被直接更新了,原始响应式对象中的对应属性不会被更新。

五、面试可能会问的问题

Vue3的响应式原理——一定要背下来!

Vue3的响应式原理是通过Proxy(代理)对对象的属性值进行读写、添加、删除、进行劫持,通过Reflect(反射)动态对被代理对象的属性值进行特定的操作,由于Proxy和Reflect不支持IE浏览器,这也是Vue3不支持IE浏览器的主要原因之一!

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Vue 3中,我们可以使用`reactive`和`toRefs`这两个函数来处理响应式数据。引用中的代码展示了如何引入这两个函数。 `reactive`函数Vue 3为我们提供的替代Vue 2中的`data`选项的函数。它接收一个普通的JavaScript对象作为参数,并将其转换为具有响应式特性的对象。这意味着当我们修改这个响应式对象的属性时,相关的组件会自动更新。所以,可以将组件的状态数据放在`reactive`函数中来管理。引用提到了不建议将方法也写在`reactive`函数中。 而`toRefs`函数在处理响应式数据时非常有用。它允许我们在模板或计算属性中访问响应式对象的属性,并保持属性的响应式特性。通常情况下,当我们将一个`reactive`对象传递给子组件时,子组件无法正确地追踪响应式对象的属性的变化。但是,我们可以使用`toRefs`将`reactive`对象的属性转换为普通的响应式引用对象,从而解决这个问题。这样,在子组件中使用这些属性时,就能够获得正确的响应式特性。引用中提到了结合`ref`、`reactive`和`toRefs`的使用能够更灵活地管理组件的状态和响应。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [VUE3 reactivetoRefs函数](https://blog.csdn.net/hsany330/article/details/120134550)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *3* [Vue 3 中的 toRefs响应式数据的关键函数](https://download.csdn.net/download/qq_29901385/88105478)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

骑着骆驼去南极

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值