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 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
|
||||
async function render(pageContext: PageContextClient) {
|
||||
const { Page, pageProps } = pageContext
|
||||
if (!Page) throw new Error('Client-side render() hook expects pageContext.Page to be defined')
|
||||
const app = createApp(Page, pageProps, pageContext)
|
||||
app.mount('#app')
|
||||
let app: ReturnType<typeof createApp>
|
||||
async function render(pageContext: VikePageContext & PageContext) {
|
||||
if (!app) {
|
||||
app = createApp(pageContext)
|
||||
app.mount('#app')
|
||||
} else {
|
||||
// console.log(pageContext)
|
||||
app.changePage(pageContext)
|
||||
}
|
||||
}
|
||||
|
||||
/* To enable Client-side Routing:
|
||||
export const clientRouting = true
|
||||
// !! WARNING !! Before doing so, read https://vike.dev/clientRouting */
|
||||
function onHydrationEnd() {
|
||||
// eslint-disable-next-line no-console
|
||||
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 { onHydrationEnd }
|
||||
export { onPageTransitionStart }
|
||||
export { onPageTransitionEnd }
|
||||
|
||||
@ -6,20 +6,14 @@ import { META } from '#src/env'
|
||||
|
||||
import { createApp } from './app'
|
||||
|
||||
import type { PageContextServer } from '#types/PageContext'
|
||||
import type { PageContextServer, PageContext } from '#types/PageContext'
|
||||
import type { App } from 'vue'
|
||||
|
||||
// See https://vike.dev/data-fetching
|
||||
export const passToClient = ['pageProps', 'urlPathname', 'routeParams']
|
||||
export const passToClient = ['pageProps', /* 'urlPathname', */ 'routeParams']
|
||||
|
||||
async function render(pageContext: PageContextServer) {
|
||||
const { Page, pageProps } = pageContext
|
||||
// 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)
|
||||
async function render(pageContext: PageContextServer & PageContext) {
|
||||
const app = createApp(pageContext, false)
|
||||
|
||||
const appHtml = await renderToString(app)
|
||||
|
||||
|
||||
@ -1,32 +1,36 @@
|
||||
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 { setPageContext } from '#context/usePageContext'
|
||||
import i18n from '#plugins/i18n'
|
||||
import pinia from '#plugins/pinia'
|
||||
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)
|
||||
|
||||
function createApp(
|
||||
Page: Page,
|
||||
pageProps: PageProps | undefined,
|
||||
pageContext: PageContext,
|
||||
isClient = true,
|
||||
) {
|
||||
const PageWithLayout = defineComponent({
|
||||
function createApp(pageContext: VikePageContext & PageContext, isClient = true) {
|
||||
let rootComponent: Component
|
||||
const PageWithWrapper = defineComponent({
|
||||
data: () => ({
|
||||
Page: markRaw(pageContext.Page),
|
||||
pageProps: markRaw(pageContext.pageProps || {}),
|
||||
isClient,
|
||||
}),
|
||||
created() {
|
||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||
rootComponent = this
|
||||
},
|
||||
render() {
|
||||
return h(
|
||||
PageShell,
|
||||
{},
|
||||
{
|
||||
default() {
|
||||
return h(Page, pageProps || {})
|
||||
default: () => {
|
||||
return h(this.Page, this.pageProps)
|
||||
},
|
||||
},
|
||||
)
|
||||
@ -37,15 +41,35 @@ function createApp(
|
||||
pinia.use(piniaPluginPersistedstate)
|
||||
}
|
||||
|
||||
const app = createSSRApp(PageWithLayout)
|
||||
const app = createSSRApp(PageWithWrapper)
|
||||
app.use(pinia)
|
||||
app.use(i18n)
|
||||
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
|
||||
setPageContext(app, pageContext)
|
||||
setPageContext(app, pageContextReactive)
|
||||
|
||||
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 }
|
||||
|
||||
@ -3,11 +3,11 @@
|
||||
|
||||
import { inject } from 'vue'
|
||||
|
||||
import { PageContext } from '#types/PageContext'
|
||||
import { PageContext, VikePageContext } from '#types/PageContext'
|
||||
|
||||
import type { App, InjectionKey } from 'vue'
|
||||
|
||||
const key: InjectionKey<PageContext> = Symbol(undefined)
|
||||
const key: InjectionKey<VikePageContext & PageContext> = Symbol(undefined)
|
||||
|
||||
function usePageContext() {
|
||||
const pageContext = inject(key)
|
||||
@ -15,7 +15,7 @@ function usePageContext() {
|
||||
return pageContext
|
||||
}
|
||||
|
||||
function setPageContext(app: App, pageContext: PageContext) {
|
||||
function setPageContext(app: App, pageContext: VikePageContext & PageContext) {
|
||||
app.provide(key, pageContext)
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<v-btn :variant="isRoutSelected($attrs.href as string) ? 'tonal' : 'flat'">
|
||||
<v-btn :variant="isRouteSelected($attrs.href as string) ? 'tonal' : 'flat'">
|
||||
<slot />
|
||||
</v-btn>
|
||||
</template>
|
||||
@ -8,7 +8,7 @@ import { usePageContext } from '#context/usePageContext'
|
||||
|
||||
const pageContext = usePageContext()
|
||||
|
||||
const isRoutSelected = (href: string) => {
|
||||
const isRouteSelected = (href: string) => {
|
||||
if (href === '/app') {
|
||||
return pageContext.urlPathname.indexOf(href) === 0
|
||||
}
|
||||
|
||||
@ -37,7 +37,12 @@ import { useCounterStore } from '#stores/counter'
|
||||
|
||||
const counter = useCounterStore()
|
||||
|
||||
/*
|
||||
const {
|
||||
routeParams: { id: page },
|
||||
} = usePageContext()
|
||||
*/
|
||||
const { routeParams } = usePageContext()
|
||||
const page = routeParams?.id
|
||||
// console.log(page)
|
||||
</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 {
|
||||
PageContextServer,
|
||||
/*
|
||||
// When using Client Routing https://vike.dev/clientRouting
|
||||
PageContextClient,
|
||||
PageContext,
|
||||
/ */
|
||||
|
||||
// When using Client Routing https://vike.dev/clientRouting
|
||||
PageContextClient,
|
||||
PageContext as VikePageContext,
|
||||
PageContextBuiltInClientWithClientRouting as PageContextBuiltInClient,
|
||||
// When using Server Routing
|
||||
/*
|
||||
PageContextClientWithServerRouting as PageContextClient,
|
||||
PageContextWithServerRouting as PageContext,
|
||||
*/
|
||||
//* /
|
||||
} from 'vike/types'
|
||||
|
||||
// https://vike.dev/pageContext#typescript
|
||||
declare global {
|
||||
// eslint-disable-next-line @typescript-eslint/no-namespace
|
||||
namespace Vike {
|
||||
interface PageContext {
|
||||
Page: Page
|
||||
pageProps?: PageProps
|
||||
urlPathname: string
|
||||
exports: {
|
||||
documentProps?: {
|
||||
title?: string
|
||||
description?: string
|
||||
}
|
||||
}
|
||||
export type PageContext = {
|
||||
Page: Page
|
||||
pageProps?: PageProps
|
||||
urlPathname: string
|
||||
exports: {
|
||||
documentProps?: {
|
||||
title?: string
|
||||
description?: string
|
||||
}
|
||||
}
|
||||
documentProps?: {
|
||||
title: string
|
||||
description?: string
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user