Advanced-Frontend/Daily-Interview-Question

第 47 题:双向绑定和 vuex 是否冲突

zeroone001 opened this issue · 9 comments

在严格模式下直接使用确实会有问题。
解决方案:

<input v-model="message" />
computed: {
    message: {
        set (value) {
            this.$store.dispatch('updateMessage', value);
        },
        get () {
            return this.$store.state.obj.message
        }
    }
}
mutations: {
    UPDATE_MESSAGE (state, v) {
        state.obj.message = v;
    }
}
actions: {
    update_message ({ commit }, v) {
        commit('UPDATE_MESSAGE', v);
    }
}

我怀疑我看的vuex文档跟别人看的不是同一个,今天又是流下没有技术的眼泪的一天

在严格模式中使用Vuex,当用户输入时,v-model会试图直接修改属性值,但这个修改不是在mutation中修改的,所以会抛出一个错误。当需要在组件中使用vuex中的state时,有2种解决方案:
1、在input中绑定value(vuex中的state),然后监听input的change或者input事件,在事件回调中调用mutation修改state的值
2、使用带有setter的双向绑定计算属性。见以下例子(来自官方文档):

<input v-model="message">
computed: { message: { get () { return this.$store.state.obj.message }, set (value) { this.$store.commit('updateMessage', value) } } }

@sisi529 不懂再严格模式中使用vuex这句话的意思

VueX规定了单向数据流,把把VueX的State放到v-model双向绑定报错,本来就是代码问题。和冲突么关系。而且VueX的双向绑定就是利用了new Vue实现的。为了单项数据流设置了Flag作为标记。不应该是VueX和双向绑定的冲突。是coder的问题。

个人认为:
该问题问的确实是 双向绑定和单向数据流的是否冲突
从名字上来看是冲突的
双向绑定是是 UI改变导致Model改变 Model的改变导致UI的render
单向数据流呢,是Model控制UI,而想改变数据请dispath...
但干的事情是一样的:
但我觉得立足点不一样,单向数据流是统一的state,目的是可追溯state的改变,最终绕这么大一圈还是在修改state,renderUI
而双向绑定更多的是组件内部

我觉这个问题是vuex设计规范的问题.
理论上双向绑定和 vuex是可以的,如果可以双向绑定就会绕过mutation函数去改变store,但是vuex的设计规范上肯定是不允许绕过mutation函数去改变store的,vuex也确实做了这样的处理,所以官方给你了一个种类双向绑定的方案去做....

winyh commented

这种 setter 的方法测试了下,好像不支持对象,只支持简单的字段。例如 v-model="message.age",不知道有人碰到过没?

<input v-model="message.age" />

computed: {
    message: {
        set (value) {
            this.$store.dispatch('updateMessage', value);
        },
        get () {
            return this.$store.state.obj.message
        }
    }
}