速来和我一起rush ref和reactive !!!🎉Vue 开发者们,“速来和我一起 rush ref 和 re
首先我们需要知道在Vue
中,ref
和reactive
是用来创建响应式数据的,大白话就是如果你用了他们去创建一个变量或者对象时,Vue会对他们进行特殊处理,以便在数据发生改变时能够及时察觉.
接下来我们来分别介绍一下他们是什么?
🐟ref和reactive是什么?
1.🐟ref
ref
是一个用于创造响应式引用的方法,它可以创造定义基本类型和对象类型的响应式数据,但是它通常用于包装基本数据类型(string,Number,boolean
),时期能被vue的响应式系统追踪并更新.
2.🐟reactive
reactive是一个用于创造响应式对象的方法,它只可以创建对象类型的响应式数据,适用于复杂的数据对象,如包含多个属性和嵌套对象的情况。
下面我们来看一段代码,理解一下他们的作用
<template>
<div>
<h2>{{ a }}</h2>
<button @click="changeA">改变a的值</button>
<h2>{{ obj.num }}</h2>
<button @click="changeB">改变b的值</button>
</div>
</template>
<script setup>
let a = 123
let obj = { num: 123 }
const changeA = () => {
a = 456
}
const changeB = () => {
obj.num = 456
}
</script>
<style lang="scss" scoped></style>
这里补充一个知识点 {{}}是一种模板语法,称为插值表达式,用于在模板中显示Vue实例中的数据,当Vue中的数据发生变化时,插值表达式中的内容会自动更新,实现视图和数据的同步
我们创建了一个数字变量a
和一个包含num
属性的对象 obj
,同时还定义了两个函数 changeA
和 changeB
分别绑定到了两个button
身上。
changeA
函数用于将变量a
的值从123
改为456
。changeB
函数用于将对象obj
的num
属性的值从123
改为456
。
但是我们去按这两个按钮,会发现视图上的数据不会发生任何变化,还都是 123
,这是因为在普通的js环境中单纯,这样的修改不会自动触发任何视图更新。但如果是在 Vue 的环境中,使用 ref
或 reactive
创建响应式数据后,对响应式数据的修改会自动触发相关视图的更新
我们现在加上ref
和reactive
试试
<template>
<div>
<h2>{{ a }}</h2>
<button @click="changeA">改变a的值</button>
<h2>{{ obj.num }}</h2>
<button @click="changeB">改变b的值</button>
</div>
</template>
<script setup>
import { ref, reactive } from "vue"; // 导入ref和reactive函数
let a = ref(123)
let obj = reactive({ num: 123 })
const changeA = () => {
a.value = 456
}
const changeB = () => {
obj.num = 456
}
</script>
可以看到我们加了响应式之后,修改成功了变量a,和对象b的值,只有你加了响应式上去,数据更新才能带动视图更新,才会有交互效果。
🐟他们的不同
记住用ref函数的时候,你定义的变量需要加value去访问,如果你嫌麻烦,你可以在vscode的扩展里下载一个插件volar,将扩展应用于所有配置文件
然后再点击 设置--找到扩展--再找到volar,然后找到这个
把它勾上之后x,以后如果用ref,他就会自动给你加.value
我们在前文提了ref是即可用于基本类型也可以用于对象属性的,我们把obj对象也用ref去创建响应式试试,
只需要加上value,然后再去访问他身上的属性即可,这个时候我就很好奇这两个ref创建的变量和对象,会有什么不一样吗,我们去console.log他们
发现他们都是 RefImpl这个内部实现类的实例,但是再点开看看你会发现,他们是不一样的,
数字变量a的_value是 456 但是 对象b的不是,他是 Proxy(Object) {num: 456},说明ref
包装的内部值是一个通过reactive
创建的响应式对象,因为你输出一个reactive
函数创建的,输出这个对象也是Proxy对象.
当给reactive重新分配一个新对象,会失去响应式,可以使用Object.assign去整体替换
先看下面一段代码,如果让你去设置一个换人的函数,你会怎么写?
<div>
<h2>{{ person.id }} {{ person.name }}</h2>
<button @click="changeid">改变id的值</button>
<button @click="changename">改变name的值</button>
</div>
</template>
<script setup>
import { ref, reactive } from "vue"; // 导入ref和reactive函数
let person = reactive({ id: 123, name: '张三' })
const changeid = () => {
person.id = 456
}
const changename = () => {
person.name = 李四
}
</script>
<style lang="scss" scoped></style>
大概率是直接写一个
const changeperson = () => {
person = reactive({ id: 789, name: '王五' })
}
然后往html里添加一个button去绑定这个函数,从而实现换人的操作,我们来试一试这样行不行
结果是失败的,这样做不到更换这个对象,
当你执行person = { id: 789, name: '王五' }
时,实际上是创建了一个新的普通对象并尝试将其赋值给person
,这不会触发响应式更新,并且会导致 Vue 失去对原来那个响应式对象的跟踪。要正确修改整个对象,可以使用Object.assign
来更新对象
const changeperson = () => {
Object.assign(person, { id: 789, name: '王五' })
}
这样就实现了,呢如果是用ref
定义的呢,修改需要像这样操作吗,答案是不需要的
<template>
<div>
<h2>{{ person.id }} {{ person.name }}</h2>
<button @click="changeid">改变id的值</button>
<button @click="changename">改变name的值</button>
<button @click="changeperson">改变person这个对象 </button>
</div>
</template>
<script setup>
import { ref, reactive } from "vue"; // 导入ref和reactive函数
let person = ref({ id: 123, name: '张三' })
console.log(person);
const changeid = () => {
person.value.id = 456
}
const changename = () => {
person.value.name = 李四
}
const changeperson = () => {
person.value = { id: 789, name: '王五' }
}
</script>
<style lang="scss" scoped></style>
直接给person.value
赋一个对象即可.是不是方便很多
🐟使用原则
- 1.若需要使用一个基本类型的响应式数据,必须使用
ref
- 2.若需要一个响应式对象,层级不深,
ref,reactive
都可以 - 3.若需要一个响应式对象,层级比较深,推荐使用
reactive.
🐟总结
总之,ref
和reactive
在 Vue 的响应式系统中都起着关键作用,开发者可以根据具体的需求场景选择合适的方式,来创建响应式数据,以实现高效的数据驱动视图更新。
转载自:https://juejin.cn/post/7426697740594462772