在vue-router中基于路由参数的动态组件

时间:2019-12-18 16:53:44

标签: vue.js vue-router

在Vue中是否可以根据路由参数的值动态使用组件?

这是我要做的事的一个例子:

path: '/model/:modelName',
components: {
  default: ModelDefinition.models.find((model) => model.key === $route.params.modelName),
},

问题是:$route在这里不可用。 modelName都不是。

如果default也可以是一个函数(类似于props),那可能会很好:

path: '/model/:modelName',
components: {
  default: (modelName) => (ModelDefinition.models.find((model) => model.key === $route.params.modelName)),
},

这个函数实际上被我吓到了,但是参数似乎是某种函数,当然不是我希望的modelName。

我需要这个的原因是:该路由实际上有很多配置,为各种事物指定了很多组件和值。如果我必须为每个模型都指定它,那将是冗长而重复的,并且必须为我们添加到系统中的每个模型进行扩展。

2 个答案:

答案 0 :(得分:1)

我不确定您是否必须使用 vue-router 来“魔术”-为什么不只处理组件内部的参数(或创建一个容器组件,并处理参数在那里)?

下面的代码片段显示您可以使用外部数据来控制应显示的组件。如果您向下传递 model 参数,则可以显示任何现有(和注册的)组件名称。

const CompA = {
  template: `<div class="border-blue">COMP-A</div>`
}

const CompB = {
  template: `<div class="border-red">COMP-B</div>`
}

new Vue({
  el: "#app",
  components: {
    CompA,
    CompB
  },
  data: {
    selected: ''
  }
})
[class^="border-"] {
  padding: 10px;
}

.border-blue {
  border: 1px solid blue;
}

.border-red {
  border: 1px solid red;
}
<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<div id="app">
  <select v-model="selected">
    <option disabled value="">Please select one</option>
    <option>CompA</option>
    <option>CompB</option>
  </select>
  <br />
  <span>Selected: {{ selected }}</span>
  <br />
  <br /> Here's a variable component - based on external data:
  <component :is="selected"></component>
</div>

答案 1 :(得分:0)

components 声明中,this 不可用,因此您无法访问道具和其他实例数据。

您可以做的是创建一个返回组件的计算属性。像这样:

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

<script>
export default {
  props: {
    componentName: String,
  },
  computed: {
    componentInstance() {
      return () => import(`./modules/${this.componentName}/template.vue`);
    },
  },
};
</script>