5

I'm having an issue with Vue.js Router. As the title suggests, this issue is about a child route that just displays the parent route's page. For example, there is a path to your account details www.example.com/account. Then, in your account you can see different projects, which will be available with the route www.example.com/account/project/foobar where project/foobar is a child route of /account and foobar is a dynamic parameter. Now, when you go to a project you expect to see the project, but instead you still see the account page.

This is the issue that I have. I feel like everything is setup correctly, but the code is shown below anyway.

router.js

const routes = [
    ..., // other routes
    {
        path: '/account',
        component: AccountPage,
        meta: {
            title: 'Your account'
        },
        children: [
            {
                path: 'project/:id',
                component: ProjectPage,
                props: true,
                meta: {
                    title: 'Project'
                }
            }
        ]
    }
];

const router = new VueRouter({
    routes,
    mode: 'history'
});

// Sets meta tags in the HEAD tag to, for example, change the title.
router.beforeEach((to, from, next) => {
    const nearestWithTitle = to.matched.slice().reverse().find(r => r.meta && r.meta.title);

    const nearestWithMeta = to.matched.slice().reverse().find(r => r.meta && r.meta.metaTags);
    const previousNearestWithMeta = from.matched.slice().reverse().find(r => r.meta && r.meta.metaTags);

    if(nearestWithTitle) document.title = nearestWithTitle.meta.title;

    Array.from(document.querySelectorAll('[data-vue-router-controlled]')).map(el => el.parentNode.removeChild(el));

    if(!nearestWithMeta) return next();

    nearestWithMeta.meta.metaTags.map(tagDef => {
        const tag = document.createElement('meta');

        Object.keys(tagDef).forEach(key => {
            tag.setAttribute(key, tagDef[key]);
        });

        tag.setAttribute('data-vue-router-controlled', '');

        return tag;
    })
    .forEach(tag => document.head.appendChild(tag));

    next();
});

I quadruple checked if I use the correct components and I'm 100% sure I do. Though, it just keeps showing the account page instead of the project page. I did notice that the title changes because of the code to change meta tags, so that means it knows that the next page is the project page. I also checked what the function parameter to contains and quickly figured out that this is the project route it wants to go to, which totally makes sense.

ProjectPage.vue

<template>
    <transition name="project-anim">
        <div>
            Foo BAR
        </div>
<    /transition>
</template>

<script>
    import MeineProject from '../../components/meine/project';

    export default {
        components: {
            MeineProject
        }
    }
</script>

Going to the URL directly (no route navigation through links or anything), also just shows the account page, so I'm pretty sure it's not the transition that isn't working for some reason. There are NO errors or warnings in the console.

I'm completely out of options. I hope you can help me out. Thanks for your time! :)

4
  • Does the account page template have a <router-view>? Commented Nov 22, 2019 at 10:51
  • I have one in my main App.vue. Do you need seperate ones for children? If that's the case, I'm guessing that I shouldn't make it a child route as I want to go to a completely different page. Commented Nov 22, 2019 at 10:54
  • You've answered your question :) Yes, if you don't want the project page to be rendered inside the account page, then it shouldn't be a child route of the account page. Commented Nov 22, 2019 at 10:57
  • Great stuff! If you want, you can post an answer and I'll accept it. Commented Nov 22, 2019 at 10:59

2 Answers 2

3

The account page needs a <router-view> to render the child routes. If you don't want the project page to be rendered inside the account page, then it shouldn't be a child route of the account page.

You probably want a route config like this:

{
    path: '/account',
    component: AccountPage,
    meta: {
        title: 'Your account'
    },
},
{
    path: 'project/:id',
    component: ProjectPage,
    props: true,
    meta: {
        title: 'Project'
    }
}

You can set the project route to /account/project/:id but it won't be a child route of the account route even though it is prefixed with /account.

Sign up to request clarification or add additional context in comments.

Comments

2

Since a router-view is necessary into parent component, you can keep the children this way and each child will render on a completely different page:

{
    path: '/account',
    component: {
        // render router-view into parent
        render(c) { 
            return c('router-view'); 
        }
    },
    children: [
        {
            path: '',
            component: AccountPage,
            meta: {
            title: 'Your account'
        },
        {
            path: 'project/:id',
            component: ProjectPage,
            props: true,
            meta: {
            title: 'Project'
        },
    ]
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.