1. toRef
:::success
- 作用:创建一个 ref 对象,其value值指向另一个对象中的某个属性。
- 语法:const name = toRef(person,’name’)
- 应用: 要将响应式对象中的某个属性单独提供给外部使用时。
- 扩展:toRefs与toRef功能一致,但可以批量创建多个 ref 对象,语法:toRefs(person)
:::
toRef 和 toRefs 可以用来复制 reactive 里面的属性然后转成 ref,而且它既保留了响应式,也保留了引用,也就是你从 reactive 复制过来的属性进行修改后,除了视图会更新,原有 ractive 里面对应的值也会跟着更新。
这样写初次展示并没有问题, 但是点击修改的时候并不会生效, 因此name:的属性值person.name其实是他的值IRIC, 他不是一个响应式的值。所以点击的时候并不会生效, 因为此时的name已经不是响应式数据了。<script>import { reactive } from 'vue'export default {setup() {const person = reactive({name:'IRIC',age:12,sex:'女',job:{salery:20}})console.log(person.name) //'IRIC'console.log(person) //Proxy {name: 'IRIC', age: 12, sex: '女', job: {…}}console.log(toRef(person, 'name')) //ObjectRefImpl {_object: Proxy, _key: 'name', _defaultValue: undefined, __v_isRef: true}return {name:person.name,age:person.age,salery:person.job.salery,}},}</script>
如果不使用toRef: ```javascript姓名:{{person.name}}
年龄{{person.age}}
性别{{person.sex}}
薪资{{person.job.selary}}
使用toRef:```javascript<template><h2>姓名:{{name}}</h2><h2>年龄:{{age}}</h2><h2>性别:{{sex}}</h2><h2>薪资:{{salery}}</h2><hr><button @click="name += '@'">修改姓名</button><button @click="age ++">修改年龄</button><button @click="salery ++">修改薪资</button></template><script>import { reactive, toRef } from 'vue'export default {setup() {const person = reactive({name:'IRIC',age:12,sex:'女',job:{salery:20}})const name = toRef(person, 'name');const age = toRef(person, 'age');const sex = toRef(person, 'sex');const salery = toRef(person.job, 'salery');return {name,age,sex,salery}},}</script>
如果改成这样:
<template><h2>姓名:{{name}}</h2><h2>年龄:{{age}}</h2><h2>性别:{{sex}}</h2><h2>薪资:{{job.salery}}</h2><hr><button @click="name += '@'">修改姓名</button><button @click="age ++">修改年龄</button><button @click="job.salery ++">修改薪资</button></template><script>import { reactive, toRef } from 'vue'export default {setup() {const person = reactive({name:'IRIC',age:12,sex:'女',job:{salery:20}})const name = toRef(person, 'name');const age = toRef(person, 'age');const sex = toRef(person, 'sex');const job = toRef(person, 'job');console.log(name)console.log(job)return {name,age,sex,job}},}</script>
name的value值是:
job依然是响应式的:
如果直接ref, 则出现数据分离问题;下面的数据和person不是同一个数据。造成原始数据不会发生变化。 被修改的是用ref重新定义的变量。
<template><h2>{{person}}</h2><h2>姓名:{{name}}</h2><h2>年龄:{{age}}</h2><h2>性别:{{sex}}</h2><h2>薪资:{{job.salery}}</h2><hr><button @click="name += '@'">修改姓名</button><button @click="age ++">修改年龄</button><button @click="job.salery ++">修改薪资</button></template><script>import { reactive, toRefs,ref } from 'vue'export default {setup() {const person = reactive({name:'IRIC',age:12,sex:'女',job:{salery:20},address:''})return {person,name: ref(person.name),age: ref(person.age),sex: ref(person.sex),job: ref(person.job)}},}</script>
2. toRefs:
<template><h2>姓名:{{name}}</h2><h2>年龄:{{age}}</h2><h2>性别:{{sex}}</h2><h2>薪资:{{job.salery}}</h2><hr><button @click="name += '@'">修改姓名</button><button @click="age ++">修改年龄</button><button @click="job.salery ++">修改薪资</button></template><script>import { reactive, toRefs } from 'vue'export default {setup() {const person = reactive({name:'IRIC',age:12,sex:'女',job:{salery:20}})return { ...toRefs(person) }},}</script>
3. ref和toRef的区别
(1). ref本质是拷贝,修改响应式数据不会影响原始数据;toRef的本质是引用关系,修改响应式数据会影响原始数据
(2). ref数据发生改变,界面会自动更新;toRef当数据发生改变是,界面不会自动更新
(3). toRef传参与ref不同;toRef接收两个参数,第一个参数是哪个对象,第二个参数是对象的哪个属性
toRef: 复制 reactive 里的单个属性并转成 ref
toRefs: 复制 reactive 里的所有属性并转成 ref
