1

I have create a global object in my main.js to access logged in user's data throughout the application between controllers

main.js

Vue.prototype.user = getUser() // assume a method to getUser data

Now the above .user object will be available in other components with this.user,

what I'm looking for is if I make change to this.user in any component, the changes reflects to other components too, this is not happening right now

I've two components, one to update data in this.user EditProfileComponent.vue

<input type="text" v-model="user.firstName" />
<input type="text" v-model="user.lastName" />

and other to show data UserCardComponent.vue

<h1>{{user.firstName}} {{user.lastName}}<h1>

on the submit of above form I'm saving data into database and getting it back at with getUser() on refresh,

What I'm expecting, when I make change to v-model in form it should show change directly into UserCardComponent.vue

2 Answers 2

9

When you set the value of Vue.prototype.user, Vue is not expecting that value to be bound to the DOM, so it won't be reactive. You maybe have seen global services set up this way (like Vue.prototype.$http or similar), but these objects are not being bound directly to the DOM.

The most straight-forward way to maintain a reactive globally-accessible object is to use Vuex.

You can create a store to contain the user object:

const store = new Vuex.Store({
  state: { user: getUser() }
})

And register the store by passing the store object to the root Vue instance:

new Vue({
  el: '#app',
  store
})

Then, in whichever components you need to access the user object, you can define a computed user property via the Vuex.mapState help function:

computed: Vuex.mapState(['user'])

Here's a simple example:

function getUser() {
  return {
    firstName: 'John',
    lastName: 'Doe'
  }
}

const store = new Vuex.Store({
  state: { user: getUser() },
})

Vue.component('user-card', {
  template: `<h1>{{user.firstName}} {{user.lastName}}</h1>`,
  computed: Vuex.mapState(['user'])
})

new Vue({
  el: '#app',
  store,
  computed: Vuex.mapState(['user'])
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/3.0.1/vuex.min.js"></script>

<div id="app">
  <user-card></user-card>
  <input type="text" v-model="user.firstName" />
  <input type="text" v-model="user.lastName" />
</div>


If you don't want to have to add the Vuex library, (and you really don't mind each of your components having access to the user object) you could also use a mixin:

let user = getUser();
Vue.mixin({ 
  data() { 
    return { user }
  }
})

This way, all of your Vue instances will have access to a reactive user object pointing to the user object initially set in you main.js file.

Here's an example of that:

function getUser() {
  return {
    firstName: 'John',
    lastName: 'Doe'
  }
}

let user = getUser();
Vue.mixin({
  data() {
    return { user }
  }
})

Vue.component('user-card', {
  template: `<h1>{{user.firstName}} {{user.lastName}}</h1>`,
})

new Vue({
  el: '#app',
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>

<div id="app">
  <user-card></user-card>
  <input type="text" v-model="user.firstName" />
  <input type="text" v-model="user.lastName" />
</div>

Sign up to request clarification or add additional context in comments.

Comments

-1
  • Globale OBJ >> Vue.prototype.OBJ
  • Reactive OBJ >> Vue.observable(OBJ)
  • assuming that getUser() return an object >> Vue.prototype.user = Vue.observable( getUser() )

3 Comments

Can you clarify why you came to the conclusion that the solution was to wrap the getUser() call in Vue.observable()?
Please do not post only code as answer, but include an explanation what your code does, and how it solves the problem of the question. Answers with an explanation are usually of higher quality and more likely to attract upvotes.
for vue to make an object available for all components , wehave to make it globale, so we use vue.prototype for that purpose,to make it reactive to components changewe have to setit observable,

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.