Vuex 之如何使用 v-model 配合 state ?

栏目: JavaScript · 发布时间: 5年前

内容简介:Vue 2.5.17Vuex 3.0.1

v-model 最好用的就是配合 data 達成 Two-way Binding,但若使用 Vuex 之後,是否還能使用 v-model 搭配 state 繼續 Two-way Binding 呢 ?

Version

Vue 2.5.17

Vuex 3.0.1

V-model vs. Data

HelloWorld.vue

<template>
  <div>
    <div>
      <input type="text" v-model="name">
    </div>
    <div>
      {{ name }}
    </div>
  </div>
</template>

<script>
/** data */    
const data = function() {
  return {
    name: '',
  };
};

export default {
  name: 'HelloWorld',
  data,
};
</script>

Vue 的 v-model 標準寫法,直接將 <input> 綁定到 name data。

Value vs. Input

但若將 name data 提升到 Vuex 的 name state 之後,就沒這麼簡單了。

Vuex 強調的是 Unidirection Dataflow, state 只能被讀取,要寫入 state 必須靠 mutation ,因此 v-model 無法直接寫入 state

v-model 本質是 value property binding 與 input event 的 syntatic sugar,因此可以回歸基本動作,使用 valueinput 實現。

HelloWorld.vue

<template>
  <div>
    <div>
      <input type="text" :value="name" @input="onInputName">
    </div>
    <div>
      {{ name }}
    </div>
  </div>
</template>

<script>
import { mapState } from 'vuex';

/** computed */
const computed = mapState(['name']);

/** methods */
const onInputName = function(e) {
  this.$store.commit('setName', e.target.value);
};

const methods = {
  onInputName,
};

export default {
  name: 'HelloWorld',
  computed,
  methods,
};
</script>

第 4 行

<input type="text" :value="name" @input="onInputName">

name 綁定到 value ,將 onInputName() 綁定到 input event。

16 行

const computed = mapState(['name']);

name state 建立 name computed。

19 行

const onInputName = function(e) {
  this.$store.commit('setName', e.target.value);
};

定義 onInputName() ,負責接收 input event,呼叫 setName mutations 修改 name state。

store.js

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

/** state */
const state = {
  name: '',
};

/** mutations */
const setName = (state, payload) => state.name = payload;

const mutations = {
  setName,
};

export default new Vuex.Store({
  strict: true,
  state,
  mutations,
});

很標準的 Vuex 寫法,由 setName mutation 負責修改 name state。

這種寫法雖然可行,但似乎喪失了原本 v-model 的特色,又必須走回頭路使用 event

V-model vs. Computed with Setter

HelloWorld.vue

<template>
  <div>
    <div>
      <input type="text" v-model="name">
    </div>
    <div>
      {{ name }}
    </div>
  </div>
</template>

<script>
/** computed */
const name = {
  get() {
    return this.$store.state.name;
  },
  set(value) {
    this.$store.commit('setName', value);
  },
};

const computed = {
  name,
};

export default {
  name: 'HelloWorld',
  computed,
};
</script>

第 4 行

<input type="text" v-model="name">

v-model 回來了,但綁定的是 name computed,而不是 name data。

14 行

const name = {
  get() {
    return this.$store.state.name;
  },
  set(value) {
    this.$store.commit('setName', value);
  },
}

建立 name computed,為了讓 v-model 能運作,特別將 name computed 加上 setter。

  • get() :負責從 name state 抓資料
  • set() :負責呼叫 setName mutation 寫入 state

透過有 setter 的 computed,我們就能繼續使用 v-model 了。

Conclusion

  • 雖然使用 value vs. input 寫法也行,但 v-model vs. computed with setter 寫法更優雅,實務上建議用此

Sample Code

完整的範例可以在我的 GitHub 上找到

Reference

Vuex , Form Handling


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Web Security Testing Cookbook

Web Security Testing Cookbook

Paco Hope、Ben Walther / O'Reilly Media / 2008-10-24 / USD 39.99

Among the tests you perform on web applications, security testing is perhaps the most important, yet it's often the most neglected. The recipes in the Web Security Testing Cookbook demonstrate how dev......一起来看看 《Web Security Testing Cookbook》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具