dev-zuo 技术日常
Github

v-model 怎么优雅的绑定 Vuex 状态管理中的值,三种方法优缺点

这篇文章发布于 2021/05/04,归类于
标签:
v-model 绑定 vuex 中的值

在需要将 vuex 中的值,直接与表单 v-model 对应时,如果我们按照 vuex 强调的规范,只能通过 mutation 来改变 vuex state,那么会比较麻烦。假设我们脱离规范,关闭严格模式。那么 v-model 可以直接绑定 vuex state 值,会非常方便,但貌似又不合规范,不利于追踪。

那到底要怎么做合适呢?个人建议是:怎么方便怎么来,只要项目可控即可。下面来看看几种方法对比

1. 官方推荐:使用 computed 的 get 和 set

// <input v-model="message">
computed: {
  message: {
    get () {
      return this.$store.state.obj.message
    },
    set (value) {
      // 通过 updateMessage mutation 方法更改值
      this.$store.commit('updateMessage', value)
    }
  }
}

参考:表单处理 | Vuex

2. 非严格模式:直接将 state 设置到 v-model

关闭严格模式后,直接将 vuex state 当全局变量用,可以任意修改操作

const store = new Vuex.Store({
  // ...
  strict: false // 关闭严格模式,或者直接不写这个属性
  // strict: true // 开启严格模式 
})
<input v-model="obj.message">

3. 中间对象转换:watch 监听 state 改变,更新中间对象,v-model 中间对象

<template>
  <div>
    <div>{{ obj }}</div>
    <div>{{ objCopy }}</div>
    <el-form>
      <el-input v-model="objCopy.message" />
      <el-button @click="confirm">提交</el-button>
    </el-form>
  </div>
</template>

<script>
import { mapState } from "vuex";
export default {
  data() {
    return {
      objCopy: {
        message: ""
      }
    };
  },

  computed: {
    ...mapState(["obj"])
  },

  watch: {
    obj: {
      handler() {
        this.initData();
      },
      deep: true
    }
  },

  created() {
    this.initData();
  },

  methods: {
    initData() {
      Object.assign(this.objCopy, this.obj);
    },
    confirm() {
      this.$store.commit("updateObj", JSON.parse(JSON.stringify(this.objCopy)));
    }
  }
};
</script>