当前位置:主页 > 网页前端 > vue >

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

时间:2022-02-19 09:39:16 | 栏目:vue | 点击:

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

我们来看下面这段代码

<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

我们来看下面这段代码

<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.最佳的使用方式

例如:

<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呢?

2.ref为什么需要.value

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

3.为什么需要toRef和toRefs

您可能感兴趣的文章:

相关文章