2024.1.20更新博客:
更新内容:在工作中的实际应用示例,更新在文章最底部
假期第四篇,对于基础的知识点,我感觉自己还是很薄弱的。
趁着假期,再去复习一遍
1、toRef与toRefs
创建一个ref对象,其value值指向另一个对象中的某个属性
语法:const name = toRef(person,‘name’)
应用:要将响应式对象中的某个属性单独提供给外部使用时
扩展:toRefs与toRef功能一致,但可以批量创建多个ref对象,语法:toRefs(person)
示例:当定义penson为响应式对象时,再定义一个变量去接收对象中的某个值,
const name1 = person.name 这种方式name1不具有响应式
const name2 = toRef(person,‘name’) 这种方式name2具有响应式
<template>
<div>
<h2>姓名:{{ person.name }}</h2>
<h2>性别:{{ person.sex }}</h2>
<h2>工作:{{ person.job.job1.work }}</h2>
<button @click="person.name += '~'">姓名变了</button>
<br />
<button @click="person.sex += '!'">性别变了</button>
<br />
<button @click="person.job.job1.work += '还有其他工作'">工作变了</button>
</div>
</template>
<script >
import { ref, reactive,toRef } from "vue";
export default {
name: "demo",
setup() {
let person = reactive({
name: "莲花",
sex: "男",
job: {
job1: {
work: "侦探",
},
},
});
const name1 = person.name;
console.log(name1, "name1");
const name2 = toRef(person,'name')
console.log(name2, "name2");
return {
person,
};
},
};
</script>
<style scoped></style>
如果模板区想简化成这样
<template>
<div>
<h2>姓名:{{ name }}</h2>
<h2>性别:{{ sex }}</h2>
<h2>工作:{{ work }}</h2>
<button @click="name += '~'">姓名变了</button>
<br />
<button @click="sex += '!'">性别变了</button>
<br />
<button @click="work += '还有其他工作'">工作变了</button>
</div>
</template>
<script >
就要用到toRef
<script >
import { ref, reactive, toRef } from "vue";
export default {
name: "demo",
setup() {
let person = reactive({
name: "莲花",
sex: "男",
job: {
job1: {
work: "侦探",
},
},
});
const name1 = person.name;
console.log(name1, "name1");
const name2 = toRef(person, "name");
console.log(name2, "name2");
return {
//toRef接收的第一个参数是对象,第二个是属性键
name: toRef(person, "name"),
sex: toRef(person, "sex"),
work: toRef(person.job.job1, "work"),
};
},
};
</script>
ref直接使用似乎也能达到相似的效果,但是可以替换为ref写法吗?答案是不可以
如果替换为ref的写法,只有在初始化的时候才会读取person中定义的属性,之后修改person中的属性,改的根本不是person中定义的属性,而是return中新定义出来ref包裹的属性。
在模板区将person对象展示出来,然后点击三个按钮,看下打印出来的结果
三个按钮随意点击,页面已经变化了,但是person对象还是原来的
再换成toRef
person对象也一起发生了改变
toRef一次只能处理一个属性,toRefs可以批量处理一个对象中的所有属性
…扩展运算符只能拿到第一层,所以模板区的work,从job开始往下点,job.job1.work
toRef的本质是引用,保持住和源对象的连接关系,维持通话,进行一个桥接,
toRef 创建的引用是对已有对象的属性的引用。因此,在修改 toRef 返回的引用时,会直接修改原始对象中的属性。
ref的本质是拷贝,将对象中的属性读取出来,打包成一个新的ref,和原来的不再有连接关系。
ref 适用于创建可变的单个值的响应式数据,而 toRef 用于获取已有响应式对象中特定属性的引用,并关注该属性的变化。
2024.1.20更新:
对于新知识的学习,初次接触概念性的东西,即使当下觉得自己理解了,但是很多时候的状态都是一学就会,一用就废。
最能让我印象深刻的,都是在实际项目中的应用,当我遇到痛点,无法解决,在经历了磨人的解决过程后会发现,原来概念性的东西是因为遇到了什么问题,能去解决这样的问题,这个时候才能去理解原来是这么使用的,原来区别是这样的。
1、假设有一个响应式的对象。
<script lang="ts" setup>
import { reactive } from "vue";
const formData = reactive({
name: "春夏",
grade: "高三",
age: 19,
address: "尔滨冰雪大世界",
gender: "2",
describe: "品学兼优",
animalYear: "龙",
school: "尔滨第一高中",
});
</script>
2、假设在页面中展示的时候不想写formData.name,formData.grade,formData.age,就想直接写name,grade,age(主要是隔太久了,具体的需求已经想不起来了,先说个简单点的演示下问题)
<template>
<div>{{ name }}-- {{ grade }}-- {{ age }}--</div>
<button @click="gotoUniversity" style="width: 120px; background: skyblue">
</template>
<script lang="ts" setup>
import { reactive } from "vue";
const formData = reactive({
name: "春夏",
grade: "高三",
age: 19,
address: "尔滨冰雪大世界",
gender: "2",
describe: "品学兼优",
animalYear: "龙",
school: "尔滨第一高中",
});
let {name,grade,age} = formData
</script>
页面中展示
点击去上大学按钮,改变formData 中的数据
function gotoUniversity() {
name = "秋冬";
grade = "大学";
age = 20;
console.log(name,grade,age, "name,grade,age");
}
数据改变了但是页面没变
是因为let {name,grade,age} = formData 这一行代码相当于
let name = formData .name
let grade= formData .grade
let age= formData .age
formData 对象是响应式的,但是name ,age,grade相当于是自己定义的变量,不具有响应式。所以我们操作name ,age,grade的修改,只是在操作我们自己定义的变量,和formData 对象是没有关系的。
要解决,就要用到toRefs,
let {name,grade,age} =toRefs(formData )
或者等价写法toRef
let {name} =toRef(formData ,name)
let {grade} =toRef(formData,grade )
let {age} =toRef(formData,age )
完整代码:
<template>
<div>{{ name }}-- {{ grade }}-- {{ age }}--</div>
<button @click="gotoUniversity" style="width: 120px; background: skyblue">
去上大学
</button>
</template>
<script lang="ts" setup>
import { reactive, toRefs } from "vue";
let formData = reactive({
name: "春夏",
grade: "高三",
age: 19,
address: "尔滨冰雪大世界",
gender: "2",
describe: "品学兼优",
animalYear: "龙",
school: "尔滨第一高中",
});
let { name, grade, age } = toRefs(formData);
function gotoUniversity() {
name.value = "秋冬";
grade.value = "大学";
age.value = 20;
console.log(name, grade, age, "name,grade,age");
}
</script>
页面更新,打印的结果都是ref定义的响应式对象,所以赋值的时候别忘了加.value