perf(reactivity): ref should not trigger if value did not change
Note: shallowRef will always trigger on assignment because it does not account for deep mutations close #1012
This commit is contained in:
parent
7d858a9001
commit
b0d4df9743
@ -22,11 +22,19 @@ describe('reactivity/ref', () => {
|
||||
it('should be reactive', () => {
|
||||
const a = ref(1)
|
||||
let dummy
|
||||
let calls = 0
|
||||
effect(() => {
|
||||
calls++
|
||||
dummy = a.value
|
||||
})
|
||||
expect(calls).toBe(1)
|
||||
expect(dummy).toBe(1)
|
||||
a.value = 2
|
||||
expect(calls).toBe(2)
|
||||
expect(dummy).toBe(2)
|
||||
// same value should not trigger
|
||||
a.value = 2
|
||||
expect(calls).toBe(2)
|
||||
expect(dummy).toBe(2)
|
||||
})
|
||||
|
||||
@ -174,6 +182,22 @@ describe('reactivity/ref', () => {
|
||||
expect(dummy).toBe(2)
|
||||
})
|
||||
|
||||
test('shallowRef force trigger', () => {
|
||||
const sref = shallowRef({ a: 1 })
|
||||
let dummy
|
||||
effect(() => {
|
||||
dummy = sref.value.a
|
||||
})
|
||||
expect(dummy).toBe(1)
|
||||
|
||||
sref.value.a = 2
|
||||
expect(dummy).toBe(1) // should not trigger yet
|
||||
|
||||
// force trigger
|
||||
sref.value = sref.value
|
||||
expect(dummy).toBe(2)
|
||||
})
|
||||
|
||||
test('isRef', () => {
|
||||
expect(isRef(ref(1))).toBe(true)
|
||||
expect(isRef(computed(() => 1))).toBe(true)
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { track, trigger } from './effect'
|
||||
import { TrackOpTypes, TriggerOpTypes } from './operations'
|
||||
import { isObject } from '@vue/shared'
|
||||
import { reactive, isProxy } from './reactive'
|
||||
import { isObject, hasChanged } from '@vue/shared'
|
||||
import { reactive, isProxy, toRaw } from './reactive'
|
||||
import { ComputedRef } from './computed'
|
||||
import { CollectionTypes } from './collectionHandlers'
|
||||
|
||||
@ -43,13 +43,11 @@ export function shallowRef(value?: unknown) {
|
||||
return createRef(value, true)
|
||||
}
|
||||
|
||||
function createRef(value: unknown, shallow = false) {
|
||||
if (isRef(value)) {
|
||||
return value
|
||||
}
|
||||
if (!shallow) {
|
||||
value = convert(value)
|
||||
function createRef(rawValue: unknown, shallow = false) {
|
||||
if (isRef(rawValue)) {
|
||||
return rawValue
|
||||
}
|
||||
let value = shallow ? rawValue : convert(rawValue)
|
||||
const r = {
|
||||
_isRef: true,
|
||||
get value() {
|
||||
@ -57,13 +55,16 @@ function createRef(value: unknown, shallow = false) {
|
||||
return value
|
||||
},
|
||||
set value(newVal) {
|
||||
value = shallow ? newVal : convert(newVal)
|
||||
trigger(
|
||||
r,
|
||||
TriggerOpTypes.SET,
|
||||
'value',
|
||||
__DEV__ ? { newValue: newVal } : void 0
|
||||
)
|
||||
if (shallow || hasChanged(toRaw(newVal), rawValue)) {
|
||||
rawValue = newVal
|
||||
value = shallow ? newVal : convert(newVal)
|
||||
trigger(
|
||||
r,
|
||||
TriggerOpTypes.SET,
|
||||
'value',
|
||||
__DEV__ ? { newValue: newVal } : void 0
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
return r
|
||||
|
Loading…
Reference in New Issue
Block a user