Vue3如何理解ref toRef和toRefs的区别

2022-04-15 0 797
目录
  • 一、基础
    • 1.ref
    • 2.toRef
  • 3.toRefs
    • 4.最佳的使用方式
      • 二、深入
        • 1.为什么需要ref
        • 2.ref为什么需要.value
        • 3.为什么需要toRef和toRefs

      Vue3中新增了几种创建响应式数据的方法,其各自的作用当然也不尽相同,每一种方法都有其自己的应用场景,今天我们来聊聊什么是ref toRef和toRefs?三者在使用方式上有什么不同?最佳的使用方式是什么?

      一、基础

      1.ref

      (1) 生成值类型的响应式数据, 通过 .value修改值

      <template>
       <div>{{ ageRef }}</div>
      </template>
      
      <script>
      import { ref } from 'vue'
      export default {
       setup() {
        const ageRef = ref(20)
      
        setInterval(() => {
         ageRef.value += 1
        }, 1000)
        
        return {
         ageRef
        }
       },
      }
      </script>
      
      

      上面这段代码,定义了一个ageRef变量,并每秒将ageRef加1,页面展示的数值也会加1.

      (2) 可用于reactive中

      将上面的代码改动如下, 引入reactive定义变量,将ref定义的变量引入reactive中, 模板中展示reactive的变量. 最后的效果和上面(1)的一样

      <template>
       <div>{{ info.age }}</div>
      </template>
      
      <script>
      import { ref, reactive } from 'vue'
      export default {
       setup() {
        const ageRef = ref(20)
        const info = reactive({
         age: ageRef
        })
        setInterval(() => {
         ageRef.value += 1
        }, 1000)
        
        return {
         info
        }
       },
      }
      </script>
      
      

      (3) 可用于获取Dom

      <template>
       <div ref="eleDom">ref-dom-test</div>
      </template>
      
      <script>
      import { ref, onMounted } from 'vue'
      export default {
       setup() {
        const eleDom = ref(null)
        onMounted(() => {
         console.log(eleDom.value.innerHTML) // ref-dom-test
        })
        return {
         eleDom 
        }
       },
      }
      
      

      上面代码控制台输出ref-dom-test, 说明获取到了Dom元素.
      要获取Dom元素必须要符合以下规则

      定义的ref变量名必须要和模板中ref中的值一致,如代码中的eleDom

      2.toRef

      • 针对一个响应式对象的prop
      • 创建一个ref,具有响应式
      • 两者保持引用关系

      我们来看下面这段代码

      <template>
       <div>{{ state.age }} --- {{ ageRef }}</div>
      </template>
      
      <script>
      import { toRef, reactive } from 'vue'
      export default {
       setup() {
        const state = reactive({
         name: 'JL',
         age: 18
        })
        const ageRef = toRef(state, 'age')
        setTimeout(() => {
         state.age = 20
        }, 1000)
        
        setTimeout(() => {
         ageRef.value = 21
        }, 2000)
        
        return {
         state,
         ageRef
        }
       },
      }
      </script>
      
      

      上面的代码中,使用toRef将state的age属性变成一个响应式变量,然后在1秒后将state的age值变为20,此时ageRef也会变成20;在2秒后将ageRef的值变为21,此时state的age值也会变成21,说明了两者保持相互引用关系

      toRef针对的是响应式,针对的不是普通对象,如果用于非响应式,产出的结果不具有响应式

      3.toRefs

      • 将一个响应式对象转为普通对象
      • 对象的每一个属性都是对应的ref
      • 两者保持引用关系

      我们来看下面这段代码

      <template>
       <div>{{ name }}---{{ age }}</div>
      </template>
      
      <script>
      import { reactive, toRefs } from 'vue'
      export default {
       setup() {
        const state = reactive({
         name: 'JL',
         age: 18
        })
      
        const stateRefs = toRefs(state)
      
        setTimeout(() => {
         state.age = 20
        }, 1000)
      
        setTimeout(() => {
         stateRefs.age.value = 21
        }, 2000)
      
        return stateRefs
       },
      }
      </script>
      
      

      上面的代码中,使用toRefs将state转变成一个普通对象,这时候就可以直接返回stateRefs,这时候在template就可以直接调用name和age。然后在1秒后将state的age值变为20,此时页面中的age也会变成20;在2秒后将stateRefs中的name的值变为21,此时页面中的age值也会变成21,说明了两者保持相互引用关系

      toRefs将响应式对象变成普通对象后,每一个属性都具有响应式ref,此时需要使用 .value才能获取其值

      4.最佳的使用方式

      • reactive做对象的响应式,ref做值类型响应式
      • setup中返回toRefs(state), 或者toRef(state, ‘xxx’)—(这样就能够在template中不使用state.xxx)
      • ref的变量命名都用xxxRef
      • 合成函数返回响应式对象时,使用toRefs

      例如:

      <template>
       <div>x:{{x}} y:{{y}}</div>
      </template>
      
      <script>
      import { reactive, toRefs } from 'vue'
      export default {
       setup() {
        function test() {
         const state = reactive({
          x: 1,
          y: 2
         })
         return toRefs(state)
        }
        const {x, y} = test()
      
        setTimeout(() => {
         x.value = 2
        }, 1000)
      
        return {
         x,
         y
        }
       }
      }
      </script>
      
      

      上面的代码,test函数中定义了响应式对象state,并通过toRefs将其转为普通对象并返回,这时候可以结构赋值,并且值是响应式的

      二、深入

      1.为什么需要ref

      在上面我们讲到,使用reactive和toRef也可以将值类型转换成响应式的,为什么还需要ref呢?

      • 值类型不具有响应式(proxy)
      • setup()、computed()…都可能返回值类型,如果vue不定义ref,用户需要响应式的值类型的时候就会通过其他方式(reactive/toRef, reactive/toRefs)自造ref,就会造成代码更混乱

      2.ref为什么需要.value

      ref为什么需要加一个.value来获取值呢?为什么要这么麻烦呢?

      • ref是一个对象(不会丢失响应式),value存储值
      • 通过.value属性的get和set来实现响应式
      • 用于reactive和模板(vue编译)的时候不需要.value,其他情况都需要

      3.为什么需要toRef和toRefs

      • 初衷: 在不丢失响应式的前提下,对对象数据进行解构
      • 前提: 针对的是响应式对象,不是普通对象
      • 结果: 不创造响应式,只延续响应式

      到此这篇关于Vue3如何理解ref toRef和toRefs的区别的文章就介绍到这了,更多相关Vue3 ref toRef和toRefs内容请搜索NICE源码以前的文章或继续浏览下面的相关文章希望大家以后多多支持NICE源码!

      免责声明:
      1、本网站所有发布的源码、软件和资料均为收集各大资源网站整理而来;仅限用于学习和研究目的,您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。 不得使用于非法商业用途,不得违反国家法律。否则后果自负!

      2、本站信息来自网络,版权争议与本站无关。一切关于该资源商业行为与www.niceym.com无关。
      如果您喜欢该程序,请支持正版源码、软件,购买注册,得到更好的正版服务。
      如有侵犯你版权的,请邮件与我们联系处理(邮箱:skknet@qq.com),本站将立即改正。

      NICE源码网 JavaScript Vue3如何理解ref toRef和toRefs的区别 https://www.niceym.com/22204.html