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