Skip to content

Commit

Permalink
perf(reactivity): ref should not trigger if value did not change
Browse files Browse the repository at this point in the history
Note: shallowRef will always trigger on assignment because it does not
account for deep mutations

close vuejs#1012
  • Loading branch information
yyx990803 authored and pikax committed Apr 29, 2020
1 parent abefdde commit 9342e6e
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 15 deletions.
24 changes: 24 additions & 0 deletions packages/reactivity/__tests__/ref.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)
})

Expand Down Expand Up @@ -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)
Expand Down
31 changes: 16 additions & 15 deletions packages/reactivity/src/ref.ts
Original file line number Diff line number Diff line change
@@ -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'

Expand Down Expand Up @@ -43,27 +43,28 @@ 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() {
track(r, TrackOpTypes.GET, 'value')
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
Expand Down

0 comments on commit 9342e6e

Please sign in to comment.