带有组件的 Vuex 仅以一种方式更新

Vuex with components only update one way

设置

我有一个超级简单的测试应用程序,包含两个组件(一个 <h1> 和一个 <input>)和一个 vuex 数据存储。 <input. 使用 v-model 绑定到存储数据元素 pageTitle<h1> 使用双括号显示 pageTitle。当我更改输入字段中的文本时,商店和所有组件中的值都会更改(我可以在开发工具中看到)。

问题

但是,当我直接在控制台中更改商店中的值时(使用 store.state.pageTitle = 'something else'<h1> 会更新,但文本字段中的值 不会 。但是,在初始页面加载时,输入是使用商店中的数据正确填充的。我猜它没有从商店接收更新。

问题

为什么我的输入字段没有从商店接收更新并更新它的值?


代码

Javascript

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
    }
});

HTML

<div id="vue">
    <topsection></topsection>
    <contentsection></contentsection>
</div><!-- #vue -->

您正在使用 v-model="pageTitle",其中 pageTitle 是计算得到的 属性。计算属性默认为 getter-only,但您尝试使用 v-model.

绑定该值

所以你需要的是 computed setter.

所以你的 contentsection 组件应该是这样的:

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);
            }
        }
    }
}; 

您不需要观察者。

这是工作jsFiddle