toRef以及toRefs
- 作用:创建一个ref对象,其value值指向另一个对象中的某个属性。
- 语法:const name = toRef(obj,'name')
- 应用:要将响应式对象中的某个属性单独提供给外部使用时
- 拓展:toRefs与toRef功能一致,但可以批量创建多个ref对象,语法:toRefs(obj)
那什么时候用到呢?
举个例子:
<template>
<div>
<h1>姓名:{{obj.name}}</h1>
<h1>年龄:{{obj.age}}</h1>
<h1>薪资:{{obj.job.j1.salary}}K</h1>
<div>
<button @click="obj.name+='-'">修改姓名</button>
<button @click="obj.age++">修改年龄</button>
<button @click="obj.job.j1.salary+=10">修改薪资</button>
</div>
</div>
</template>
<script>
import {ref,reactive} from 'vue'
export default {
name: "Demo2",
setup(){
let obj = reactive({
name:'孙悟空',
age:99,
job:{
j1:{
salary:20
}
}
});
return {
obj
}
}
}
</script>
<style scoped>
</style>
以上实例可以看出,我们定义了一个obj,把它return出去后。页面上可以渲染出obj。但是如果要渲染出obj里面的一个属性,就必须{{obj.属性名}}。
那如何在插值语法里面,不通过obj.属性名,直接在插值里面写属性名的形式即可渲染呢?
我们可以在return的时候,直接return想要的属性名,而不是return整个对象。
return {
name:obj.name,
age:obj.age,
salary:obj.job.j1.salary
}
完整代码:
<template>
<div>
<h1>姓名:{{name}}</h1>
<h1>年龄:{{age}}</h1>
<h1>薪资:{{salary}}K</h1>
<div>
<button @click="name+='-'">修改姓名</button>
<button @click="age++">修改年龄</button>
<button @click="salary+=10">修改薪资</button>
</div>
</div>
</template>
<script>
import {ref,reactive} from 'vue'
export default {
name: "Demo2",
setup(){
let obj = reactive({
name:'孙悟空',
age:99,
job:{
j1:{
salary:20
}
}
});
return {
name:obj.name,
age:obj.age,
salary:obj.job.j1.salary
}
}
}
</script>
<style scoped>
</style>
效果图:
但是这时候,我们会发现一个问题。数据变成不是响应式得了。点击按钮,页面上并不会发生改变。这是为什么呢?
原因是return出去的name的值是一个字符串。也就是obj.name是一个字符串。所以这时候修改name,仅仅只是修改了字符串,并没有修改obj这个对象里面的name。
举个例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
</body>
<script>
let obj = {
name:'孙悟空',
age:99
}
let p = new Proxy(obj,{
set(target,propName,value){
console.log(`${propName}被修改了,准备更新界面`)
Reflect.set(target,propName,value)
}
})
let name = p.name
</script>
</html>
首先可以看到,通过p修改值的时候,数据依旧是响应式的。
但是如果这时候,let name = p.name。name值这时候是字符串孙悟空,如果这时候把name值进行修改,仅仅只是修改了孙悟空这个字符串,仅此而已。
所以为了解决这个问题。这时候就要使用toRef属性了。
语法:
第一步先引入:
import {toRef} from 'vue'
使用:
toRef(obj,"name")
我们来对比一下,使用toRef与不使用toRef得区别
let name = obj.name
console.log(`我是name`,name);
let name1 = toRef(obj,"name")
console.log(`我是name1`,name1);
可以看出不使用toRef是一个字符串,使用toRef是变成了一个ref对象,这时候修改ref对象里面的name,会帮我们做代理,去修改obj里面的name。
接下来说说toRefs
使用toRef过程中,会发现,toRef只能代理一个对象属性。
return {
name:toRef(obj,'name'),
age:toRef(obj,'age'),
salary:toRef(obj.job.j1,'salary'),
}
使用toRef可以代理这个对象下的所有属性
return {
...toRefs(obj)
}
完整代码:
<template>
<div>
<h1>姓名:{{name}}</h1>
<h1>年龄:{{age}}</h1>
<h1>薪资:{{obj.job.j1.salary}}K</h1>
<div>
<button @click="name+='-'">修改姓名</button>
<button @click="age++">修改年龄</button>
<button @click="obj.job.j1.salary+=10">修改薪资</button>
</div>
</div>
</template>
<script>
import {ref,reactive,toRef,toRefs} from 'vue'
export default {
name: "Demo2",
setup(){
let obj = reactive({
name:'孙悟空',
age:99,
job:{
j1:{
salary:20
}
}
});
let name = obj.name
console.log(`我是name`,name);
let name1 = toRef(obj,"name")
console.log(`我是name1`,name1);
return {
obj,
// name:toRef(obj,'name'),
// age:toRef(obj,'age'),
// salary:toRef(obj.job.j1,'salary'),
...toRefs(obj)
}
}
}
</script>
<style scoped>
</style>
以上就是toRef以及toRefs的基本使用
版权归原作者 天才小熊猫点、 所有, 如有侵权,请联系我们删除。