在Vue Router中有条件地导入组件

问题描述 投票:0回答:3

我想有条件地在 vue 路由器中导入一个组件。这是我目前所拥有的:

children: [
  {
    path: ':option',
    component: () => import('../components/Option1.vue'),
  },
],

根据

:option
是什么,我想导入不同的组件(
Option1.vue
Option2.vue
等)。我知道我可以放置几个
children
但我实际上需要父组件中的
option
变量(我会测试路由是否有选项)。

怎么可能做到这一点? 预先感谢:)

vue.js vue-router vuejs3
3个回答
6
投票

您可以创建一个包含动态组件的加载器组件,而不是进行条件路由。在加载器中,您将根据路由参数有条件地延迟加载选项组件。这不仅在路由时更容易,而且您也不必手动导入任何内容,并且只会导入使用的选项。

第 1 步。 路由至选项加载器组件

路由器

{
  path: ':option',
  component: () => import('../components/OptionLoader.vue'),
}

第 2 步。 在该选项加载器模板中,使用动态组件,该组件将由称为

optionComponent
的计算确定:

OptionLoader.vue

<template>
  <component :is="optionComponent" />
</template>

第 3 步。 创建一个计算延迟加载当前选项

OptionLoader.vue

export default {
  computed: {
    optionComponent() {
      return () => import(`@/components/Option${this.$route.params.option}.vue`);
    }
  }
}

这将加载名为“Option5.vue”的组件,例如,当

option
路由参数为
5
时。现在您有了一个延迟加载的选项加载器,无需手动导入每个选项。


编辑: OP 现在表示他正在使用 Vue 3。

Vue 3

对于 Vue 3,将计算更改为使用

defineAsyncComponent
:

OptionsLoader.vue

import { defineAsyncComponent } from "vue";
computed: {
  optionComponent() {
    return defineAsyncComponent(() =>
      import(`@/components/Option${this.$route.params.option}.vue`)
    );
  }
}

1
投票

这是在 VueJS3 中可以使用的东西:

<template>
  <component :is="userComponent"/>
</template>

<script>
import { defineAsyncComponent } from 'vue';
import { useRoute, useRouter } from 'vue-router';

export default {
  computed: {
    userComponent() {
      const route = useRoute();
      const router = useRouter();

      const components = {
        first: 'Option1',
        second: 'Option2',
        third: 'OtherOption',
        fourth: 'DefaultOption',
      };
      if (components[route.params.option]) {
        return defineAsyncComponent(() => import(`./options/${components[route.params.option]}.vue`));
      }
      router.push({ path: `/rubrique/${route.params.parent}`, replace: true });
      return false;
    },
  },
};
</script>

来源:https://v3-migration.vuejs.org/writing-changes/async-components.html 对于带有“

return
”的行,可能会收到类似这样的错误消息:
Syntax Error: TypeError: Cannot read property 'range' of null

在这种情况下,这意味着您可能想从

babel-eslint
迁移到
@babel/eslint-parser
(来源:https://babeljs.io/blog/2020/07/13/the-state-of-babel-eslint#现在


0
投票

哦,这真的很酷,所以我可以 foreach 组件列表中的组件,然后按自定义顺序为每个页面渲染组件🤩

理论上,您可以拥有一个块数组并按自定义顺序加载所有内容

let blocks = [
    {'type': 'header', 'blockContent': [headerData]},
    {'type': 'section1', 'blockContent': [headerData]},
    {'type': 'component1', 'blockContent': [componentData]},
    {'type': 'component2', 'blockContent': [componentData]},
    {'type': 'section2', 'blockContent': [headerData]},
    {'type': 'component3', 'blockContent': [componentData]},
    {'type': 'footer', 'blockContent': [footerData]}
]



<div v-for(block in blocks)>
  <div v-if="block.type == 'header'">
    </header-component>
  </div>
  <div v-if="block.type == 'section1'">
    </section1-component>
  </div>
  <div v-if="block.type == 'section2'">
    </section2-component>
  </div>
  <div v-if="block.type == 'component1'">
    </component1-component>
  </div>
  <div v-if="block.type == 'component2'">
    </component2-component>
  </div>
  <div v-if="block.type == 'component3'">
    </component3-component>
  </div>
  <div v-if="block.type == 'footer'">
    </footer-component>
  </div>
</div>

这个问题已经得到了回答,所以我可以随意咆哮,以防将来有人需要这个想法:)

© www.soinside.com 2019 - 2024. All rights reserved.