【问题标题】:Vue3: Nested Routes and Dynamic Layout componentVue3:嵌套路由和动态布局组件
【发布时间】:2021-10-30 08:48:42
【问题描述】:

您好 Vue 爱好者, 我一直在开发一个多租户应用程序,但遇到了动态布局问题。

要求:从公共文件夹中加载特定于租户的 layout.vue 文件并将<router-view> 包裹起来。

尝试了dynamic importsdefineAsyncComponent 等一些方法,但无法正常工作。

   // router:
        import store from '../store/index';
        import NestedApp from '../views/NestedApp.vue';
        // const layoutA = () => defineAsyncComponent(import(store.getters.pageLayout('LayoutA')));

        const routes = [
          {
            path: '/:tenant:/:locale',
            name: 'NestedApp',
            component: NestedApp,
            children: [
             {
                path: 'about',
                name: 'About',
                component: () => import(/* webpackChunkName: "about" */ '../views/About.vue'),
                meta: { layout: () => import(store.getters.pageLayout('LayoutA')) }
              }
            ]
        ]


    // NestedApp.vue:
    <template>
      <div class="NestedApp">
        <navbar/>
        <component :is="layoutWrapper">
          <router-view/>
        </component>
      </div>
    </template>
    <script>
    import Navbar from '../components/Navbar.vue';
    export default {
      name: 'NestedApp',
      components: {
        Navbar,
      },
      computed: {
        layoutWrapper() {
          console.info(`layout: ${this.$route.meta.layout}`);
          return this.$route.meta.layout || 'div';
        }
      }
    }
    
    // LayoutA.vue:
    <template>
      <div class="LayoutA">
          <span>Layout A</span>
          <slot/>
      </div>
  </template>
   

我在浏览器控制台中收到以下错误:

【问题讨论】:

    标签: javascript vuejs3 vue-router4 vue-dynamic-components


    【解决方案1】:

    找到了解决此问题的方法。 通过后端 API 调用的模板字符串发送组件,然后通过 defineComponent 和 markRaw 方法创建组件。

    API 响应:

    "Layouts": {
            "LayoutA": {
                "name": "LayoutAbout",
                "template": "<div class='LayoutA' style='background-color: darkgray'><span>Layout A</span><slot/></div>"
            }
    },

    然后在App.vue中使用:

        import { defineComponent, markRaw } from 'vue';
    
        export default {
          name: 'App',
          methods: {
            loadLayout(pageLayout) {
              const layout = this.$store.getters.pageLayout(pageLayout);
    
              this.layoutWrapper = layout ? defineComponent(markRaw({...layout})) : 'div'; 
            }
          },
        created() {
          this.loadLayout(this.$route.meta.layout);
        },
        beforeRouteUpdate(to) {
          this.loadLayout(to.meta.layout);
        },
    }
    <template>
      <div class="App">
        <navbar/>
        <component :is="layoutWrapper">
          <router-view/>
        </component>
      </div>
    </template>

    【讨论】:

    • 再次评论以获得更好的影响力
    猜你喜欢
    • 1970-01-01
    • 2020-07-21
    • 2021-03-14
    • 1970-01-01
    • 2021-01-20
    • 1970-01-01
    • 2016-11-12
    • 2015-08-01
    • 1970-01-01
    相关资源
    最近更新 更多