Vue-meta: Children components of render functions

Created on 4 Nov 2016  路  14Comments  路  Source: nuxt/vue-meta

I'm using vue-meta on a children component of a render function that use createElement to render a component List with different props given by routes.

The method beforeMount is called everytime I change the route (tried to log on it), but metaInfo updates only at first render (logged on title() method as suggested by docs), how is it possible? If i use metaInfo on component with render function everything is working.

Thank you in advice.

bug

All 14 comments

Hi @liqueflies - thank you for giving vue-meta a try. I'm not exactly sure what you're asking here - are you experiencing a bug? Is the metaInfo of the child component not being included in your data?

Okay maybe I didn't explain what was my problem :)

Two of my routes:

 { path: '/', component: switch('home') },
 { path: '/about', component: switch('about') },

switch function (the render function):

export function switch (page) {
    return {
        name: `section-${page}`,
        render (h) {
            return h(MyChildComponent, {
                props: { page }
            });
        }
    };

MyChildComponent:

export default {
    name: 'my-child-component',
    props: {
        page: VueTypes.string
    },
    metaInfo: {
        title() {
            return this.page;
        }
    }
};

The title of MyChildComponent should show home or about.
But show the correct one only at first app run, not when i change the route clicking a link.

I tried to move metaInfo to switch function and it works:

export function switch (page) {
    return {
        name: `section-${page}`,
        metaInfo: {
           title() {
             return page;
           }
        },
        render (h) {
            return h(MyChildComponent, {
                props: { page }
            });
        }
    };

I think I'm encountering a bug, beacause I logged every method of Vue instance lifecycle and everytime it log the correct message.

Maybe there's a problem in child component when parent has render function.

Maybe there's cache problem with child when parent has render function.

Maybe I am the problem :)

Have you ever encountered this issue?

Thank you so much for vue-meta :)

Out of interest, what version of vue-meta are you using? The one from npm?

Yes, the One from npm.

Try uninstalling it and re-installing using Github as a source:

$ npm install https://github.com/declandewet/vue-meta --save

It might solve your issue :)

https://github.com/declandewet/vue-meta#disclaimer

Please note that this project is still in very early alpha development and is not considered to be production ready. You have been warned. There is no sanitization yet, no tests, and you might even find some features are still missing.

vue-meta is not yet ready for a release on npm yet - I'm still working on getting it to a full working state.

Hi, yes found now the disclaimer :)

If I install from github, there is no main file, so I have to import from 'vue-meta/src' it gives me Uncaught SyntaxError: Unexpected token import error. Using vue-cli with webpack.

If you know how to handle the error, or I'll wait for stable release on npm.

Keep working on it, really good! :) 馃憤

If I install from github, there is no main file, so I have to import from 'vue-meta/src' it gives me Uncaught SyntaxError: Unexpected token import error. Using vue-cli with webpack.

That's because the Github version isn't transpiled - The main field points to lib/, so you have two options - compile it with npm run build or add it to your resolver in your Webpack config. Or just wait for the official release :smile:

Following your tips, I simply excluded vue-meta from exclude loaders on webpack, but I'm still encountering the same issue: the child component rendered with a function from parent not switch on router-link but only at first app run. The other lifecycle methods are called everytime i click on link.

I see - I'm able to reproduce the issue - since this is pretty edge-case I'm going to add a test case for it after the initial release. Use your workaround for now.

Hey @declandewet

Do you have an ETA for the official release?

@Atinux I'm aiming for either tomorrow or the day after. :smile:

馃憦
I'm having a prototype of nuxt.js working, missing vue-meta to rock 馃槃

That's great news @Atinux 馃帄

@liqueflies I think I've found the issue - although, it's not a bug in vue-meta. It's to do with the way Vue handles VNodes in render functions - According to the docs, VNodes have to be unique.

In your example, the issue is remedied by making MyChildComponent a factory function that returns a new singleton, like so:

export default function MyChildComponent () {
  return {
    name: 'my-child-component',
    props: {
        page: VueTypes.string
    },
    metaInfo: {
        title() {
            return this.page;
        }
    }
  }
}

And then in your switch component (which I have renamed to view, since switch is a reserved word):

export function view (page) {
    return {
        name: `section-${page}`,
        render (h) {
            return h(MyChildComponent(), {
                props: { page }
            });
        }
    };
}

I have added an example of this pattern here: https://github.com/declandewet/vue-meta/blob/master/examples/vue-router/app.js

You can test it out by git clone-ing vue-meta and running npm run dev from the root directory - this will start the examples server, once it's started, navigate to localhost:8080 and click on "vue-router"

I've considered handling this automatically in vue-router, but it's beyond my needs for the moment. If anyone happens to figure this out, feel free to submit a PR.

As it turns out, this was being caused by the same logic that causes #10. I've implemented a crude fix in https://github.com/declandewet/vue-meta/commit/6ad56ec73e428316c2e4c115274ca655024c2810

The solution was to recursively shallow-merge all child component data along with their parent data into a new object, and compile the functions once all info has already been fetched (as opposed to my previous strategy of just overridding the bound context of each function each time it encountered a new component until it was time to call)

You should be able to use your original syntax now @liqueflies 馃帀

Was this page helpful?
0 / 5 - 0 ratings