Vue 3 中使用 Vite 实现动态布局

ste*_*ish 6 vue.js vue-router vuejs3 vite

Vue 和 Vite 新手,但试图让动态布局在这里正常工作。我相信我有需要的东西,但问题是元似乎总是作为空对象或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>
Run Code Online (Sandbox Code Playgroud)

应用程序.vue

<script setup lang="ts">
  import AppLayout from '@/layouts/AppLayout.vue'
</script>
<template>
  <AppLayout>
    <router-view />
  </AppLayout>
</template>
Run Code Online (Sandbox Code Playgroud)

每个路由都有适当的元集,其属性称为layout

我似乎无法在第一次加载或任何点击导航栏中的链接(这只是路由器链接)时正确应用布局。

ton*_*y19 9

主要问题是layout初始化为markRaw(),这不是反应式的ref

\n
const layout = markRaw(AppLayoutDefault) // \xe2\x9d\x8c not reactive\n
Run Code Online (Sandbox Code Playgroud)\n

解决方案

\n
    \n
  1. 初始化layoutref.
  2. \n
  3. 不要观看整个route对象,而是观看,route.meta?.layout因为这是处理程序的唯一相关字段。
  4. \n
  5. layout\ 的新值括起来markRaw(),以避免对组件定义产生反应。
  6. \n
\n
const layout = ref() 1\xef\xb8\x8f\xe2\x83\xa3\n\nwatch(\n  () => route.meta?.layout as string | undefined, 2\xef\xb8\x8f\xe2\x83\xa3\n  async (metaLayout) => {\n    try {\n      const component = metaLayout && await import(/* @vite-ignore */ `./${metaLayout}.vue`)\n      layout.value = markRaw(component?.default || AppLayoutDefault) 3\xef\xb8\x8f\xe2\x83\xa3\n    } catch (e) {\n      layout.value = markRaw(AppLayoutDefault) 3\xef\xb8\x8f\xe2\x83\xa3\n    }\n  },\n  { immediate: true }\n)\n
Run Code Online (Sandbox Code Playgroud)\n

演示

\n