Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Output data from one Vue.js instance into another

I have a pretty big page with lots of stuff going on. So i have 2 Vue instances for 2 parts of the page. How can i bind data from one Vue instance into another?

This example should show what i am trying to do. (it's not working that way)

<div class="app1">...</div>
...
<div class="app2">{{app1.$data.msg}}</div>

var app1 = new Vue({
    el: '.app1',
    data: {msg: "test"}
});

var app2 = new Vue({
    el: '.app2'
});
like image 888
IanDess Avatar asked May 29 '15 22:05

IanDess


2 Answers

In advance, I know this isn't the question you are asking, but I don't know why you need two instances of Vue. Why not just bind Vue to the body and treat both the Vue instances as components. It might be difficult to do what you are trying to do, because it was not intended. Maybe it was, I don't know. I have set Vue up on the body and I haven't seen a performance hit. Here is a JSBin.

HTML

<div class="container">
    <div id="app1">
        <h1>{{ msg }}</h1>
        <input type="text" v-model="msg" class="form-control"/>

    </div>
    <div id="app2">
        <h1>{{ msg }}</h1>
        <input type="text" v-model="msg" class="form-control"/>
    </div>
</div>

JavaScript

var VueComponent1 = Vue.extend({
    template: '#app1',
    data: function(){
        return {
            msg: ""
        }
    }
});

var VueComponent2 = Vue.extend({
    template: '#app2',
    data: function(){
        return {
            msg: ""
        }
    }
});

var app1 = Vue.component('app1', VueComponent1);
var app2 = Vue.component('app2', VueComponent2);
var app = new Vue({
    el: 'body',
    data: { msg: 'Everybody loves Vue.' }
});

If you are looking for a better way to separate you code, you might want to check out this Vue with Browserify example.

Laracasts has a free series on Vue which has been pretty informative as well.

like image 195
whoacowboy Avatar answered Oct 09 '22 12:10

whoacowboy


I am still looking for the best solution. The following feels a bit hacky but it works.

You can use the watch option to listen for the change of an expression and trigger a function. In this function you can update the desired data of another Vue instance. In you example we would do this:

var app1 = new Vue({
  el: '.app1',
  data: {msg: 'test'},
  watch: {
    'msg': function() { app2.msg = this.msg; }
  }
});

var app2 = new Vue({
  el: '.app2',
  data: { msg: app1.$data.msg },
  watch: {
    'msg': function() { app1.msg = this.msg; }
  }
});

You can see this at work in this jsbin.

Moreover, I am wondering if you even need to do this. If this was a real-life-situation there could be better ways to handle this avoiding this hacky solution.

like image 37
DutGRIFF Avatar answered Oct 09 '22 13:10

DutGRIFF