在 Vuex store 中处理表单
当我们在 Vue
应用程序中使用 v-model
进行双向数据绑定时,Vue
实例中的数据会与 v-model
输入字段同步。因此,当你在输入字段中键入任何内容时,数据会立即更新。然而,这会在 Vuex store
中产生一个问题,因为我们不能在 mutations
属性之外修改 store
的 state
(数据)。让我们看一个 Vuex store
中简单的双向数据绑定示例:
// vuex-non-sfc/handling-forms/v-model.html
<div id="demo">
<input v-model="user.message" />
<p>Message: {{ user.message }}</p>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuex@3.6.2/dist/vuex.js"></script>
<script type="text/javascript">
const store = new Vuex.Store({
strict: true,
state: {
user: {
message: ''
}
}
})
new Vue({
el: '#demo',
store: store,
computed: {
user () {
return this.$store.state.user
}
}
})
</script>
对于这个示例,当你在输入字段中键入消息时,你将在浏览器的调试工具中看到以下错误消息:
Error: [vuex] do not mutate vuex store state outside mutation handlers.
这是因为当你键入时,v-model
尝试直接修改 store
state 中的 message
,因此在严格模式下会导致错误。让我们在接下来的章节中看看我们有哪些选项可以解决这个问题。
使用 v-bind 和 v-on 指令
在大多数情况下,双向绑定并不总是合适的。在 Vuex
中,使用单向绑定和显式数据更新通过将 <input>
绑定到 value
属性和 change
事件上更有意义。你可以通过以下步骤轻松实现此操作:
-
就像你在前面的章节中学到的那样,在
mutations
属性中创建一个用于修改state
的方法:// vuex-sfc/form-handling/value-event/store/index.js import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ strict: true, state: { message: '' }, mutations: { updateMessage (state, message) { state.message = message } } })
-
将
<input>
元素绑定到value
属性,并将input
事件绑定到方法,如下所示:// vuex-sfc/form-handling/value-event/components/app.vue <template> <input v-bind:value="message" v-on:input="updateMessage" /> <p>Message: {{ message }}</p> </template> <script> import { mapState } from 'vuex' export default { computed: { ...mapState({ message: state => state.message }) }, methods: { updateMessage (e) { this.$store.commit('updateMessage', e.target.value) } } } </script>
在这个解决方案中,我们使用子组件中的 updateMessage
方法来提交 store
中的 mutation
方法 updateMessage
,并传递来自 input
事件的值。通过像这样只显式地提交 mutation
,我们没有违反 Vuex
中必须遵守的强制规则。因此,采用这种解决方案意味着你不能使用 v-model
来处理 Vuex store
的表单。然而,如果你使用 Vue
本身的计算属性的 getter
和 setter
,你仍然可以使用它。让我们在下一节中介绍这一点。
使用双向计算属性
我们可以借助以下步骤,使用 Vue
内置的带 setter
的双向计算属性来处理带有 v-model
的表单:
-
就像上一节一样,在
mutations
属性中创建一个用于修改state
的方法。 -
将
get
和set
方法应用于message
键,如下所示:
// vuex-sfc/form-handling/getter-setter/components/app.vue
<template>
<input v-model="message" />
<p>Message: {{ message }}</p>
</template>
<script>
export default {
computed: {
message: {
get () {
return this.$store.state.message
},
set (value) {
this.$store.commit('updateMessage', value)
}
}
}
}
</script>
然而,这可能适用于简单的计算属性。如果你有一个超过 10 个键的深层对象需要更新,你将需要 10 组双向计算属性(getter
和 setter
)。与基于事件的解决方案相比,代码最终会变得更加重复和冗长。
做得好!你已经成功掌握了 Vuex store
的基础和概念。你已经学习了如何在 Vue
应用程序中使用 store
。现在,是时候继续在 Nuxt
中应用 store
了。让我们在下一节中开始吧。
如果你想了解更多关于 Vuex
的信息,请访问 https://vuex.vuejs.org/ 。