🕒携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1
天
来自网友的的指正,这是第四
次修改
Vue 3 的 Composition API 提供了两种主要的方式来声明响应式数据:ref
和reactive
.
✏️ 这些有什么区别?
✏️ 实际项目中如何合理选择?
1.是什么ref
?
官方的解释是这样的
看个例子:
<template>
<div>数值类型:{{number}}</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup () {
let number = ref(0)
console.log('ref对象', number)
console.log('取值', number.value)
return {
number
}
}
}
</script>
我这分别把ref对象和值打印出来了,看看返回的响应式对象到底啥样
❗️新手的易错点:
一个很大的“陷阱”, ref
是在 JavaScript 中访问值与在模板中访问它是不同的
🍓模板
<h1>{{ number.value }}</h1> <!--❌-->
<h1>{{ number }}</h1> <!--✔️-->
🍑js
<script>
import { ref } from 'vue'
export default {
setup () {
let number = ref(0)
console.log('取值', number.value)<!--❗️取值需要.value❗️-->
return {
number
}
}
}
</script>
❓提问环节:
1.可以接受的值有哪些?
答:
基本数据类型和对象类型
2.基本数据类型怎么实现响应式?
答:
依靠Object.defineProperty()
的get
与set
完成
3.对象类型怎么实现响应式?
答:
内部求助
了vue3一个新的函数叫reactive
函数
2. 是什么reactive
?
官方解释:
<template>
<div>姓名:{{obj.name}}</div>
<div>年龄:{{obj.age}}</div>
</template>
<script>
import { reactive } from 'vue'
export default {
setup () {
let obj = reactive({
name: '葱头',
age: 28
})
console.log('reactive对象', obj)
console.log('取值', obj.name)
return {
obj
}
}
}
</script>
我这分别把reactive对象和值打印出来了,看看返回的响应式对象到底啥样
❗️新手的易错点:
最大的“陷阱”reactive
可能会诱使您解构对象,尤其是当它是从另一个文件中的函数返回时
❌
<template>
<div>姓名:{{obj.name}}</div>
<div>年龄:{{obj.age}}</div>
</template>
<script>
import { reactive } from 'vue'
export default {
setup () {
let obj = reactive({
name: '葱头',
age: 28
})
let { age } = obj
console.log(age)
age++
console.log(age)
return {
obj
}
}
}
</script>
响应式丢失了 ❗️ ❗️ ❗️ ,那我这个怎么写?,往下看
<template>
<div>姓名:{{obj.name}}</div>
<div>年龄:{{obj.age}}</div>
</template>
<script>
import { reactive } from 'vue'
export default {
setup () {
let obj = reactive({
name: '葱头',
age: 28
})
obj.age++
return {
obj
}
}
}
</script>
❓提问环节:有的小伙伴说为啥?
我们分析一下:
首先看一下log,我们发现这个返回的响应式对象为什么没有变化,我明明+1了呀
我给大家看一下原因
let { age } = obj
age++
实际是这样的
let duixing={
name: '葱头',
age: 28
}
duixing.age++
你操作的不是响应式的对象,你操作的是{name: '葱头',age: 28}中的age变量,
人家响应式是这样的 Proxy {name: '葱头', age: 28},所以解构会失去响应式!!!
前端小菜鸡之青岛分鸡同学反馈看不懂上面的,那我一起看看下面代码
const obj1 = {
age: 28
}
const handler = {
get: function (target, key) {
console.log('get--', key)
return Reflect.get(...arguments)
},
set: function (target, key, value) {
console.log('set--', key, '=', value)
return Reflect.set(...arguments)
}
}
const data = new Proxy(obj1, handler)
// 这种方法是错误的,不能解构
let { age } = data
age++
console.log(age, '错误age')
console.log(data, '错误data')
console.log(data.age, '错误data.age')
// 正确的方法是这样些的
data.age++
console.log(age, '正确的age')
console.log(data, '正确的data')
console.log(data.age, '正确的data.age')
下面是夏2同学提出的,让我增加建议补充下reactive的响应式版本的解构,安排
❓toRefs 是什么?
toRefs可以将对象(只能接收rective对象
)中的属性变成响应式,正常reactive对象数据也是响应式的,如果用toRefs解构出去会更加方便
❓什么时候用?
数据量如果很多
, 我们一般会用解构来简化代码, 那么在vue3 中如果使用对象的解构, 会让改对象失去响应式, 所有一般解构的时候 借助 toRefs 来解构 仍然带有响应式解构后
, 我们就不需要用对象属性了, 而是可以直接使用属性,来简化
看一下例子
<script setup>
import { reactive,toRefs } from 'vue'
const obj = reactive({
name:'给葱头点个赞吧,谢谢小哥哥小姐姐啦',
age:'27'
})
const {name} = toRefs(obj)
</script>
<template>
<h1>{{ name }}</h1>
<input v-model="name">
</template>
3.应该使用ref
orreactive
?
1.首先看一下各自的优点?
ref
优点:
- 适合传递单个变量
- 避免解构陷阱
reactive
优点:
- 适合声明大量反应变量
- JavaScript 和模板之间的一致性
- 跟 Vue 2 的数据对象很相似
2.讲了这么多,到底用啥?
在开发一个项目的时候最好选择一个,通常选择ref
,因为它更灵活,看我们之前的图片可见ref不光能处理常见的数据类型,处理对象可以求助reactive函数
,简直万能,直接给我盲选!!!