Meteor-vue2-example-routing questions

I am struggling to understand the example of meteor-vue project found here: https://github.com/Akryum/meteor-vue2-example-routing

In particular the line

render: h => h(AppLayout),

in the client/main.js file:

// App layout
import AppLayout from '/imports/ui/AppLayout.vue';

// App start
Meteor.startup(() => {
  // Start the router
  const router = routerFactory.create();
  new Vue({
    router,
    render: h => h(AppLayout),
  }).$mount('app');
});

What is h here?
Is it a function?
Where is it defined and what does it do?
I am guessing that injects the AppLayout vue component inside the root App component being created though this new Vue call but I do not understand the syntax, even after reading the vue docs on render functions. Could anyone clarifies this?

Another question is whether this way to integrate vue with meteor by creating the root app vue component by JavaScript code inside the Meteor.startup object is the only way that works.

Wouldnā€™t it be possible to simply add an App.vue component in the template/imports/ui/ folder that would look something like:

<template name=ā€œappā€>
  <app-layout></app-layout>
</template>

<script>
  app = new Vue({
    el: 'app';
    router
    })
</script>

?
Or must the code creating the app root instance with the router injected in it must necessarily appear in a Meteor.startup call to link the Vue code to the Meteor code?

I found answer to the first question here: https://github.com/vuejs-templates/webpack-simple/issues/29
In short, this mysterious h is an alias for the createElement Vue function that creates a new node in the DOM. It apparently is an compulsory argument to the render lambda that the render option of a Vue instance is expected as value (why it needs to be passed as argument instead of just called inside the render lambda I still donā€™t get it)

So
h => h(AppLayout)
is just an abbrevation for
createElement => createElement(AppLayout)

Now if you want to stay at the highest possible level of abstraction and hence would like to avoid using render functions, you can substitute

new Vue({
    router,
    render: h => h(AppLayout),
  }).$mount('app');
});

by:

new Vue({
    router,
    el: 'app',
    template: ''<app/>",
    components: { AppLayout }
});

BUT, this will only work if you import the development versions of Vue and VueRouter that include the template compiler instead of the production versions that exclude it and thus require the use of a render function.

Hence your imports:

import Vue from 'vueā€™
import VueRouter from ā€˜vue-routerā€™

must be replaced by:

import Vue from '/node_modules/vue/dist/vue.common.jsā€™
import VueRouter from ā€˜/node_modules/vue-router/dist/vue-router.common.jsā€™
1 Like

Great you found the answer @Jacques and thank you for sharing it!

For the sake of completeness Iā€™ll link an article from Sarah Drasner about this: https://css-tricks.com/what-does-the-h-stand-for-in-vues-render-method/

She mentions the Vue Guide and particularly this section: https://vuejs.org/v2/guide/render-function.html#createElement-Arguments where it explains the createElement's arguments.

Also, maybe best to stick to using the versions that donā€™t ship the compiler along the rest of the code?