一、reactive() 与 shallowReactive()
1、reactive 默认返回代理对象,且响应是深度转换的;
2、shallowReactive: 浅响应,响应只用于第一层属性;有坑注意;
示例:
<template>
<div id="app">
<p>stateReac:{{stateReac}}<button @click="changeStateReac">修改stateReac</button></p>
<p>shallowStateReac:{{shallowStateReac}}<button @click="changeShallowStateReac">修改shallowStateReac</button></p>
</div>
</template>
<script setup>
import { reactive,isProxy, shallowReactive } from 'vue'
const stateReac = reactive({
foo: 1,
bar: {
baz: 2,
quz: {
foobar: 3
}
}
})
const shallowStateReac = shallowReactive({
foo: 1,
bar: {
baz: 2,
quz: {
foobar: 3
}
}
})
//reactive()返回的对象,以及内部的嵌套属性都是Proxy,所以是深度响应的
console.log('stateReac',stateReac,isProxy(stateReac),isProxy(stateReac.foo),isProxy(stateReac.bar)) //true false true
// true false false
console.log('shallowStateReac',shallowStateReac,isProxy(shallowStateReac),isProxy(shallowStateReac.foo),isProxy(shallowStateReac.bar))
const changeStateReac = () =>{
// 默认深度响应
stateReac.foo = 3
stateReac.bar.baz = 3
}
const changeShallowStateReac = () =>{
// shallowStateReac.foo = 3 // 此时会触发更新
// shallowStateReac.bar = {} // 此时会触发更新,只用于第一层属性
//避坑:如果前面代码第一层属性没有发生响应,如果只修改嵌套属性,数据会变化,但不会更新试图
shallowStateReac.bar.baz = 3
shallowStateReac.bar.quz.foobar = 4;
console.log(shallowStateReac)
}
</script>
二、reactive() 包裹单个数组[]问题;推荐解构和ref
<template>
<div id="app">
<p>{{todos}} <button @click="getTodos">异步获取todos</button></p>
<ul>
<li v-for="item in todos" :key="item.id">{{item.txt}}</li>
</ul>
</div>
</template>
<script setup>
import { reactive } from 'vue'
let todos = reactive([]);
const getTodos =() =>{
setTimeout(() =>{
const list = [{ id:1, txt:'吃饭', done: false}, { id:2, txt:'睡觉', done: true}]
// todos = list; 错误的,todos本身是proxy,不能直接赋值;
todos.push(...list) // 推荐解构,或者增加属性,数值为数组,或者用ref定义简单的一个数组,不用reactive
},800)
}
</script>
三、reactive的ref 自动解包问题:
默认自动深层解包任何ref属性,同时保持响应式
let count = ref(0)
let state = reactive({count})
state.count++ //不用写 state.count.value ++,自动解包;此时count属性和count 保持连接;
console.log(count.value === state.count) // true
遇到响应式数组,和map集合类型中的 ref 元素时,不会自动解包
const books = reactive([ref('Vue 3 Guide')])// 这里需要 .value
console.log(books[0].value)
const map = reactive(new Map([['count', ref(0)]]))// 这里需要 .valueconsole.log(map.get('count').value)