Daniel Morell
Daniel Morell

Reputation: 2586

How to initialize Vue-CLI app with data during created() hook?

I am working on updating a large lecacy system, and so I am constrained by what I can and cannot do.

I have a small multi-component Vue-CLI app that will replace multiple heavy jQuery forms. There are instances where there will be multiple instaces of the Vue app on the same page. I need to be able to pass data into each instance and push that data back out. Each instance needs to interact with it's own set of data.

I am currently mouting the app in my main.js file like this...

const mounts = document.querySelectorAll('.a-mount-spot');
for ( let i = 0; i < mounts.length; i++ ) {
    let mount = mounts[i];
    new Vue({
        render: h => h(App)
    }).$mount(mount);
}

App is a single file Vue component with several child components. I don't know how to make App aware of it's own mount during the created() hook. So I would like to pass in data when the component is created. How do I do that?

For example, a psudo code of the desired result might look like this...

main.js

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

const mounts = document.querySelectorAll('.a_mount_spot');
for ( let i = 0; i < mounts.length; i++ ) {
    let mount = mounts[i];
    new Vue({
        init_data: { // This does not actuall pass in data
            who_am_i: mount.dataset.myname
        },
        render: h => h(App)
    }).$mount(mount);
}

App.vue

<template>
    <div id="app">
        {{ who_am_i }}
    </div>
</template>

<script>
    export default {
        name: 'app',
        data: function () {
            return {
                who_am_i: ''
            }
        },
        created() {
            this.who_am_i = '' // Some how get the init_data passed in when created
        }
    }
</script>

<style>
</style>

A working method

If I wait in the component lifecycle until after it is mounted, I can do this...

<script>
    export default {
        name: 'app',
        data: function () {
            return {
                who_am_i: ''
            }
        },
        mounted() {
            this.who_am_i = this.$el.parentElement.dataset.myname
        }
    }
</script>

This method requires the HTML to look like this...

<div class="app-wrapper" data-myname="Betty">
    <div class="a-mount-spot">
</div>
<div class="app-wrapper" data-myname="Name 2">
    <div class="a-mount-spot">
</div>

This feels hacky. It also does not allow me access to who_am_i until after it is mounted. It would be nice to provide some initiall data on creation.

Upvotes: 0

Views: 804

Answers (1)

IVO GELOV
IVO GELOV

Reputation: 14269

Perhaps you can try with props:

const mounts = document.querySelectorAll('.a-mount-spot');
for ( let i = 0; i < mounts.length; i++ ) 
{
    let mount = mounts[i];
    new Vue({
        render: h => h(App,
        {
          props:
          {
            who_am_i: mount.parentElement.dataset.myname,
          }
        })
    }).$mount(mount);
}

Upvotes: 1

Related Questions