【问题标题】:Vue Router moves to route but loads wrong componentVue Router 移动到路由但加载了错误的组件
【发布时间】:2018-12-29 07:04:03
【问题描述】:

我有以下路由器配置:

export default new Router({
  mode: 'history',
  routes: [
    {
      path: '/',
      name: 'notselected',
      component: PackageUnselected
    },
    {
      path: '/package/:id',
      children: [
        { path: 'meta', name: 'packageMeta', component: ViewPackageMeta },
        { path: 'readme', name: 'packageReadme', component: PackageReadme },
        { path: 'docs', name: 'packageDocs', component: PackageDocs },
        {
          path: 'playground',
          name: 'packagePlayground',
          component: PackagePlayground
        }
      ]
    },
    {
      path: '/about',
      name: 'about',
      component: About
    },
    {
      path: '*',
      redirect: '/'
    }
  ]
});

当我在根路由时,它正确地将路由名称标识为notselected。当我路由到任何“/package/[id]”路由时,它会继续加载PackageUnselected 组件而不是适当的路由(又名ViewPackageMetaPackageDocs 等)。

现在,在 DOM 中我希望路由插入路由组件的位置,我有以下模板:

<v-tab-item v-for="item in tabs" :id="'tab-item-' + item" :key="item" exact>
  item: {{item}}
  <router-view :selectedPackage="selected"></router-view>
</v-tab-item>

因为我已经安装了vuex-router-sync,所以很容易在任何给定时间查看路线状态。所以当点击应该加载PackageDocs的路径时:

但是vue-devtools的组件视图窗口是这样的:

突出显示的区域显示没有组件已加载到选项卡中。然后我尝试在父路由/package/:id的定义中添加一个组件

{
  path: '/package/:id',
  component: Packages,
  children: [
    { path: 'meta', name: 'packageMeta', component: ViewPackageMeta },
    { path: 'readme', name: 'packageReadme', component: PackageReadme },
    { path: 'docs', name: 'packageDocs', component: PackageDocs },
    {
      path: 'playground',
      name: 'packagePlayground',
      component: PackagePlayground
    }
  ]
},

然后我必须为Packages 创建世界上最简单的组件:

<template>
  <view-router-view></view-router-view>
</template>

这会导致以下结果:

嗯。想不出下一步该怎么做。有没有人指点一下?

【问题讨论】:

  • 您阅读过nested routes 上的文档吗?您可能需要一个显示活动选项卡的&lt;view-router&gt; 插座,但选项卡循环正在为每个插座创建一个单独的插座。这反映了您在开发工具中看到的内容。
  • 是的,我知道我从使用组件的默认 Vuetify 方式开始(依赖于 v-model),并计划稍后对其进行重构。我现在已经对其进行了重构,以便删除 VTabItem 并且有一个 &lt;view-router&gt;。尽管如此,总体问题仍然没有改变。
  • 我已经让它工作了,但是以一种不优雅的方式......我刚刚创建了一些根路由,但我希望以更类似于我开始的方式来解决问题。跨度>
  • 你熟悉dynamic components吗?我发现它们至少是我认为的一种比拥有许多路线更优雅的方法。
  • 是的,我在 Ember 中广泛使用了它们,我记得我在 VueJS 中读到过它们,但我还没有从工具包中提取出来。我会看看,我可以看到它们在许多情况下如何工作得更好。

标签: vue.js vuejs2 vue-router


【解决方案1】:

当我路由到任何“/package/[id]”路由时,尽管它继续 加载 PackageUnselected 组件而不是适当的 路线(又名 ViewPackageMeta、PackageDocs 等)。

这是 vue-router 的正确行为。

只有当 URL 路径为:时才能加载子项:

  • /package/[id]/meta
  • /package/[id]/readme
  • /package/[id]/playground
  • /package/[id]/docs

如果您配置了redirect 选项,则父路径可能未定义组件,并且打开/package/[id] 的用户将被重定向到您的默认路径(可以是任何路径)。

让我们转到问题的下一部分...

<v-tab-item v-for="item in tabs" :id="'tab-item-' + item" :key="item" exact>
  item: {{item}}
  <router-view :selectedPackage="selected"></router-view>
</v-tab-item>

您无需在此处创建 4 个不同的 &lt;router-view&gt; 标签,您只需要一个所有子组件都将显示 html 代码的标签。

<v-tab-item v-for="item in tabs" :id="'tab-item-' + item" :key="item" exact></v-tab-item>
<router-view></router-view>

现在您将只有一个router-view,它是default 一个。当用户单击您的任何选项卡时,您只需要在Packages 组件中的@click-event 上this.$router.push 一个新路径。就是这样。

我创建了一个simple example (codepen) 来演示如何解决此任务:

Vue.use(VueRouter);

// Components
let MetaPackages = {
  mounted() { console.log('Mounted MetaPackages...'); },
  template: `<div>MetaPackages...</div>`,
};
let DocsPackages = {
  mounted() { console.log('Mounted DocsPackages...'); },
  template: `<div>DocsPackages...</div>`,
};
let ReadmePackages = {
  mounted() { console.log('Mounted ReadmePackages...'); },
  template: `<div>ReadmePackages...</div>`,
};
let Packages = {
  mounted() { console.log('Mounted Packages... ' + this.$route.path); },
  template: '<div>Packages (parent) screen...<br/><router-view></router-view></div>',
};

// Router
const router = new VueRouter({
  mode: 'hash',
  routes: [
    {
      path: "/packages/:id",
      component: Packages,
      children: [
        {path:"meta", component: MetaPackages},
        {path:"docs", component: DocsPackages},
        {path:"readme", component: ReadmePackages}
      ]
    }
  ]
});

// Vue instance
const vm = new Vue({
  el: '#app',
  router,
  components: {Packages, MetaPackages, DocsPackages, ReadmePackages}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue-router/3.0.2/vue-router.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"> 
  <router-link to="/packages/100/meta">Meta</router-link>
  <router-link to="/packages/100/docs">Docs</router-link>
  <router-link to="/packages/100/readme">Readme</router-link>
  <hr/>
  <router-view></router-view>
</div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-03
    • 2017-06-20
    • 2021-07-22
    • 2021-05-26
    • 2018-10-11
    • 2019-02-27
    • 2019-04-21
    相关资源
    最近更新 更多