mirror of
https://github.com/IT4Change/boilerplate-frontend.git
synced 2025-12-13 07:35:53 +00:00
client side routing works except parameters
This commit is contained in:
parent
aac1b93cc8
commit
fedeacad19
@ -1,17 +1,36 @@
|
|||||||
import { createApp } from './app'
|
import { createApp } from './app'
|
||||||
|
|
||||||
import type { PageContextClient } from '#types/PageContext'
|
import type { PageContext, VikePageContext } from '#types/PageContext'
|
||||||
|
|
||||||
// This render() hook only supports SSR, see https://vike.dev/render-modes for how to modify render() to support SPA
|
let app: ReturnType<typeof createApp>
|
||||||
async function render(pageContext: PageContextClient) {
|
async function render(pageContext: VikePageContext & PageContext) {
|
||||||
const { Page, pageProps } = pageContext
|
if (!app) {
|
||||||
if (!Page) throw new Error('Client-side render() hook expects pageContext.Page to be defined')
|
app = createApp(pageContext)
|
||||||
const app = createApp(Page, pageProps, pageContext)
|
app.mount('#app')
|
||||||
app.mount('#app')
|
} else {
|
||||||
|
// console.log(pageContext)
|
||||||
|
app.changePage(pageContext)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* To enable Client-side Routing:
|
function onHydrationEnd() {
|
||||||
export const clientRouting = true
|
// eslint-disable-next-line no-console
|
||||||
// !! WARNING !! Before doing so, read https://vike.dev/clientRouting */
|
console.log('Hydration finished; page is now interactive.')
|
||||||
|
}
|
||||||
|
function onPageTransitionStart() {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log('Page transition start')
|
||||||
|
// document.querySelector('.content')!.classList.add('page-transition')
|
||||||
|
}
|
||||||
|
function onPageTransitionEnd() {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log('Page transition end')
|
||||||
|
// document.querySelector('.content')!.classList.remove('page-transition')
|
||||||
|
}
|
||||||
|
|
||||||
|
export const clientRouting = true
|
||||||
|
export const prefetchStaticAssets = 'viewport'
|
||||||
export { render }
|
export { render }
|
||||||
|
export { onHydrationEnd }
|
||||||
|
export { onPageTransitionStart }
|
||||||
|
export { onPageTransitionEnd }
|
||||||
|
|||||||
@ -6,20 +6,14 @@ import { META } from '#src/env'
|
|||||||
|
|
||||||
import { createApp } from './app'
|
import { createApp } from './app'
|
||||||
|
|
||||||
import type { PageContextServer } from '#types/PageContext'
|
import type { PageContextServer, PageContext } from '#types/PageContext'
|
||||||
import type { App } from 'vue'
|
import type { App } from 'vue'
|
||||||
|
|
||||||
// See https://vike.dev/data-fetching
|
// See https://vike.dev/data-fetching
|
||||||
export const passToClient = ['pageProps', 'urlPathname', 'routeParams']
|
export const passToClient = ['pageProps', /* 'urlPathname', */ 'routeParams']
|
||||||
|
|
||||||
async function render(pageContext: PageContextServer) {
|
async function render(pageContext: PageContextServer & PageContext) {
|
||||||
const { Page, pageProps } = pageContext
|
const app = createApp(pageContext, false)
|
||||||
// This render() hook only supports SSR, see https://vike.dev/render-modes for how to modify render() to support SPA
|
|
||||||
if (!Page) {
|
|
||||||
throw new Error('My render() hook expects pageContext.Page to be defined')
|
|
||||||
}
|
|
||||||
|
|
||||||
const app = createApp(Page, pageProps, pageContext, false)
|
|
||||||
|
|
||||||
const appHtml = await renderToString(app)
|
const appHtml = await renderToString(app)
|
||||||
|
|
||||||
|
|||||||
@ -1,32 +1,36 @@
|
|||||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
||||||
import { createSSRApp, defineComponent, h } from 'vue'
|
import { createSSRApp, defineComponent, h, markRaw, reactive } from 'vue'
|
||||||
|
|
||||||
import PageShell from '#components/PageShell.vue'
|
import PageShell from '#components/PageShell.vue'
|
||||||
import { setPageContext } from '#context/usePageContext'
|
import { setPageContext } from '#context/usePageContext'
|
||||||
import i18n from '#plugins/i18n'
|
import i18n from '#plugins/i18n'
|
||||||
import pinia from '#plugins/pinia'
|
import pinia from '#plugins/pinia'
|
||||||
import CreateVuetify from '#plugins/vuetify'
|
import CreateVuetify from '#plugins/vuetify'
|
||||||
import { Page } from '#types/Page'
|
|
||||||
import { PageProps } from '#types/PageProps'
|
|
||||||
|
|
||||||
import type { PageContext } from '#types/PageContext'
|
import type { Component } from '#types/Component'
|
||||||
|
import type { PageContext, VikePageContext } from '#types/PageContext'
|
||||||
|
|
||||||
const vuetify = CreateVuetify(i18n)
|
const vuetify = CreateVuetify(i18n)
|
||||||
|
|
||||||
function createApp(
|
function createApp(pageContext: VikePageContext & PageContext, isClient = true) {
|
||||||
Page: Page,
|
let rootComponent: Component
|
||||||
pageProps: PageProps | undefined,
|
const PageWithWrapper = defineComponent({
|
||||||
pageContext: PageContext,
|
data: () => ({
|
||||||
isClient = true,
|
Page: markRaw(pageContext.Page),
|
||||||
) {
|
pageProps: markRaw(pageContext.pageProps || {}),
|
||||||
const PageWithLayout = defineComponent({
|
isClient,
|
||||||
|
}),
|
||||||
|
created() {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||||
|
rootComponent = this
|
||||||
|
},
|
||||||
render() {
|
render() {
|
||||||
return h(
|
return h(
|
||||||
PageShell,
|
PageShell,
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
default() {
|
default: () => {
|
||||||
return h(Page, pageProps || {})
|
return h(this.Page, this.pageProps)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -37,15 +41,35 @@ function createApp(
|
|||||||
pinia.use(piniaPluginPersistedstate)
|
pinia.use(piniaPluginPersistedstate)
|
||||||
}
|
}
|
||||||
|
|
||||||
const app = createSSRApp(PageWithLayout)
|
const app = createSSRApp(PageWithWrapper)
|
||||||
app.use(pinia)
|
app.use(pinia)
|
||||||
app.use(i18n)
|
app.use(i18n)
|
||||||
app.use(vuetify)
|
app.use(vuetify)
|
||||||
|
|
||||||
|
objectAssign(app, {
|
||||||
|
changePage: (pageContext: VikePageContext & PageContext) => {
|
||||||
|
Object.assign(pageContextReactive, reactive(pageContext))
|
||||||
|
rootComponent.Page = markRaw(pageContext.Page)
|
||||||
|
rootComponent.pageProps = markRaw(pageContext.pageProps || {})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// When doing Client Routing, we mutate pageContext (see usage of `app.changePage()` in `_default.page.client.js`).
|
||||||
|
// We therefore use a reactive pageContext.
|
||||||
|
const pageContextReactive = reactive(pageContext)
|
||||||
|
|
||||||
// Make pageContext available from any Vue component
|
// Make pageContext available from any Vue component
|
||||||
setPageContext(app, pageContext)
|
setPageContext(app, pageContextReactive)
|
||||||
|
|
||||||
return app
|
return app
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Same as `Object.assign()` but with type inference
|
||||||
|
function objectAssign<Obj extends object, ObjAddendum>(
|
||||||
|
obj: Obj,
|
||||||
|
objAddendum: ObjAddendum,
|
||||||
|
): asserts obj is Obj & ObjAddendum {
|
||||||
|
Object.assign(obj, objAddendum)
|
||||||
|
}
|
||||||
|
|
||||||
export { createApp }
|
export { createApp }
|
||||||
|
|||||||
@ -3,11 +3,11 @@
|
|||||||
|
|
||||||
import { inject } from 'vue'
|
import { inject } from 'vue'
|
||||||
|
|
||||||
import { PageContext } from '#types/PageContext'
|
import { PageContext, VikePageContext } from '#types/PageContext'
|
||||||
|
|
||||||
import type { App, InjectionKey } from 'vue'
|
import type { App, InjectionKey } from 'vue'
|
||||||
|
|
||||||
const key: InjectionKey<PageContext> = Symbol(undefined)
|
const key: InjectionKey<VikePageContext & PageContext> = Symbol(undefined)
|
||||||
|
|
||||||
function usePageContext() {
|
function usePageContext() {
|
||||||
const pageContext = inject(key)
|
const pageContext = inject(key)
|
||||||
@ -15,7 +15,7 @@ function usePageContext() {
|
|||||||
return pageContext
|
return pageContext
|
||||||
}
|
}
|
||||||
|
|
||||||
function setPageContext(app: App, pageContext: PageContext) {
|
function setPageContext(app: App, pageContext: VikePageContext & PageContext) {
|
||||||
app.provide(key, pageContext)
|
app.provide(key, pageContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-btn :variant="isRoutSelected($attrs.href as string) ? 'tonal' : 'flat'">
|
<v-btn :variant="isRouteSelected($attrs.href as string) ? 'tonal' : 'flat'">
|
||||||
<slot />
|
<slot />
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</template>
|
</template>
|
||||||
@ -8,7 +8,7 @@ import { usePageContext } from '#context/usePageContext'
|
|||||||
|
|
||||||
const pageContext = usePageContext()
|
const pageContext = usePageContext()
|
||||||
|
|
||||||
const isRoutSelected = (href: string) => {
|
const isRouteSelected = (href: string) => {
|
||||||
if (href === '/app') {
|
if (href === '/app') {
|
||||||
return pageContext.urlPathname.indexOf(href) === 0
|
return pageContext.urlPathname.indexOf(href) === 0
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,7 +37,12 @@ import { useCounterStore } from '#stores/counter'
|
|||||||
|
|
||||||
const counter = useCounterStore()
|
const counter = useCounterStore()
|
||||||
|
|
||||||
|
/*
|
||||||
const {
|
const {
|
||||||
routeParams: { id: page },
|
routeParams: { id: page },
|
||||||
} = usePageContext()
|
} = usePageContext()
|
||||||
|
*/
|
||||||
|
const { routeParams } = usePageContext()
|
||||||
|
const page = routeParams?.id
|
||||||
|
// console.log(page)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
2
types/Component.ts
Normal file
2
types/Component.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
export type Component = any
|
||||||
@ -3,31 +3,31 @@ import { PageProps } from '#types/PageProps'
|
|||||||
|
|
||||||
export type {
|
export type {
|
||||||
PageContextServer,
|
PageContextServer,
|
||||||
/*
|
|
||||||
// When using Client Routing https://vike.dev/clientRouting
|
// When using Client Routing https://vike.dev/clientRouting
|
||||||
PageContextClient,
|
PageContextClient,
|
||||||
PageContext,
|
PageContext as VikePageContext,
|
||||||
/ */
|
PageContextBuiltInClientWithClientRouting as PageContextBuiltInClient,
|
||||||
// When using Server Routing
|
// When using Server Routing
|
||||||
|
/*
|
||||||
PageContextClientWithServerRouting as PageContextClient,
|
PageContextClientWithServerRouting as PageContextClient,
|
||||||
PageContextWithServerRouting as PageContext,
|
PageContextWithServerRouting as PageContext,
|
||||||
|
*/
|
||||||
//* /
|
//* /
|
||||||
} from 'vike/types'
|
} from 'vike/types'
|
||||||
|
|
||||||
// https://vike.dev/pageContext#typescript
|
export type PageContext = {
|
||||||
declare global {
|
Page: Page
|
||||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
pageProps?: PageProps
|
||||||
namespace Vike {
|
urlPathname: string
|
||||||
interface PageContext {
|
exports: {
|
||||||
Page: Page
|
documentProps?: {
|
||||||
pageProps?: PageProps
|
title?: string
|
||||||
urlPathname: string
|
description?: string
|
||||||
exports: {
|
|
||||||
documentProps?: {
|
|
||||||
title?: string
|
|
||||||
description?: string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
documentProps?: {
|
||||||
|
title: string
|
||||||
|
description?: string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user