Passing props to root instances in 2.0

Hi posva,

Possibly - it didn’t appear to be the solution based on the API documentation, but perhaps you could provide a snippet to show how it would work in this situation?

Can’t you simply use the data as a window variable?

Figure it out yet?

The way I’ve worked around this so far is to turn the root (in your case #vue-app) into a component.

<div class="app-entrypoint">
    <vue-app passedthroughvar="...."></vue-app>

new Vue({ el: '.app-entrypoint', components: .... })

Hi @Cheddam

There is a tricky way and unofficial to do it, on the mounted hook and after the next tick, you can have access to:

And you want also to v-bind your prop to let Vue.js interprets it as JavaScript.

Here my example:

But this might change in future versions of Vue.js, so a good way to do it is like @simshaun said, by using a component for your root entry point (a functional component is enough):

Vue.component('app', {
  functional: true,
  props: ['passedthroughvar'],
  render: function (createElement, context) {
    // You have access to context.props.passedthroughvar here
    return createElement('div',, context.children);

I let you check the example updated for using a functional component:

I hope it solves your query :slight_smile:

Hi guys,

Thanks for your suggestions! I hadn’t considered Simshaun’s approach of simply putting the component in the HTML - this will suit my purposes! Atinux, I hadn’t seen functional components before; your example was very useful as well.

The final product:

Cheers for all your help - consider this case closed.

Just thought I’d throw my solution in. I think the idea of a component is an interesting way of doing this, but it honestly feels wrong to be. Components are reusable bits of code that can be replicated either on the same page via a v-for or on other pages.

So my solution is instead to leave it as a root instance and use the following code instead:


<div my-data="hey"></div>


new Vue({
    mounted: function () {
        this.myData = this.$el.attributes.myData.value;

I hope this helps anyone not wanting to use the component method!


Same issue for me, and I solved thanks to you guys. New to vue 2, I struggled to put together your clues, so here is a full code (using vue-cli webpack as starting point).


<!DOCTYPE html>
    <entry-component myprop="propValue"></entry-component>


import Vue from 'vue'
import App from './App'

new Vue({
  el: 'entry-component',
  render(h) {
    return h(App, {
      props: {
        myprop: this.$el.attributes.myprop.value


export default {
  props: ['myprop']

So ‘myprop’ from root component is available in App component


In case your app declares a template, than you need to detect the target element’s attributes before the app gets mounted, as once mounted, the attributes will be those of the template element.

So my working solution is:


<div id="my-target-element" data-var-name="var-value"></div>


new Vue({
    el: '#my-target-element',
    template: '<div>Just an example with {{varName}}</div>',
    data: {varName: null},
    beforeMount: function () {
        this.varName = this.$el.attributes['data-var-name'].value;

PS: I’ve used data-something attribute naming to be valid names even for older browsers.


Thanks, was looking for this for a long time! I’m trying to pass an integer, but when I use this code, it will become a string. When I change data-var-name to :data-var-name, nothing is passed at al. Any suggestions?

1 Like

This looks like the most elegant solution of the many provided. Thanks!

It surprises me that passing in props from markup generated by the server outside of Vue is such a non-standard thing if Vue is meant to be useful on existing sites and not as a SPA, and if we want to think of vue as components outside of itself. it would make sense to me that the attributes on any new Vue instance are automatically available as props.

I guess you could loop over this.$el.attributes yourself, but odd that it doesn’t come easy…


This method works perfectly. Thanks!

Building upon your answer, if you’re using Babel and have the object-rest-spread plugin (which will soon be supported as standard ES2018), you can use Spread to quickly init all data-* attributes as Vue props:


<div id="my-target-element"


    <div>Just an example with {{myProp}} and {{otherProp}}</div>
    export default {
        name: 'App',
        props: ['myProp', 'otherProp']


import App from './app.vue';

const root_element = document.getElementById('my-target-element');

const AppRoot = Vue.extend(App);
new AppRoot({
    el: root_element,
    propsData: { ...root_element.dataset }

That’s exactly what I thought!

I’ve worked with riot before digging into vue and in riot it’s much more comfortable: you just write custom attributes on the tag you’re mounting and they’re automatically available at opts within the tag/component.

Would be really great to have something similar in vue without the need to do all of it yourself. Otherwise it’s not fun to use vue when you only use it for specific parts of the page and don’t build a SPA.

The new Vue CLI has a webpack build option that builds your single file components as chunks and gives you an entry point that’ll just load each’s javascript asynchronously when it hits it in the DOM. So all you do is <my-component my-prop=“”> and it all kinda works.

It’s not supported in IE bc it’s webcomponenty, but there must be a way to do it in IE still and I think that’ll exist already or soon in the ecosystem

Hi @Hyzual,
I can’t get your example working. Can you please help me out?


The trick was to use Vue.extend() and make a new App(), instead of new Vue()

1 Like

This worked for me

new Vue({
render: h => h(App,
 { props:
  { myProp: "the data" }

So I also found a solution that is pretty easy to use, but I’m not sure if it violates some of vue’s rules since we will have the root component and template component bound to the same DOM element.

this is similar to @simshaun’s solution, but with the wrapper element being more hidden



<component id="component" prop-a ="Value A"></component>
let el = document.getElementById("component")
let component_instance = (new Vue({el: el, components: {component: component_options}})).$children[0];

This doesn’t seems to work anymore in a project made with vue-cli version 3. At least in my case.

The error was: Cannot get $el of undefined

I ended up doing this: (assuming jQuery is loaded in the window element, thought the code could easily be refactored for vanilla-js)

import Vue from "vue";
import EditarContratos from "./components/EditarContratos.vue";

Vue.config.productionTip = false;

new Vue({
  el: "#vue-app",
  render: h =>
    h(EditarContratos, {
      props: {
        idConcesionario: window.$("#vue-app").attr("id-concesionario")
1 Like

This worked for me as well, except I used raw Javascript i.e.,
idConcesionario: document.getElementById(“app”).getAttribute(“id-concesionario”)

VueJS team, there should be an easier way to do this for integration with Django/Rails/Jinja templates.