知道大家使用 Vue3 的时候有没有这样的疑惑,“ref、rective 都能创建一个响应式对象,我该如何选择?”,“为什么响应式对象解构之后就失去了响应式?应该如何处理?” 今天咱们就来全面盘点一下 ref、reactive,相信看完你一定会有不一样的收获,一起学起来吧!
reactive()
基本用法
在 Vue3 中我们可以使用 reactive()
创建一个响应式对象或数组:
import {
reactive } from 'vue'
const state = reactive({
count: 0 })
这个响应式对象其实就是一个 Proxy
, Vue 会在这个 Proxy
的属性被访问时收集副作用,属性被修改时触发副作用。
要在组件模板中使用响应式状态,需要在 setup()
函数中定义并返回。
<script>
import {
reactive } from 'vue'
export default {
setup() {
const state = reactive({
count: 0 }) return {
state } }}
</script>
<template>
<div>{
{ state.count }}</div>
</template>
当然,也可以使用 <script setup>
,<script setup>
中顶层的导入和变量声明可以在模板中直接使用。
<script setup>
import {
reactive } from 'vue'
const state = reactive({
count: 0 })
</script>
<template>
<div>{
{ state.count }}</div>
</template>
响应式代理 vs 原始对象
reactive()
返回的是一个原始对象的 Proxy
,他们是不相等的:
const raw = {
}
const proxy = reactive(raw)
console.log(proxy === raw) // false
原始对象在模板中也是可以使用的,但修改原始对象不会触发更新。因此,要使用 Vue 的响应式系统,就必须使用代理。
<script setup>
const state = {
count: 0 }
function add() {
state.count++
}
</script>
<template>
<button @click="add">
{
{
state.count }} <!-- 当点击button时,始终显示为 0 -->
</button>
</template>
为保证访问代理的一致性,对同一个原始对象调用 reactive()
会总是返回同样的代理对象,而对一个已存在的代理对象调用 reactive()
会返回其本身:
const raw = {
}
const proxy1 = reactive(raw)
const proxy2 = reactive(raw)
console.log(proxy1 === proxy2) // true
console.log(reactive(proxy1) === proxy1) // true
这个规则对嵌套对象也适用。依靠深层响应性,响应式对象内的嵌套对象依然是代理:
const raw = {
}
const proxy = reactive({
nested: raw })
const nested = reactive(raw)
console.log(proxy