[英]Dynamic layout in Vue 3 with Vite
Vue 和 Vite 的新手,但試圖讓動態布局在這里正常工作。 我相信我有需要的東西,但 meta 的問題似乎總是以空 object 或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
的屬性。
就此而言,我似乎無法在第一次加載時或在導航欄(只是路由器鏈接)中單擊任何鏈接時正確應用他的布局。
主要問題是layout
被初始化為markRaw()
,它不是反應式ref
:
const layout = markRaw(AppLayoutDefault) // ❌ not reactive
layout
初始化為ref
。route
對象, route.meta?.layout
查看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 }
)
托尼的解決方案很棒。 但是您需要在手表內部添加 computed ,因為它會阻止第一個初始化的“布局”變量的代碼執行,該變量仍未定義,並且會導致不必要的渲染。 因此,請將計算出的 function 添加到 watch function 中。此外,您需要查看“route.path”而不是“route.meta?.layout”。
import DefaultLayout from '@/layouts/Default.vue'
import { markRaw, ref } from '@vue/reactivity'
import { computed, watch } from '@vue/runtime-core'
import { useRoute } from 'vue-router'
const layout = ref()
const route = useRoute()
watch(
computed(() => route.path), async () => {
let metaLayout = route.meta?.layout
try {
const metaLayoutComponent = metaLayout && await import(`./layouts/${metaLayout}.vue`)
layout.value = markRaw(metaLayoutComponent?.default || DefaultLayout)
} catch (error) {
layout.value = markRaw(DefaultLayout)
}
}
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.