Vuejs2 update Vue.prototype global object

2019-06-01 17:51发布

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

1条回答
我只想做你的唯一
2楼-- · 2019-06-01 18:12

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>

查看更多
登录 后发表回答