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
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>
- Globale OBJ >>
Vue.prototype.OBJ
- Reactive OBJ >>
Vue.observable(OBJ)
- assuming that
getUser()
return an object >>Vue.prototype.user = Vue.observable( getUser() )
来源:https://stackoverflow.com/questions/48050762/vuejs2-update-vue-prototype-global-object