使用 Vite 在 Vue 3 中进行动态布局
Dynamic layout in Vue 3 with Vite
Vue 和 Vite 的新手,但试图让动态布局在这里正常工作。我相信我有需要的东西,但问题是 meta 似乎总是以空对象或 undefined
.
的形式出现
AppLayout.vue
<script setup lang="ts">
import AppLayoutDefault from './stub/AppLayoutDefault.vue'
import { markRaw, watch } from 'vue'
import { useRoute } from 'vue-router'
const layout = markRaw(AppLayoutDefault)
const route = useRoute()
console.log('Current path: ', route.path)
console.log('Route meta:', route.meta)
watch(
() => route.meta,
async (meta) => {
try {
const component = await import(`./stub/${meta.layout}.vue`)
layout.value = component?.default || AppLayoutDefault
} catch (e) {
layout.value = AppLayoutDefault
}
},
{ immediate: true }
)
</script>
<template>
<component :is="layout"> <router-view /> </component>
</template>
App.vue
<script setup lang="ts">
import AppLayout from '@/layouts/AppLayout.vue'
</script>
<template>
<AppLayout>
<router-view />
</AppLayout>
</template>
每条路线都有适当的元集,其中 属性 称为 layout
。
我似乎无法在第一次加载时或在导航栏(只是路由器-link)中单击任何 link 时正确应用布局。
主要问题是 layout
被初始化为 markRaw()
,这不是反应式 ref
:
const layout = markRaw(AppLayoutDefault) // ❌ not reactive
解决方案
- 将
layout
初始化为 ref
。
- 与其查看完整的
route
对象,不如查看 route.meta?.layout
,因为这是处理程序唯一相关的字段。
- 用
markRaw()
包装 layout
的新值以避免对组件定义的反应。
const layout = ref() 1️⃣
watch(
() => route.meta?.layout as string | undefined, 2️⃣
async (metaLayout) => {
try {
const component = metaLayout && await import(/* @vite-ignore */ `./${metaLayout}.vue`)
layout.value = markRaw(component?.default || AppLayoutDefault) 3️⃣
} catch (e) {
layout.value = markRaw(AppLayoutDefault) 3️⃣
}
},
{ immediate: true }
)
Vue 和 Vite 的新手,但试图让动态布局在这里正常工作。我相信我有需要的东西,但问题是 meta 似乎总是以空对象或 undefined
.
AppLayout.vue
<script setup lang="ts">
import AppLayoutDefault from './stub/AppLayoutDefault.vue'
import { markRaw, watch } from 'vue'
import { useRoute } from 'vue-router'
const layout = markRaw(AppLayoutDefault)
const route = useRoute()
console.log('Current path: ', route.path)
console.log('Route meta:', route.meta)
watch(
() => route.meta,
async (meta) => {
try {
const component = await import(`./stub/${meta.layout}.vue`)
layout.value = component?.default || AppLayoutDefault
} catch (e) {
layout.value = AppLayoutDefault
}
},
{ immediate: true }
)
</script>
<template>
<component :is="layout"> <router-view /> </component>
</template>
App.vue
<script setup lang="ts">
import AppLayout from '@/layouts/AppLayout.vue'
</script>
<template>
<AppLayout>
<router-view />
</AppLayout>
</template>
每条路线都有适当的元集,其中 属性 称为 layout
。
我似乎无法在第一次加载时或在导航栏(只是路由器-link)中单击任何 link 时正确应用布局。
主要问题是 layout
被初始化为 markRaw()
,这不是反应式 ref
:
const layout = markRaw(AppLayoutDefault) // ❌ not reactive
解决方案
- 将
layout
初始化为ref
。 - 与其查看完整的
route
对象,不如查看route.meta?.layout
,因为这是处理程序唯一相关的字段。 - 用
markRaw()
包装layout
的新值以避免对组件定义的反应。
const layout = ref() 1️⃣
watch(
() => route.meta?.layout as string | undefined, 2️⃣
async (metaLayout) => {
try {
const component = metaLayout && await import(/* @vite-ignore */ `./${metaLayout}.vue`)
layout.value = markRaw(component?.default || AppLayoutDefault) 3️⃣
} catch (e) {
layout.value = markRaw(AppLayoutDefault) 3️⃣
}
},
{ immediate: true }
)