当前位置:   article > 正文

reactive和ref的异同、toRef和toRefs的使用

reactive和ref的异同、toRef和toRefs的使用

一、reactive和ref

有了reactive为什么还要ref?

ref处理起基本数据类型来更加的方便快捷,性能要更好。

ref 内部值的变化只会触发订阅它的副作用函数(effect)更新,而 reactive(Proxy) 内部对象的任何属性变化都会触发整个对象的重新渲染。

相同点:

  1. 都是 Vue 3 提供的用于创建响应式数据的函数;
  2. 在组件中都能够触发视图更新,实现数据的双向绑定。

不同点:

  1. 数据类型

    • reactive:主要用于处理对象或数组等复杂数据类型,将整个对象转为响应式对象;
    • ref:主要用于处理基本类型数据(如数字、字符串等)或单一值,将单一值转为响应式数据。
  2. 使用方式

    • reactive:接收一个普通对象作为参数,并返回一个包含响应式数据的代理对象。

      1. import { reactive } from 'vue';
      2. const state = reactive({
      3. count: 0
      4. });
    • ref:接收一个初始值作为参数,并返回一个包含响应式数据的引用对象。

      1. import { ref } from 'vue';
      2. const count = ref(0);
  3. 访问方式

    • reactive:直接通过对象属性访问。

      state.count++;
      
    • ref:需要通过 .value 属性来访问或修改值。

      count.value++;
      
  4. 特殊情况

    • ref 对象是通过 .value 来访问内部值的;而 reactive 返回的代理对象可以直接访问属性值。
    • 当需要监听一个基本类型的值时,通常会使用 ref;当需要监听一个对象或数组的多个属性时,使用 reactive 更方便。

ref里面放对象或者数组也是合法的,但可能会出现以下问题,所以最好还是用reactive。

  1. 内部值访问:由于 ref 对象内部的值是通过 .value 属性来访问的,因此如果你这样创建了一个 ref 对象:const myRef = ref({val: 1}),那么在访问该对象的值时需要通过 myRef.value.val 来获取属性值,这会使代码显得冗长和不够直观。

  2. 响应性ref 主要用于处理基本类型数据或单一值,而不是复杂对象。当使用 ref({val: 1}) 创建一个 ref 对象时,其内部的对象可能不会被完全响应化,即对象内部属性的变化可能不会触发视图更新。

  3. 深度监听:Vue 的响应式系统不会对对象进行深度监听,即对象内部嵌套的对象或数组的变化不会被自动追踪。因此,如果 ref 内部的对象包含深层次的属性,可能会导致部分属性的变化无法被及时监听到。

二、toRef / toRefs

作用
toRef 和 toRefs 可以用来复制 reactive 里面的属性然后转成 ref,而且它既保留了响应式,也保留了引用,也就是你从 reactive 复制过来的属性进行修改后,除了视图会更新,原有 ractive 里面对应的值也会跟着更新,浅拷贝,它复制的其实就是引用 + 响应式 ref。(这样的转换可以提高数据响应式的性能,使数据的访问和操作更加方便和直观)

不加 s 和 加 s 的区别就是这样:

toRef: 复制 reactive 里的单个属性并转成 ref;
toRefs: 复制 reactive 里的所有属性并转成 ref。

使用方式 

toRef

  1. <template>
  2. <h2>
  3. reactive-greet: {{ info.greet }}
  4. </h2>
  5. <h2>
  6. toRef-greet: {{ rGreet }}
  7. </h2>
  8. <button @click="onChangeGreet">更换问候语</button>
  9. </template>
  10. <script>
  11. import { reactive, toRef } from 'vue'
  12. export default {
  13. setup() {
  14. let info = reactive({
  15. name: 'Tony',
  16. greet: 'Hello'
  17. })
  18. // 复制 info 里的 greet 属性
  19. let rGreet = toRef(info, 'greet')
  20. // 更改 rGreet
  21. const onChangeGreet = () => {
  22. rGreet.value = 'world!'
  23. }
  24. return {
  25. info,
  26. rGreet,
  27. onChangeGreet
  28. }
  29. }
  30. }
  31. </script>

 更改 rRgeet 的同时更改了原有的 info.greet 属性

 toRefs

  1. <template>
  2. <h2>
  3. reactive-info-greet: {{ info.greet }}
  4. </h2>
  5. // 要带上 .value
  6. <h2>
  7. toRefs-rInfo-greet: {{ rInfo.greet.value }}
  8. </h2>
  9. <button @click="onChangeGreet">更新</button>
  10. </template>
  11. <script>
  12. import { reactive, toRefs } from 'vue'
  13. export default {
  14. setup() {
  15. let info = reactive({
  16. name: 'Tony',
  17. greet: 'Hello'
  18. })
  19. // 复制整个 info
  20. let rInfo = toRefs(info)
  21. // 更改 rInfo.greet
  22. const onChangeGreet = () => {
  23. rInfo.greet.value = 'world!'
  24. }
  25. return {
  26. info,
  27. rInfo,
  28. onChangeGreet
  29. }
  30. }
  31. }
  32. </script>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/324624
推荐阅读
相关标签
  

闽ICP备14008679号