Vue3 理解 toRef 和 toRefs 的作用、用法、区别

toRef / toRefs

作用

toReftoRefs 可以用来复制 reactive 里面的属性然后转成 ref,而且它既保留了响应式,也保留了引用,也就是你从 reactive 复制过来的属性进行修改后,除了视图会更新,原有 ractive 里面对应的值也会跟着更新,如果你知道 浅拷贝 的话那么这个引用就很好理解了,它复制的其实就是引用 + 响应式 ref
不加 s 和 加 s 的区别就是这样:

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

下面我会为这两个属性举一些使用案例

使用方式

toRef

<template>
  <h2>
    reactive-greet: {
    
    {
    
     info.greet }} 
  </h2>
  <h2>
    toRef-greet: {
    
    {
    
     rGreet }}
  </h2>
  <button @click="onChangeGreet">更换问候语</button>
</template>

<script>
import {
    
     reactive, toRef } from 'vue'
export default {
    
    
	setup() {
    
    
    let info = reactive({
    
    
      name: 'Tony',
      greet: 'Hello'
    })
	// 复制 info 里的 greet 属性
    let rGreet = toRef(info, 'greet')
    // 更改 rGreet
    const onChangeGreet = () => {
    
    
      rGreet.value = 'world!'
    }
    return {
    
    
      info,
      rGreet,
      onChangeGreet
    }
  }
}
</script>

效果:
在这里插入图片描述

我们可以看到,更改了 rRgeet 也同时更改了原有的 info.greet 属性

toRefs

<template>
  <h2>
    reactive-info-greet: {
    
    {
    
     info.greet }} 
  </h2>
  // 要带上 .value
  <h2>
    toRefs-rInfo-greet: {
    
    {
    
     rInfo.greet.value }}
  </h2>
  <button @click="onChangeGreet">更新</button>
</template>

<script>
import {
    
     reactive, toRefs } from 'vue'
export default {
    
    
	setup() {
    
    
    let info = reactive({
    
    
      name: 'Tony',
      greet: 'Hello'
    })
	// 复制整个 info
    let rInfo = toRefs(info)
    // 更改 rInfo.greet
    const onChangeGreet = () => {
    
    
      rInfo.greet.value = 'world!'
    }
    return {
    
    
      info,
      rInfo,
      onChangeGreet
    }
  }
}
</script>

在这里插入图片描述

怎么样,是不是很简单,这两个属性作用是一样的,唯一的区别就是访问方式不同

  • template 要想访问 toRefs 的值,需要带上 .value 如果不带上,就会出现双引号。
  • template 要想访问 toRef 的值,不需要带上 .value

可能有的小伙伴会问了,那这两个属性实际应用场景中有啥作用呢?
这个用处可多了,这里简单举一个封装获取计算鼠标移动位置

<template>
  <h2>
    x: {
    
    {
    
     x }}
  </h2>
  <h2>
    y: {
    
    {
    
     y }}
  </h2>
</template>

<script>
import {
    
     reactive, toRefs } from 'vue'
export default {
    
    
	setup() {
    
    
    // 封装位置函数
    function usePosition(state, x, y) {
    
    
      const position = reactive({
    
    
        x: 0,
        y: 0
      })
      // 绑定鼠标移动事件
      const onMouseMove = (event) => {
    
    
        position.x = event.x
        position.y = event.y
      }
      window.addEventListener('mousemove', onMouseMove)
      
      // 返回出去
      return toRefs(position)
    }
    
    // 接受 x, y 位置
    const {
    
    x, y} = usePosition()
    return {
    
    
      x,
      y
    }
  }
}
</script>

在这里插入图片描述

我们可以看到,案例中将提前封装好的 usePosition 函数通过 toRefs 返回一个响应式的数据,然后直接拿来就用。

我们还可以将它放到 js 文件里面去,在需要的地方引入进来即可,无需再去重复声明,笔者甚至认为这两属性就是用来避免重复声明 reactive 的。

好了,内容就这么多,喜欢就点个小赞,欢迎有问题的小伙伴到下方评论。

上一篇文章是:Vue3 理解 ref 和 reactive 的用法、区别

猜你喜欢

转载自blog.csdn.net/cookcyq__/article/details/121618833