我们应该使用 v-model 来修改 Vuex store 吗?
Should we use v-model to modify Vuex store?
您好,我是 Vue 的初学者,我确实遇到了一个困扰我的问题。
我想知道我们是否应该使用 v-model 指令来修改 vuex 存储? Vuex 说我们应该只通过突变来修改 vuex 存储,但是 v-model 使一切变得更容易和更短。(我问是因为我找不到明确的答案)
可以,但不是最佳做法。
正如文档所说,状态应该只在突变内部更新以保持对状态的控制。
但如果你真的想这样做,你可以:
v-model="$store.state.yourProperty"
https://vuex.vuejs.org/guide/forms.html
When using Vuex in strict mode, it could be a bit tricky to use v-model
on a piece of state that belongs to Vuex.
The "Vuex way" to deal with it is binding the <input>
's value and call an action on the input or change event.
请务必查看该页面上的简单“双向计算 属性”示例:
<input v-model="message">
computed: {
message: {
get () {
return this.$store.state.obj.message
},
set (value) {
this.$store.commit('updateMessage', value)
}
}
}
上述解决方案也可以通过突变实现:
<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>
我的解决方案是使用 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;
}
};
如果您使用此方法,请务必检查您想要的事件。
我认为这里的任何答案都没有提到的另一个不错的选择是使用 vuex-map-fields. In fact, the library author has written a very nice explanation 来提高库的实用性。根据其 GitHub 页面,要使用该库,您可以执行以下操作:
在你的 Vuex 商店中,你可以有一个类似这样的片段:
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 存储库中显示了各种用例的其他示例。
我使用这个解决方案。
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。
从存储中深度复制对象很重要,比如对数组使用 map,以及我如何处理内部对象。
而且,您还需要在存储中启动此用户对象,字段为空。
您好,我是 Vue 的初学者,我确实遇到了一个困扰我的问题。 我想知道我们是否应该使用 v-model 指令来修改 vuex 存储? Vuex 说我们应该只通过突变来修改 vuex 存储,但是 v-model 使一切变得更容易和更短。(我问是因为我找不到明确的答案)
可以,但不是最佳做法。
正如文档所说,状态应该只在突变内部更新以保持对状态的控制。
但如果你真的想这样做,你可以:
v-model="$store.state.yourProperty"
https://vuex.vuejs.org/guide/forms.html
When using Vuex in strict mode, it could be a bit tricky to use
v-model
on a piece of state that belongs to Vuex.The "Vuex way" to deal with it is binding the
<input>
's value and call an action on the input or change event.
请务必查看该页面上的简单“双向计算 属性”示例:
<input v-model="message"> computed: { message: { get () { return this.$store.state.obj.message }, set (value) { this.$store.commit('updateMessage', value) } } }
上述解决方案也可以通过突变实现:
<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>
我的解决方案是使用 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;
}
};
如果您使用此方法,请务必检查您想要的事件。
我认为这里的任何答案都没有提到的另一个不错的选择是使用 vuex-map-fields. In fact, the library author has written a very nice explanation 来提高库的实用性。根据其 GitHub 页面,要使用该库,您可以执行以下操作:
在你的 Vuex 商店中,你可以有一个类似这样的片段:
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 存储库中显示了各种用例的其他示例。
我使用这个解决方案。
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。 从存储中深度复制对象很重要,比如对数组使用 map,以及我如何处理内部对象。
而且,您还需要在存储中启动此用户对象,字段为空。