我们应该使用 v-model 来修改 Vuex 存储吗?
Posted
技术标签:
【中文标题】我们应该使用 v-model 来修改 Vuex 存储吗?【英文标题】:Should we use v-model to modify Vuex store? 【发布时间】:2019-07-22 12:16:14 【问题描述】:您好,我是 Vue 的初学者,我确实遇到了一个困扰我的问题。 我想知道我们应该使用 v-model 指令来修改 vuex 商店吗? Vuex 说我们应该只通过突变来修改 vuex 存储,但是 v-model 使一切变得更容易和更短。(我问是因为我找不到明确的答案)
【问题讨论】:
【参考方案1】:https://vuex.vuejs.org/guide/forms.html
在严格模式下使用 Vuex 时,在属于 Vuex 的状态上使用
v-model
可能有点棘手。处理它的“Vuex 方式”是绑定
<input>
的值并在输入或更改事件上调用操作。
请务必查看该页面上的简单“双向计算属性”示例:
<input v-model="message"> computed: message: get () return this.$store.state.obj.message , set (value) this.$store.commit('updateMessage', value)
【讨论】:
这是否适用于消息中更复杂的数据? 感谢您的解决方案。我将其修改为使用 dispatch("SomeAction") 而不是提交。因为使用动作是推荐的方式。【参考方案2】:我认为这里的任何答案中都没有提到的另一个好选择是使用vuex-map-fields。事实上,图书馆作者有written a very nice explanation 为图书馆的用处。根据其 GitHub 页面,要使用该库,您可以执行以下操作:
在你的 Vuex Store 中,你可以有一个类似这样的 sn-p:
import Vue from 'vue';
import Vuex from 'vuex';
import getField, updateField from 'vuex-map-fields';
Vue.use(Vuex);
export default new Vuex.Store(
// ...
modules:
fooModule:
namespaced: true,
state:
foo: '',
,
getters:
getField,
,
mutations:
updateField,
,
,
,
);
在你的组件代码中,你可以有类似这样的东西:
<template>
<div id="app">
<input v-model="foo">
</div>
</template>
<script>
import mapFields from 'vuex-map-fields';
export default
computed:
// `fooModule` is the name of the Vuex module.
...mapFields('fooModule', ['foo']),
,
;
</script>
我在这个答案的第一句话中链接到的库的 GitHub 存储库中显示了各种用例的其他示例。
【讨论】:
【参考方案3】:上述解决方案也可以通过突变实现:
<template>
<input v-model="message">
</template>
<script>
import mapMutations, mapState from 'vuex';
export default
computed:
...mapState(messageFromStore: 'message'),
message:
get()
return this.messageFromStore;
,
set(value)
this.updateMessage(value);
,
methods:
...mapMutations('updateMessage')
;
</script>
【讨论】:
我猜你的意思是<input v-model="tab">
在第 2 行【参考方案4】:
对此我的解决方案是使用 getter 设置 value
和 @input
来调用突变。
<input
type="text"
:value="$store.getters.apartmentStreet"
@input="value => $store.commit('apartmentValue', handle: 'street', value )"
>
getters.js:
export default
apartmentStreet: state => state.apartment.street,
;
mutations.js
export default
apartmentValue(state, payload)
let oldValue = state.apartment[payload.handle];
let newValue = payload.value;
if (newValue !== oldValue) state.apartment[payload.handle] = payload.value;
;
如果您使用此方法,请务必检查您想要的事件。
【讨论】:
【参考方案5】:我使用这个解决方案。
data()
return
formData:
username: '',
email: '',
bio:
firstName: '',
lastName: ''
,
games: ['civ4', 'caesar3', 'homeworld', 'cataclysm'],
,
computed:
...mapGetters( //or mapState
user: 'users'
)
,
watch:
user(newValue)
this.formData.username = newValue.name;
this.formData.email = newValue.email;
this.formData.bio.firstName = newValue.bio.firstName;
this.formData.bio.lastName = newValue.bio.lastName;
this.formData.games = newValue.games.map(x=> return x );
,
beforeCreate: fucntion()
this.$store.dispatch('getUser');
然后你就经常使用 v-model。 从存储中制作对象的深层副本很重要,例如使用数组的映射,以及我如何在里面处理对象。
而且,您还需要在商店中启动此用户对象,并使用空字段。
【讨论】:
【参考方案6】:可以,但不是最佳做法。
正如文档所说,状态应该只在突变内部更新以保持对状态的控制。
但如果你真的想这样做,你可以这样做:
v-model="$store.state.yourProperty"
【讨论】:
是的,但是为什么我们不应该使用 v-model (因为我们应该只通过突变来修改 vuex 存储)但是 v-model 正在做什么不建议通过 v- 来修改 vuex 存储模型指令? > : vuejs.org/v2/guide/state-management.html @TristanDeoliveira 如果有人不关心“高级调试助手”,因为他正在构建一个简单的应用程序怎么办? v-modeling store 会直接导致其他问题吗?当我开始学习 Vue 时,我确实使用 v-models 直接链接存储(我使用了 getter,但不是状态对象),我不记得有任何问题。对于小型应用程序来说,最佳实践不是矫枉过正吗? @Eggon 同意,vuex 应该在幕后处理这个问题......以上是关于我们应该使用 v-model 来修改 Vuex 存储吗?的主要内容,如果未能解决你的问题,请参考以下文章
VueJS v3、Vuex 和 Composition API 以及输入字段上的 v-model
切换 Vuetify 导航抽屉 v-modeled 到 Vuex 变量