mirror of https://github.com/vuejs/core.git
parent
6e4de8d75e
commit
b094c72b3d
|
@ -170,15 +170,14 @@ function doWatch(
|
|||
|
||||
if (__DEV__) baseWatchOptions.onWarn = warn
|
||||
|
||||
// immediate watcher or watchEffect
|
||||
const runsImmediately = (cb && immediate) || (!cb && flush !== 'post')
|
||||
let ssrCleanup: (() => void)[] | undefined
|
||||
if (__SSR__ && isInSSRComponentSetup) {
|
||||
if (flush === 'sync') {
|
||||
const ctx = useSSRContext()!
|
||||
ssrCleanup = ctx.__watcherHandles || (ctx.__watcherHandles = [])
|
||||
} else if (!cb || immediate) {
|
||||
// immediately watch or watchEffect
|
||||
baseWatchOptions.once = true
|
||||
} else {
|
||||
} else if (!runsImmediately) {
|
||||
const watchStopHandle = () => {}
|
||||
watchStopHandle.stop = NOOP
|
||||
watchStopHandle.resume = NOOP
|
||||
|
@ -226,7 +225,14 @@ function doWatch(
|
|||
|
||||
const watchHandle = baseWatch(source, cb, baseWatchOptions)
|
||||
|
||||
if (__SSR__ && ssrCleanup) ssrCleanup.push(watchHandle)
|
||||
if (__SSR__ && isInSSRComponentSetup) {
|
||||
if (ssrCleanup) {
|
||||
ssrCleanup.push(watchHandle)
|
||||
} else if (runsImmediately) {
|
||||
watchHandle()
|
||||
}
|
||||
}
|
||||
|
||||
return watchHandle
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
import { createSSRApp, defineComponent, h, ref, watch } from 'vue'
|
||||
import {
|
||||
createSSRApp,
|
||||
defineComponent,
|
||||
h,
|
||||
nextTick,
|
||||
ref,
|
||||
watch,
|
||||
watchEffect,
|
||||
} from 'vue'
|
||||
import { type SSRContext, renderToString } from '../src'
|
||||
|
||||
describe('ssr: watch', () => {
|
||||
|
@ -27,4 +35,168 @@ describe('ssr: watch', () => {
|
|||
|
||||
expect(html).toMatch('hello world')
|
||||
})
|
||||
|
||||
test('should work with flush: sync and immediate: true', async () => {
|
||||
const text = ref('start')
|
||||
let msg = 'unchanged'
|
||||
|
||||
const App = defineComponent(() => {
|
||||
watch(
|
||||
text,
|
||||
() => {
|
||||
msg = text.value
|
||||
},
|
||||
{ flush: 'sync', immediate: true },
|
||||
)
|
||||
expect(msg).toBe('start')
|
||||
text.value = 'changed'
|
||||
expect(msg).toBe('changed')
|
||||
text.value = 'changed again'
|
||||
expect(msg).toBe('changed again')
|
||||
return () => h('div', null, msg)
|
||||
})
|
||||
|
||||
const app = createSSRApp(App)
|
||||
const ctx: SSRContext = {}
|
||||
const html = await renderToString(app, ctx)
|
||||
|
||||
expect(ctx.__watcherHandles!.length).toBe(1)
|
||||
expect(html).toMatch('changed again')
|
||||
await nextTick()
|
||||
expect(msg).toBe('changed again')
|
||||
})
|
||||
|
||||
test('should run once with immediate: true', async () => {
|
||||
const text = ref('start')
|
||||
let msg = 'unchanged'
|
||||
|
||||
const App = defineComponent(() => {
|
||||
watch(
|
||||
text,
|
||||
() => {
|
||||
msg = String(text.value)
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
text.value = 'changed'
|
||||
expect(msg).toBe('start')
|
||||
return () => h('div', null, msg)
|
||||
})
|
||||
|
||||
const app = createSSRApp(App)
|
||||
const ctx: SSRContext = {}
|
||||
const html = await renderToString(app, ctx)
|
||||
|
||||
expect(ctx.__watcherHandles).toBeUndefined()
|
||||
expect(html).toMatch('start')
|
||||
await nextTick()
|
||||
expect(msg).toBe('start')
|
||||
})
|
||||
|
||||
test('should run once with immediate: true and flush: post', async () => {
|
||||
const text = ref('start')
|
||||
let msg = 'unchanged'
|
||||
|
||||
const App = defineComponent(() => {
|
||||
watch(
|
||||
text,
|
||||
() => {
|
||||
msg = String(text.value)
|
||||
},
|
||||
{ immediate: true, flush: 'post' },
|
||||
)
|
||||
text.value = 'changed'
|
||||
expect(msg).toBe('start')
|
||||
return () => h('div', null, msg)
|
||||
})
|
||||
|
||||
const app = createSSRApp(App)
|
||||
const ctx: SSRContext = {}
|
||||
const html = await renderToString(app, ctx)
|
||||
|
||||
expect(ctx.__watcherHandles).toBeUndefined()
|
||||
expect(html).toMatch('start')
|
||||
await nextTick()
|
||||
expect(msg).toBe('start')
|
||||
})
|
||||
})
|
||||
|
||||
describe('ssr: watchEffect', () => {
|
||||
test('should run with flush: sync', async () => {
|
||||
const text = ref('start')
|
||||
let msg = 'unchanged'
|
||||
|
||||
const App = defineComponent(() => {
|
||||
watchEffect(
|
||||
() => {
|
||||
msg = text.value
|
||||
},
|
||||
{ flush: 'sync' },
|
||||
)
|
||||
expect(msg).toBe('start')
|
||||
text.value = 'changed'
|
||||
expect(msg).toBe('changed')
|
||||
text.value = 'changed again'
|
||||
expect(msg).toBe('changed again')
|
||||
return () => h('div', null, msg)
|
||||
})
|
||||
|
||||
const app = createSSRApp(App)
|
||||
const ctx: SSRContext = {}
|
||||
const html = await renderToString(app, ctx)
|
||||
|
||||
expect(ctx.__watcherHandles!.length).toBe(1)
|
||||
expect(html).toMatch('changed again')
|
||||
await nextTick()
|
||||
expect(msg).toBe('changed again')
|
||||
})
|
||||
|
||||
test('should run once with default flush (pre)', async () => {
|
||||
const text = ref('start')
|
||||
let msg = 'unchanged'
|
||||
|
||||
const App = defineComponent(() => {
|
||||
watchEffect(() => {
|
||||
msg = text.value
|
||||
})
|
||||
text.value = 'changed'
|
||||
expect(msg).toBe('start')
|
||||
return () => h('div', null, msg)
|
||||
})
|
||||
|
||||
const app = createSSRApp(App)
|
||||
const ctx: SSRContext = {}
|
||||
const html = await renderToString(app, ctx)
|
||||
|
||||
expect(ctx.__watcherHandles).toBeUndefined()
|
||||
expect(html).toMatch('start')
|
||||
await nextTick()
|
||||
expect(msg).toBe('start')
|
||||
})
|
||||
|
||||
test('should not run for flush: post', async () => {
|
||||
const text = ref('start')
|
||||
let msg = 'unchanged'
|
||||
|
||||
const App = defineComponent(() => {
|
||||
watchEffect(
|
||||
() => {
|
||||
msg = text.value
|
||||
},
|
||||
{ flush: 'post' },
|
||||
)
|
||||
text.value = 'changed'
|
||||
expect(msg).toBe('unchanged')
|
||||
return () => h('div', null, msg)
|
||||
})
|
||||
|
||||
const app = createSSRApp(App)
|
||||
const ctx: SSRContext = {}
|
||||
const html = await renderToString(app, ctx)
|
||||
|
||||
expect(ctx.__watcherHandles).toBeUndefined()
|
||||
expect(html).toMatch('unchanged')
|
||||
await nextTick()
|
||||
expect(msg).toBe('unchanged')
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue