From 2ee8cf08425406406ffbfd507e403bcb9b6d3da6 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Wed, 20 Dec 2023 17:09:13 +0100 Subject: [PATCH] test(ssr): computed with onServerPrefetch As noted in https://github.com/vuejs/core/issues/5300#issuecomment-1790432852 --- .../__tests__/ssrComputed.spec.ts | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/packages/server-renderer/__tests__/ssrComputed.spec.ts b/packages/server-renderer/__tests__/ssrComputed.spec.ts index 52b45a636..df27c4e2f 100644 --- a/packages/server-renderer/__tests__/ssrComputed.spec.ts +++ b/packages/server-renderer/__tests__/ssrComputed.spec.ts @@ -1,4 +1,11 @@ -import { createSSRApp, defineComponent, h, computed, reactive } from 'vue' +import { + createSSRApp, + defineComponent, + h, + computed, + reactive, + onServerPrefetch +} from 'vue' import { renderToString } from '../src/renderToString' // #5208 reported memory leak of keeping computed alive during SSR @@ -45,3 +52,42 @@ test('computed reactivity during SSR', async () => { // during the render phase expect(getterSpy).toHaveBeenCalledTimes(2) }) + +test('computed reactivity during SSR with onServerPrefetch', async () => { + const store = { + // initial state could be hydrated + state: reactive({ items: null as null | string[] }), + + // pretend to fetch some data from an api + async fetchData() { + this.state.items = ['hello', 'world'] + } + } + + const getterSpy = vi.fn() + + const App = defineComponent(() => { + const msg = computed(() => { + getterSpy() + return store.state.items?.join(' ') + }) + + onServerPrefetch(() => store.fetchData()) + + // simulate the read from a composable (e.g. filtering a list of results) + msg.value + + return () => h('div', null, msg.value) + }) + + const app = createSSRApp(App) + + // in real world serve this html and append store state for hydration on client + const html = await renderToString(app) + + expect(html).toMatch('hello world') + + // should only be called twice since access should be cached + // during the render phase + expect(getterSpy).toHaveBeenCalledTimes(2) +})