Easy two-way binding between v-model and vuex state / mutations.
For example I want to bind the state of the global menu to a vuex state.
Meanwhile I use this manual workaround in my component:
computed: {
nav: {
get () { return this.$store.state.nav },
set (v) { this.$store.commit('SET_NAV', v) }
}
}
It would be helpful to have an easy function like mapGetters to do this.
I like the idea, just not sure if this is fit for inclusion in library or separate lib.
Here is an example, if it makes sense I can create PR and tests:
https://github.com/manico/vuex/commit/1663b0e11c443e1a22ca3200b9ae18332db62caa
Looking forward for this! Has this been discussed to see if it should be part of the library or not?
Here's a potential solution
https://github.com/maoberlehner/vuex-map-fields
Any feedbacks yet?
import { mapState } from 'vuex'
// based on article:
// VueJS - Two way data binding and state management with Vuex and strict mode
// https://ypereirareis.github.io/blog/2017/04/25/vuejs-two-way-data-binding-state-management-vuex-strict-mode/
import { mapState } from 'vuex'
export default function mapStatesTwoWay (namespace, states, updateCb) {
const mappedStates = mapState(namespace, states)
const res = {}
for (const key in mappedStates) {
res[key] = {
set (update) {
updateCb.call(this, { [key]: update })
},
get () {
return mappedStates[key].call(this)
}
}
}
return res
}
Sample usage:
computed: {
...mapStatesTwoWay('plan', {
name: state => state.current.name,
email: state => state.current.email,
phone: state => state.current.phone,
code: state => state.current.code
}, function (stateUpdate) {
// ex: value = { name: 'John' }
this.$store.commit('updateCurrent', value)
})
}
state: {
current: {
name: '',
email: '',
phone: '',
code: ''
}
}
mutations: {
updateCurrent(state, payload) {
Object.assing(state.current, payload)
}
}
Uses mapState under the hood for consistency and computed {set, get} to be compatible with v-model.
This works, but I expect an even leaner solution.
I made a simple library.
what about computed? why this question has no continuation?
i'm tryed analyse argument-cheapness, and drawed a conclusion that some one argument does not greatly affect performance, we can hope to progress?
You can try to disable strict, https://vuex.vuejs.org/en/strict.html
In strict mode, whenever Vuex state is mutated outside of mutation handlers, an error will be thrown.
if you are using nuxt: export const strict = false
To disable strict mode is brute force and dirty coding. State MUST NOT be changed by direct value change.
anything on this?
yet another solution for this issue, designed as standalone lib: https://github.com/yarsky-tgz/vuex-dot
i've patiently investigated libs, that are mentioned already at this topic, but was not satisfied with that solution's architecture quality, or simplicity of usage, and, in all cases, I was feeling a lack of flexibility.
Mine solution not only can be used in all usage cases of other mentioned solutions, but also It provides some own features, analogs for which i haven't met, like exposition or plain hook (dispatching actions - is just mine sugar for hook).
Using plain hook() you can inject commit, validation before commit, any other complex logic you want to be invoked on your properties change.
look usage examples, read tests, it's 100% covered, so tests exposes all features my tools have.
btw - it do not depends on vue or vuex even for testing, just only designed with vue on mind.
That's just getters-setters generator for nested structures with hook and expose abilities.
P.S. I have some more features on mind, which coming soon
This is now part of the official docs
https://vuex.vuejs.org/guide/forms.html#two-way-computed-property
Mine setters generation helper library updated:
https://github.com/yarsky-tgz/vuex-dot
now it have takeState() helper with vuex namespaces support (not native because `normalizeNamespace is not exported from helpers).
so now you can do it just such way (simplest way of usage)
```vue
````
https://github.com/yarsky-tgz/vuex-dot
updated again: now working with mutations too.
Documentation updated a lot.
significant update done to vuex-dot: added plugins support and vuex-dot-buffer plugin, which makes form handling even more flexible.
Added a possible implementation that extends mapState to accept an get/set arguments in a that mimics vue's existing get/set on computed properties. PR #1308
Hey all, just found this library adds some niceties to solving this pattern elegantly without breaking the flux pattern:
https://github.com/maoberlehner/vuex-map-fields
Even has support for multi-row fields (v-for). Working great for me thus far.
Guys, for the matter of solution, the cleaner/ simpler/ minimal is already documented as pointed out by https://github.com/vuejs/vuex/issues/1085#issuecomment-394684988.
Let's move with our lives and don't touch this zombie anymore. 馃槃
Guys, for the matter of solution, the cleaner/ simpler/ minimal is already documented as pointed out by #1085 (comment).
Let's move with our lives and don't touch this zombie anymore.
I dunno, I still think the getter/setter syntax is super verbose and you also need to still create the mutation. I'd something like what is being talked about above, and NOT to treat this as a zombie request!
I agree with @MarkGStacey . The getter/setter code is just boilerplate and the need to create a mutation for every single field is also tedious.
For a small example application the additional code matters not very much, but imagine a business application where it is not uncommon that an entity holds then fields an more. You have to write a lot of boilerplate code for a simple edit form.
@MarkGStacey @kleinph In the vuex 4.x roadmap it looks like they are planning on merging actions and mutations. It would be really nice (and a lot less code) to be able to bind directly to the state. I think this is possible if vuex used something like ES6 proxies behind the scenes to observe changes.
Any updates on this issue?
Maybe, my small library could be useful to reduce boilerplate code with 2 simple functions - genVuexModels (generates object with state/mutations/getter/action) and mapVuexModels (generates getter/setter).
We get this issue quite a lot, so maybe it would be something to consider. But it's how Vue works in general, and not sure if Vuex core should expose some kind of magic on this.
I think it would be great to have plugin for this feature though 馃憤
Most helpful comment
I dunno, I still think the getter/setter syntax is super verbose and you also need to still create the mutation. I'd something like what is being talked about above, and NOT to treat this as a zombie request!