Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue Router moves to route but loads wrong component

I have the following router config:

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: '/'
    }
  ]
});

And when I'm at the root route it correctly identifies the route name as notselected. When I route to any of the "/package/[id]" routes though it continues to load the PackageUnselected component instead of the appropriate route (aka, ViewPackageMeta, PackageDocs, etc.).

Now at the point in the DOM where I want the route to insert the route's component I have the following template:

<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>

And because I have installed vuex-router-sync it's easy to see the route state at any given time. So when clicking on the route that should load PackageDocs:

enter image description here

But the component view window of vue-devtools looks like this:

enter image description here

the highlighted area shows that NO component has been loaded into the tabs. I then tried adding a component to the definition of the parent route /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
    }
  ]
},

I then had to create the world simplest component for Packages:

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

This results in the following:

enter image description here

Hmmm. Can't figure out what to do next. Anyone have any pointers?

like image 753
ken Avatar asked Jul 20 '18 23:07

ken


People also ask

How do I redirect my Vue router?

But what if you want to redirect programmatically, without using an anchor tag at all? If you're using Vue Router you'll push the new URL onto the router in order to do a redirect: this. $router. push('www.yoursite.com/blog') .

What is lazy loading in VUE router?

vue file. Lazy loading refers to an approach by which all the scripts are not loaded on the DOM as the application starts. Instead, they're only loaded when requested, which makes the JavaScript bundle size very small at initial load. Vue.

How do I switch between VUE components?

You need to bind the value into the component and then emit a new value to the parent when you click a link. If you emit the event input and bind the value value , then you can use v-model .


1 Answers

When I route to any of the "/package/[id]" routes though it continues to load the PackageUnselected component instead of the appropriate route (aka, ViewPackageMeta, PackageDocs, etc.).

That is the correct behavior of the vue-router.

Children can only be loaded when URL paths are:

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

Parent path may not have component defined if you have configured redirect option and your user, who opens /package/[id] will be redirected to your default path (could be anything).

Lets move to the next part of your question...

<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>

You don't need to create here 4 different <router-view> tags, you just need one where all your children components will display html code.

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

Now you will have only one router-view and it's the default one. When user clicks on any of your tabs you just need to this.$router.push a new path on @click-event in Packages component. That's it.

I have created a simple example (codepen) to demonstrate how this task can be solved:

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>
like image 152
AndrewShmig Avatar answered Oct 01 '22 02:10

AndrewShmig