控件的v-model到底该不该直接绑定vuex的state属性?

作者站长头像
站长
· 阅读数 10

刚开是学习和使用vuex的方式都是按照官方提供的使用方式:1、定义 state、getters、mutations

state: {
    abc: '',
},
getters: {
    getAbc(state) {
        return state.abc
    },
},
mutations: {
    updateAbc(state, val) {
        state.abc = val
    },
},

2、在vue页面中使用 store,通过如下步骤保持页面和 store 数据同步。

  • 定义一个 data 属性,用来绑定控件的 v-model;
  • 在created方法中,通过mapGetters给定义的 data 属性赋值;
  • 当控件修改v-model属性后,在该控件对应的事件里面通过 this.$store.commit('', val)修改该属性(同步store);
<template>
  <div>
    <div>{{getAbc}}</div>
    <el-input v-model="abc" @change="handleChagne"></el-input>
  </div>
</template>

<script>

import { mapGetters } from 'vuex'

export default {
  name: 'Home',
  computed: {
    ...mapGetters(['getAbc']),
  },
  created() {
    this.abc = this.getAbc
  },
  methods: {
    handleChagne(val) {
      this.$store.commit('updateAbc', val)
    },
  },
  data() {
    return {
      abc: '',
    }
  },
}
</script>

但是现在发现一个问题,页面中定义的所有关于abc属性的data属性,created中的赋值,methods中修改abc的代码都有点多余,这些代码没有任何业务逻辑,全部为了本地变量和store中的变量同步而服务,感觉很浪费;

后来我发现,如果把 state 的 abc 封装成一个对象,那么v-model就可以直接绑定一个getters属性了,从而代码得到了极大的简化,如下:

1、定义 store

  • 去掉了mutations中修改state变量的方法
state: {
    formModel: {
        abc: '',
    }
},
getters: {
    getFormModel(state) {
        return state.formModel
    }
},

2、在vue页面中使用 store

使用页面简化如下:

  • 去掉了data属性定义;
  • 去掉了created中为data属性赋值代码;
  • 去掉了控件在修改data属性后,同步store代码;
<template>
  <div>
    <div>{{getFormModel.abc}}</div>
    <el-input v-model="getFormModel.abc"></el-input>
  </div>
</template>

<script>

import { mapGetters } from 'vuex'

export default {
  name: 'Home',
  computed: {
    ...mapGetters(['getFormModel']),
  },
}
</script>

从上面定义 store 和 使用页面代码简化来看,这是非常可观的,尤其是当 store 变量非常复杂时,如此精简时非常有必要的。

那么大家对这种简化的使用方式有什么意见呢?或者说大家一般都怎么使用 store 呢?

回复
1个回答
avatar
test
2024-07-15

不应该,所有修改 vuex 当中 state 的值都应该通过 mutation 去修改,而不是直接操作 state。并且在开启严格模式之后,无论何时发生了状态变更且不是由 mutation 函数引起的,将会抛出错误。因为可能会由于浅拷贝的问题导致意想之外的修改,或者其他类似的问题。导致没有办法去追踪问题。比如说新的数据值你在 Vue DevTools 当中可能会查看不到改变后的新值。

如果是一些频繁需要修改但是并不需要时效性的属性,可以在最后通过 提交 按钮或者其他方式去统一把表单数据 commit 上去,而不是修改一个 input 输入框的值就去同步一次。也就是说在不需要实时同步的数据操作时,只是在 init 的时候获取一下 vuex 当中的数据,然后在完成所有操作之后去调用 action 或者 mutation 去修改 state 来让 store 中的数据更新。


当然如果你觉得真的是太麻烦了,我觉得你可以去了解一下 piniavuex 的对比,其实就会对这个内容有更深入的理解,对比 Vuex - Pinia是什么? | Pinia

回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容