你好,我是Vue的初学者,遇到了一个困扰我的问题。我在想我们是否应该使用v-model指令来修改vuex store?Vuex表示我们只应通过mutations来修改vuex store,但是v-model使所有事情变得更加容易和简短。(我问这个问题是因为我找不到清晰的答案)
你好,我是Vue的初学者,遇到了一个困扰我的问题。我在想我们是否应该使用v-model指令来修改vuex store?Vuex表示我们只应通过mutations来修改vuex store,但是v-model使所有事情变得更加容易和简短。(我问这个问题是因为我找不到清晰的答案)
当在严格模式下使用Vuex时,对于属于Vuex的状态使用v-model
可能有些棘手。
处理这个问题的“Vuex方式”是绑定<input>
的值并在输入或更改事件上调用一个action。
一定要查看该页面上简单的“双向计算属性”示例:
https://vuex.vuejs.org/guide/forms.html
<input v-model="message">
computed: {
message: {
get () {
return this.$store.state.obj.message
},
set (value) {
this.$store.commit('updateMessage', value)
}
}
}
我认为另一个好的选择是使用vuex-map-fields,这个选项在任何答案中都没有提到。实际上,库的作者已经为该库的有用性写了一个非常好的解释。根据其GitHub页面,你可以像这样使用该库:
在你的Vuex Store中,你可以有类似于以下的代码段:
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存储库,其中显示了各种用例的其他示例。
<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">
。 - Kwesi Smart我的解决方案是使用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;
}
};
如果您使用此方法,请确保检查您想要的事件。
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。
重要的是从存储中深度复制对象,就像对数组使用映射一样,并且要像我在内部处理对象时那样进行。
此外,您还需要在存储中初始化此用户对象,并使用空字段。
在计算属性中使用getter和setter非常完美。但是在我的情况下,我有一个“重置”按钮,它应该恢复所有未保存的更改。我已经使用了watcher与mapState的组合:
<h5>Edit User</h5>
...
<q-input v-model="user_data.full_name" label="Full Name" />
<q-input v-model="user_data.email" type="email" label="Email" />
<q-checkbox v-model="user_data.is_active" label="Is Active" />
...
<q-btn label="Cancel" @click="cancel" />
<q-btn label="Reset" @click="reset" />
<q-btn label="Save" @click="save" />
</template>
<script>
import { mapActions, mapState } from "vuex";
export default {
data() {
return {
id: "",
user_data: {},
};
},
computed: {
...mapState(["user"]),
},
watch: {
user(value) {
this.user_data = { ...value }; // very important to copy object
},
},
mounted() {
this.id = parseInt(this.$route.params.id);
this.getUserById({ id: this.id });
},
methods: {
...mapActions(["saveUser", "getUserById"]),
save() {
this.saveUser(this.user_data);
this.$router.push({ name: "userList" });
},
reset() {
this.user_data = this.user;
},
cancel() {
this.reset();
this.$router.push({ name: "userList" });
},
},
};
</script>
是的,你可以这样做,但这不是最佳实践。
正如文档所说,为了保持对状态的控制,状态应该仅在mutation内部更新。
但如果你真的想这样做,可以使用以下方法:
v-model="$store.state.yourProperty"