Reputation: 11210
I have a super-simple test app with two components (an <h1>
and an <input>
) and a vuex data store. The <input.
is bound to the store data element pageTitle
with v-model
, and the <h1>
displays pageTitle
using double brackets. When I change the text in the input field, the value is changed in the store and all components (I can see that in the dev tools).
However, when I change the value in the store directly in the console (using store.state.pageTitle = 'something else'
, the <h1>
updates, but the value in the text field does not. However, on initial page load, the input is correctly populated using the data from the store. I guess it's not receiving updates from the store.
Why is my input field not receiving updates from the store and updating it's value?
const store = new Vuex.Store({
state: {
pageTitle: "My Vuex Thing"
},
mutations: {
pageTitle(state,title){
state.pageTitle = title;
}
}
});
const topsection = {
template: `<h1>{{ pageTitle }}</h1>`,
computed: {
pageTitle(){
return store.state.pageTitle;
}
}
};
const contentsection = {
template: `<div id="content">
Enter a page title: <input type="text" name="pageTitle" v-model="pageTitle">
</div>
`,
computed: {
pageTitle(){
return store.state.pageTitle;
}
},
watch: {
pageTitle(val){
store.commit('pageTitle',val);
},
}
};
var v = new Vue({
el: '#vue',
store,
components: {
topsection,
contentsection
}
});
<div id="vue">
<topsection></topsection>
<contentsection></contentsection>
</div><!-- #vue -->
Upvotes: 1
Views: 887
Reputation: 31352
You are using v-model="pageTitle"
where pageTitle
is a computed property. Computed properties are by default getter-only, but you trying to bind the value by using v-model
.
So what you need is a computed setter.
So your contentsection component should be like this:
const contentsection = {
template: `<div id="content">
Enter a page title: <input type="text" name="pageTitle" v-model="pageTitle">
</div>
`,
computed: {
pageTitle:{
get: function(){
return store.state.pageTitle;
},
set: function(newTitle){
store.commit('pageTitle',newTitle);
}
}
}
};
You do not need a watcher.
Here is the working jsFiddle
Upvotes: 1