Skip to content

Commit

Permalink
Reapply "simple & robust useData() impl"
Browse files Browse the repository at this point in the history
This reverts commit 631f674.
  • Loading branch information
brillout committed Jun 5, 2024
1 parent 631f674 commit 56938fa
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 3 deletions.
14 changes: 13 additions & 1 deletion examples/vue-full/renderer/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { createSSRApp, h, markRaw, reactive, ref } from 'vue'
import PageLayout from './PageLayout.vue'
import { setPageContext } from './usePageContext'
import type { PageContext } from 'vike/types'
import { objectAssign } from './utils'
import { setData } from './useData'
import { isObject, objectAssign } from './utils'

function createApp(pageContext: PageContext) {
const { Page } = pageContext
Expand All @@ -22,13 +23,24 @@ function createApp(pageContext: PageContext) {
// app.changePage() is called upon navigation, see +onRenderClient.ts
objectAssign(app, {
changePage: (pageContext: PageContext) => {
const data = pageContext.data ?? {}
assertDataIsObject(data)
Object.assign(dataReactive, data)
Object.assign(pageContextReactive, pageContext)
pageRef.value = markRaw(pageContext.Page)
}
})

const data = pageContext.data ?? {}
assertDataIsObject(data)
const dataReactive = reactive(data)
const pageContextReactive = reactive(pageContext)
setPageContext(app, pageContextReactive)
setData(app, dataReactive)

return app
}

function assertDataIsObject(data: unknown): asserts data is Record<string, unknown> {
if (!isObject(data)) throw new Error('Return value of data() hook should be an object, undefined, or null')
}
13 changes: 11 additions & 2 deletions examples/vue-full/renderer/useData.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
// https://vike.dev/useData
export { useData }
export { setData }

import { usePageContext } from './usePageContext'
import { inject } from 'vue'
import type { App } from 'vue'

const key = Symbol()

/** https://vike.dev/useData */
function useData<Data>(): Data {
const { data } = usePageContext()
const data = inject(key)
if (!data) throw new Error('setData() not called')
return data as any
}

function setData(app: App, data: unknown): void {
app.provide(key, data)
}
4 changes: 4 additions & 0 deletions examples/vue-full/renderer/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ export function objectAssign<Obj extends object, ObjAddendum>(
): asserts obj is Obj & ObjAddendum {
Object.assign(obj, objAddendum)
}

export function isObject(value: unknown): value is Record<string, unknown> {
return typeof value === 'object' && value !== null
}

0 comments on commit 56938fa

Please sign in to comment.