1、解构proxy响应式对象
<template>
<a-button @click="add">add</a-button>
<div>{{ a }}</div>
<div>{{ b.c }}</div>
</template>
<script setup lang="ts">
let proxy = reactive({
a: 1,
b: {
c: 2
}
})
let { a, b } = proxy;
function add() {
a++;
b.c = 5
}
</script>
只有a属性时,a(基本数据类型)失去响应式,很神奇。有b存在时,b和a都具有响应式。
我们在图下可以看到b是一个响应式对象,a不是
解决方案
使用toRefs,消费者组件可以解构/展开返回的对象而不会失去响应性
(vue官网解释)
let { a } = toRefs(proxy);
function add() {
a.value++;
}
2、reactive定义的变量直接赋值(数组、对象等)
<template>
<a-button @click="change">add</a-button>
<div>{{ proxy.a }}</div>
<div>{{ proxy.b.c }}</div>
</template>
<script setup lang="ts">
let proxy = reactive({
a: 1,
b: {
c: 2,
},
});
function change() {
proxy = {
a: 2,
b: {
c: 5
}
};
}
</script>
我们在工具中可以看到proxy的值没有任何变化
场景复现:我们在初始化的时候,数据为空,调用接口后赋值,此时无法赋值成功
解决方案
- 使用ref声明对象
<template>
<a-button @click="change">add</a-button>
<div>{{ proxy.a }}</div>
<div>{{ proxy.b.c }}</div>
</template>
<script setup lang="ts">
let proxy = ref({
a: 1,
b: {
c: 2,
},
});
function change() {
proxy.value = {
a: 2,
b: {
c: 5
}
};
}
</script>
- 不直接赋值,包裹一层
<template>
<a-button @click="change">add</a-button>
<div>{{ proxy.data.a }}</div>
<div>{{ proxy.data.b.c }}</div>
</template>
<script setup lang="ts">
let proxy = reactive({
data: {
a: 1,
b: {
c: 2,
},
}
});
function change() {
proxy.data = {
a: 2,
b: {
c: 5
}
};
}
</script>
其他
其他实际业务中响应式丢失的情况,可以借助 computed() 来实现