Vue3中,toRef与toRefs,以及使用其他方法return数据不可行的原因

本文详细解析Vue.js中toRef和toRefs的使用,阐述它们如何实现数据的响应式绑定。toRef用于创建一个ref对象,其value指向源数据的属性,而toRefs则适用于批量转换响应式对象的所有属性。通过实例分析,揭示直接使用源数据属性无法实现双向绑定的原因,并解释了ref包装后数据变化的原理。此外,还对比了使用ref直接包装对象时的潜在问题。
摘要由CSDN通过智能技术生成

toRef和toRefs的正确使用方式:

toRef

         toRef(person, 'name') 是个ref对象,里面有value值,将这个value值利用getter指向了person源数据,所以toRef是引用,ref是复制。
         操作后可以发现person中的源数据也是在同时变的

<template>
  <h2>姓名:{{name}}</h2>
  <h2>年龄:{{age}}</h2>
  <h2>job1薪资:{{salary}}</h2 -->
</template>
<script>
import { reactive, toRefs } from 'vue'
export default {
  name: 'DemoPerson',
  setup() {
    let person = reactive({
      name: '张珍',
      age: 18,
      job: {
        j1: {
          salary: 20
        }
      }
    })
    return {
      person,
      name: toRef(person, 'name'),
      age: toRef(person, 'age'),
      salary: toRef(person.job.j1, 'salary'),
    }
  }
}
</script>

<style>

</style>

toRefs

        toRefs适合操作有很多数据的情况;如果很多数据用toRef,则要一个个去操作。
        toRefs() 返回值是个对象,由于不能在一个对象中直接再放一个对象,所以需要用解构的方法将 toRefs() 返回的对象,全部摊开变成key-value;

<script>
import { reactive, toRefs } from 'vue'
export default {
  name: 'DemoPerson',
  setup() {
    let person = reactive({
      name: '张珍',
      age: 18,
      job: {
        j1: {
          salary: 20
        }
      }
    })
    return {
      ...toRefs(person)
    }
  }
}
</script>

<style>

</style>

对toRef() 及 toRefs() 的总结:
           作用:创建一个 ref 对象,其value值指向另一个对象中的某个属性。
           语法:const name = toRef(person,'name')
           应用:   要将响应式对象中的某个属性单独提供给外部使用时。
           扩展:toRefs 与 toRef 功能一致,但可以批量创建多个 ref 对象,
           语法:toRefs(person)

接下来做一些其他的分析

我们在return数据时可能会觉得不用toRef()来操作,但是却发现是不可行的。

那就来分析一下,为什么不可行。

情况一:

  为什么直接用person.xxx作为值赋给变量,却看不到数据的变化? 

<template>
  <h2>姓名:{{name}}</h2>
  <h2>年龄:{{age}}</h2>
  <h2>job1薪资:{{salary}}</h2 -->
</template>
<script>
import { reactive, toRefs } from 'vue'
export default {
  name: 'DemoPerson',
  setup() {
    let person = reactive({
      name: '张珍',
      age: 18,
      job: {
        j1: {
          salary: 20
        }
      }
    })
    return {
       name: person.name,
       age: person.age,
       salary: person.job.j1.salary,
    }
</script>

分析:

let p = new Proxy(person, {
    set(target, props, value) {
        console.log(`${props}被修改了,更新!`)
        Reflect.set(target, props, value)
    }
})
// 通过p取出来name,交给了变量name
let name = p.name

我们到控制台:

        1. 输入:p,得到结果:Proxy {name: '张珍', age: 18},是没问题的。

                

        2. 再输入person,得到结果:{name: '张珍', age: 18},也是没问题的;

                

        3. 再输入变量name,得到结果:'张珍', 仍然没问题;

                

            我们再修改name,name = '李四' ,得到结果:'李四'

                

        但是, 此时修改name = '李四',改的是name这个变量!
        我们可以通过输入p和person来验证一下:

        

        可以看到p和person中,name属性的值仍然是'张珍'。
        这是什么原因呢?
               name是自己新定义的一个变量:let name = p.name,这种方式就相当于直接写了 let name = '张珍',p.name就相当于一个字符串,然后给了name变量,是没有引用关系的。
               就相当于:
                    let obj = { a: 100 }
                    let x = obj.a
                    x = 200
                变量x确实会变成200, 但是obj中的a是不变的
           所以:
                 name: person.name   中 person.name就是个字符串 相当于name: '张珍'
                 retrun {
                        name: person.name
                }
                return的内容就是返回了一个普通的对象!无法实现双向绑定

情况二:

        为什么用ref,看到数据仍然可以变化,但是却不能直接用ref?

<template>
  <h2>{{person}}</h2>
  <h2>姓名:{{name}}</h2>
  <h2>年龄:{{age}}</h2>
  <h2>job1薪资:{{salary}}</h2>
</template>
<script>
import { reactive, toRefs } from 'vue'
export default {
  name: 'DemoPerson',
  setup() {
    let person = reactive({
      name: '张珍',
      age: 18,
      job: {
        j1: {
          salary: 20
        }
      }
    })
    return {
      person,
      name: ref(person.name),
      age: ref(person.age),
      salary: ref(person.job.j1.salary)
    }
  }
}
</script>

<style>

</style>

     这是什么原因呢?

        用 ref(person.name) 读取出来的字符串'张珍',是打包成了一个新的ref,页面上读取的是新的ref的数据,但是实际上源数据person是没有变化的。

        即:name: ref(person.name), // 虽然显示的是张珍~~
               person, // 但是源数据person中name的值还是张珍,数据丝毫不变。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值