Skip to content

Commit f27021b

Browse files
committed
fix(watch): watching multiple sources: computed
vuejs/core#3066
1 parent 8a897e4 commit f27021b

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

packages/wechat/__tests__/watch.spec.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,30 @@ describe('watch', () => {
558558
expect(spy).toHaveBeenCalledTimes(1)
559559
})
560560

561+
test('watching sources: ref<any[]>', async () => {
562+
const foo = ref([1])
563+
const spy = jest.fn()
564+
watch(foo, () => {
565+
spy()
566+
})
567+
foo.value = [...foo.value]
568+
await nextTick()
569+
expect(spy).toBeCalledTimes(1)
570+
})
571+
572+
test('watching multiple sources: computed', async () => {
573+
let count = 0
574+
const value = ref('1')
575+
const plus = computed(() => Boolean(value.value))
576+
watch([plus], () => {
577+
count++
578+
})
579+
value.value = '2'
580+
await nextTick()
581+
expect(plus.value).toBe(true)
582+
expect(count).toBe(0)
583+
})
584+
561585
/** Dividing line, the above tests is directly copy from vue.js **/
562586

563587
it('warn when using old simple watch api', async () => {

packages/wechat/src/watch.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,8 @@ function doWatch(
160160

161161
let getter: () => any
162162
let forceTrigger = false
163+
let isMultiSource = false
164+
163165
if (isRef(source)) {
164166
getter = () => (source as Ref).value
165167
// @ts-expect-error
@@ -168,6 +170,8 @@ function doWatch(
168170
getter = () => source
169171
deep = true
170172
} else if (isArray(source)) {
173+
isMultiSource = true
174+
forceTrigger = source.some((s) => isReactive(s))
171175
getter = () =>
172176
source.map((s) => {
173177
if (isRef(s)) {
@@ -225,7 +229,7 @@ function doWatch(
225229
}
226230
}
227231

228-
let oldValue = isArray(source) ? [] : INITIAL_WATCHER_VALUE
232+
let oldValue = isMultiSource ? [] : INITIAL_WATCHER_VALUE
229233
const job: SchedulerJob = () => {
230234
if (!runner.active) {
231235
return
@@ -234,7 +238,15 @@ function doWatch(
234238
if (cb) {
235239
// Watch(source, cb)
236240
const newValue = runner()
237-
if (deep || forceTrigger || hasChanged(newValue, oldValue)) {
241+
if (
242+
deep ||
243+
forceTrigger ||
244+
(isMultiSource
245+
? (newValue as any[]).some((v, i) =>
246+
hasChanged(v, (oldValue as any[])[i])
247+
)
248+
: hasChanged(newValue, oldValue))
249+
) {
238250
// Cleanup before running cb again
239251
if (cleanup) {
240252
cleanup()

0 commit comments

Comments
 (0)