render,
serializeInner,
nextTick,
- watch,
+ watchEffect,
defineComponent,
triggerEvent,
TestElement
const Child = defineComponent({
setup(props: { count: number }) {
- watch(() => {
+ watchEffect(() => {
dummy = props.count
})
return () => h('div', props.count)
},
setup(props) {
- watch(() => {
+ watchEffect(() => {
dummy = props.count
})
return () => h('div', props.count)
-import { watch, reactive, computed, nextTick, ref, h } from '../src/index'
+import {
+ watch,
+ watchEffect,
+ reactive,
+ computed,
+ nextTick,
+ ref,
+ h
+} from '../src/index'
import { render, nodeOps, serializeInner } from '@vue/runtime-test'
import {
ITERATE_KEY,
describe('api: watch', () => {
mockWarn()
- it('watch(effect)', async () => {
+ it('effect', async () => {
const state = reactive({ count: 0 })
let dummy
- watch(() => {
+ watchEffect(() => {
dummy = state.count
})
expect(dummy).toBe(0)
expect(dummy).toMatchObject([[2, true], [1, false]])
})
- it('stopping the watcher', async () => {
+ it('stopping the watcher (effect)', async () => {
const state = reactive({ count: 0 })
let dummy
- const stop = watch(() => {
+ const stop = watchEffect(() => {
dummy = state.count
})
expect(dummy).toBe(0)
expect(dummy).toBe(0)
})
+ it('stopping the watcher (with source)', async () => {
+ const state = reactive({ count: 0 })
+ let dummy
+ const stop = watch(
+ () => state.count,
+ count => {
+ dummy = count
+ }
+ )
+
+ state.count++
+ await nextTick()
+ expect(dummy).toBe(1)
+
+ stop()
+ state.count++
+ await nextTick()
+ // should not update
+ expect(dummy).toBe(1)
+ })
+
it('cleanup registration (effect)', async () => {
const state = reactive({ count: 0 })
const cleanup = jest.fn()
let dummy
- const stop = watch(onCleanup => {
+ const stop = watchEffect(onCleanup => {
onCleanup(cleanup)
dummy = state.count
})
const Comp = {
setup() {
- watch(() => {
+ watchEffect(() => {
assertion(count.value)
})
return () => count.value
const Comp = {
setup() {
- watch(
+ watchEffect(
() => {
assertion(count.value, count2.value)
},
const Comp = {
setup() {
- watch(
+ watchEffect(
() => {
assertion(count.value)
},
expect(spy).toHaveBeenCalledTimes(3)
})
- it('warn immediate option when using effect signature', async () => {
+ it('warn immediate option when using effect', async () => {
const count = ref(0)
let dummy
- // @ts-ignore
- watch(
+ watchEffect(
() => {
dummy = count.value
},
+ // @ts-ignore
{ immediate: false }
)
expect(dummy).toBe(0)
events.push(e)
})
const obj = reactive({ foo: 1, bar: 2 })
- watch(
+ watchEffect(
() => {
dummy = [obj.foo, 'bar' in obj, Object.keys(obj)]
},
events.push(e)
})
const obj = reactive({ foo: 1 })
- watch(
+ watchEffect(
() => {
dummy = obj.foo
},
nextTick,
onMounted,
watch,
+ watchEffect,
onUnmounted,
onErrorCaptured
} from '@vue/runtime-test'
// extra tick needed for Node 12+
deps.push(p.then(() => Promise.resolve()))
- watch(() => {
+ watchEffect(() => {
calls.push('immediate effect')
})
const p = new Promise(r => setTimeout(r, 1))
deps.push(p)
- watch(() => {
+ watchEffect(() => {
calls.push('immediate effect')
})
watch,
ref,
nextTick,
- defineComponent
+ defineComponent,
+ watchEffect
} from '@vue/runtime-test'
import { setErrorRecovery } from '../src/errorHandling'
import { mockWarn } from '@vue/shared'
expect(fn).toHaveBeenCalledWith(err, 'ref function')
})
- test('in watch (effect)', () => {
+ test('in effect', () => {
const err = new Error('foo')
const fn = jest.fn()
const Child = {
setup() {
- watch(() => {
+ watchEffect(() => {
throw err
})
return () => null
expect(fn).toHaveBeenCalledWith(err, 'watcher callback')
})
- test('in watch (getter)', () => {
+ test('in watch getter', () => {
const err = new Error('foo')
const fn = jest.fn()
expect(fn).toHaveBeenCalledWith(err, 'watcher getter')
})
- test('in watch (callback)', async () => {
+ test('in watch callback', async () => {
const err = new Error('foo')
const fn = jest.fn()
expect(fn).toHaveBeenCalledWith(err, 'watcher callback')
})
- test('in watch cleanup', async () => {
+ test('in effect cleanup', async () => {
const err = new Error('foo')
const count = ref(0)
const fn = jest.fn()
const Child = {
setup() {
- watch(onCleanup => {
+ watchEffect(onCleanup => {
count.value
onCleanup(() => {
throw err
const invoke = (fn: Function) => fn()
+// Simple effect.
+export function watchEffect(
+ effect: WatchEffect,
+ options?: BaseWatchOptions
+): StopHandle {
+ return doWatch(effect, null, options)
+}
+
// initial value for watchers to trigger on undefined initial values
const INITIAL_WATCHER_VALUE = {}
// watch(source, cb)
return doWatch(effectOrSource, cbOrOptions, options)
} else {
+ // TODO remove this in the next release
+ __DEV__ &&
+ warn(
+ `\`watch(fn, options?)\` signature has been moved to a separate API. ` +
+ `Use \`watchEffect(fn, options?)\` instead. \`watch\` will only ` +
+ `support \`watch(source, cb, options?) signature in the next release.`
+ )
// watch(effect)
return doWatch(effectOrSource, null, cbOrOptions)
}
markNonReactive
} from '@vue/reactivity'
export { computed } from './apiComputed'
-export { watch } from './apiWatch'
+export { watch, watchEffect } from './apiWatch'
export {
onBeforeMount,
onMounted,
</div>
<script>
-const { createApp, ref, watch } = Vue
+const { createApp, ref, watchEffect } = Vue
const API_URL = `https://api.github.com/repos/vuejs/vue-next/commits?per_page=3&sha=`
const truncate = v => {
const currentBranch = ref('master')
const commits = ref(null)
- watch(() => {
+ watchEffect(() => {
fetch(`${API_URL}${currentBranch.value}`)
.then(res => res.json())
.then(data => {
</div>
<script>
-const { createApp, reactive, computed, watch, onMounted, onUnmounted } = Vue
+const { createApp, reactive, computed, watchEffect, onMounted, onUnmounted } = Vue
const STORAGE_KEY = 'todos-vuejs-3.x'
const todoStorage = {
})
})
- watch(() => {
+ watchEffect(() => {
todoStorage.save(state.todos)
})