fix(reactivity): fix shallow/readonly edge cases

This commit is contained in:
Evan You
2022-07-22 11:10:52 +08:00
parent 8dcb6c7bbd
commit a95554d35c
5 changed files with 69 additions and 14 deletions

View File

@@ -158,10 +158,10 @@ function createSetter(shallow = false) {
if (isReadonly(oldValue) && isRef(oldValue) && !isRef(value)) {
return false
}
if (!shallow && !isReadonly(value)) {
if (!isShallow(value)) {
value = toRaw(value)
if (!shallow) {
if (!isShallow(value) && !isReadonly(value)) {
oldValue = toRaw(oldValue)
value = toRaw(value)
}
if (!isArray(target) && isRef(oldValue) && !isRef(value)) {
oldValue.value = value

View File

@@ -6,7 +6,14 @@ import {
} from './effect'
import { TrackOpTypes, TriggerOpTypes } from './operations'
import { isArray, hasChanged, IfAny } from '@vue/shared'
import { isProxy, toRaw, isReactive, toReactive } from './reactive'
import {
isProxy,
toRaw,
isReactive,
toReactive,
isReadonly,
isShallow
} from './reactive'
import type { ShallowReactiveMarker } from './reactive'
import { CollectionTypes } from './collectionHandlers'
import { createDep, Dep } from './dep'
@@ -112,10 +119,12 @@ class RefImpl<T> {
}
set value(newVal) {
newVal = this.__v_isShallow ? newVal : toRaw(newVal)
const useDirectValue =
this.__v_isShallow || isShallow(newVal) || isReadonly(newVal)
newVal = useDirectValue ? newVal : toRaw(newVal)
if (hasChanged(newVal, this._rawValue)) {
this._rawValue = newVal
this._value = this.__v_isShallow ? newVal : toReactive(newVal)
this._value = useDirectValue ? newVal : toReactive(newVal)
triggerRefValue(this, newVal)
}
}