File tree 3 files changed +28
-9
lines changed
3 files changed +28
-9
lines changed Original file line number Diff line number Diff line change @@ -7,13 +7,17 @@ import { CollectionTypes } from './collectionHandlers'
7
7
declare const RefSymbol : unique symbol
8
8
9
9
export interface Ref < T = any > {
10
+ value : T
10
11
/**
11
12
* Type differentiator only.
12
13
* We need this to be in public d.ts but don't want it to show up in IDE
13
14
* autocomplete, so we use a private Symbol instead.
14
15
*/
15
16
[ RefSymbol ] : true
16
- value : T
17
+ /**
18
+ * @internal
19
+ */
20
+ _shallow ?: boolean
17
21
}
18
22
19
23
export type ToRefs < T = any > = { [ K in keyof T ] : Ref < T [ K ] > }
@@ -49,7 +53,7 @@ class RefImpl<T> {
49
53
50
54
public readonly __v_isRef = true
51
55
52
- constructor ( private _rawValue : T , private readonly _shallow = false ) {
56
+ constructor ( private _rawValue : T , public readonly _shallow = false ) {
53
57
this . _value = _shallow ? _rawValue : convert ( _rawValue )
54
58
}
55
59
@@ -75,7 +79,7 @@ function createRef(rawValue: unknown, shallow = false) {
75
79
}
76
80
77
81
export function triggerRef ( ref : Ref ) {
78
- trigger ( ref , TriggerOpTypes . SET , 'value' , __DEV__ ? ref . value : void 0 )
82
+ trigger ( toRaw ( ref ) , TriggerOpTypes . SET , 'value' , __DEV__ ? ref . value : void 0 )
79
83
}
80
84
81
85
export function unref < T > ( ref : T ) : T extends Ref < infer V > ? V : T {
Original file line number Diff line number Diff line change @@ -13,7 +13,8 @@ import {
13
13
DebuggerEvent ,
14
14
TrackOpTypes ,
15
15
TriggerOpTypes ,
16
- triggerRef
16
+ triggerRef ,
17
+ shallowRef
17
18
} from '@vue/reactivity'
18
19
19
20
// reference: https://vue-composition-api-rfc.netlify.com/api.html#watch
@@ -750,8 +751,8 @@ describe('api: watch', () => {
750
751
expect ( calls ) . toBe ( 1 )
751
752
} )
752
753
753
- test ( 'should force trigger on triggerRef when watching a ref' , async ( ) => {
754
- const v = ref ( { a : 1 } )
754
+ test ( 'should force trigger on triggerRef when watching a shallow ref' , async ( ) => {
755
+ const v = shallowRef ( { a : 1 } )
755
756
let sideEffect = 0
756
757
watch ( v , obj => {
757
758
sideEffect = obj . a
@@ -785,4 +786,17 @@ describe('api: watch', () => {
785
786
await nextTick ( )
786
787
expect ( spy ) . toHaveBeenCalledTimes ( 1 )
787
788
} )
789
+
790
+ // #2231
791
+ test ( 'computed refs should not trigger watch if value has no change' , async ( ) => {
792
+ const spy = jest . fn ( )
793
+ const source = ref ( 0 )
794
+ const price = computed ( ( ) => source . value === 0 )
795
+ watch ( price , spy )
796
+ source . value ++
797
+ await nextTick ( )
798
+ source . value ++
799
+ await nextTick ( )
800
+ expect ( spy ) . toHaveBeenCalledTimes ( 1 )
801
+ } )
788
802
} )
Original file line number Diff line number Diff line change @@ -161,9 +161,10 @@ function doWatch(
161
161
}
162
162
163
163
let getter : ( ) => any
164
- const isRefSource = isRef ( source )
165
- if ( isRefSource ) {
164
+ let forceTrigger = false
165
+ if ( isRef ( source ) ) {
166
166
getter = ( ) => ( source as Ref ) . value
167
+ forceTrigger = ! ! ( source as Ref ) . _shallow
167
168
} else if ( isReactive ( source ) ) {
168
169
getter = ( ) => source
169
170
deep = true
@@ -242,7 +243,7 @@ function doWatch(
242
243
if ( cb ) {
243
244
// watch(source, cb)
244
245
const newValue = runner ( )
245
- if ( deep || isRefSource || hasChanged ( newValue , oldValue ) ) {
246
+ if ( deep || forceTrigger || hasChanged ( newValue , oldValue ) ) {
246
247
// cleanup before running cb again
247
248
if ( cleanup ) {
248
249
cleanup ( )
You can’t perform that action at this time.
0 commit comments