*首先在开始之前,需要先了解下v-modle双向绑定的原理,v-modle的本质是语法糖,主要做了两件事:
- 给元素绑定 value 属性
- 给表单元素绑定 input 事件, 在事件处理函数中修改绑定的数据
<input :value="count" @input="val => message = val" />
v-modle使得表单元素的数据总是来源于 Vue 实例中,当输入事件 input 或 change 发生时实时更新 Vue 实例中的数据。
但是在 Vuex 中存储的数据如果直接在表单元素中通过绑定$store.state.obj.message来直接改变 Vuex 中存储的信息则会导致后续调试无法通过 dev-tool 监视数据改变,对于数据流向不便理解,且Vue官方文档中明确说明在严格模式下,由于这个修改不是在 mutation 函数中执行的, 会直接抛出一个错误。
*对此,Vue官方也给出了两种解决方案:vuex.vuejs.org/zh/guide/fo…
- 第一种方法:直接 给
<input>中绑定 value,然后侦听input或者change事件,在事件回调中调用一个方法通过 commit 方法委派给 mutation 执行来修改 Vuex 中的数据。这种方法写起来比较繁琐,不太常用,相信大家都倾向于第二种解决方案。 - 第二种方法:使用带有 setter 的双向绑定计算属性,为了便于新手理解,这里通过一张数据流向图来解释下该方法的原理
- 可以很清晰的看到 input 通过计算属性的 get 方法获取 store 中数据展示到页面,再通过 set 将 input 元素的修改值传递到 vuex 的 mutation 中再对 state 中的数据重新赋值,这样就可以将数据的修改事件放到 Vuex 中监视,同时又不会损失
v-modle的特性
<!-- DOM -->
<input v-model="message">
// Vue实例中代码如下
computed: {
message: {
get () {
return this.$store.state.obj.message
},
set (value) {
this.$store.commit('updateMessage', value)
}
}
}
// Vuex.store实例中代码如下
state:{
obj: { message }
},
mutations: {
updateMessage (state, message) {
state.obj.message = message
}
}
- 这样就可以将表单元素与 Vuex 实例中存储的数据进行双向绑定来实现类似购物车中的功能了,最后希望大家在 vue 学习中技术更上一层楼,这里是前端小王同学,欢迎大家讨论前端学习中的问题,一起加油进步!