Closed thelinuxlich closed 8 years ago
Ha, I'd say this is pretty clever. The point is making sure all changes are explicitly recordable, and this does ensure every change to message
is recorded in a mutation.
Id say this is a good way to incorporate flux, as long as there is no direct manipulation, so that an action can control calls to multiple mutations. +1
If this is encouraged, I wonder if it can be made less verbose and perhaps even part of Vuex or Vue natively. I'm thinking of a brand new vuex property declaration:
vuex: {
message: {
dispatch: "CHANGE_MESSAGE",
// more configuration?
}
}
Again, probably a lot of thought needs to go in to this before it is actually incorporated. But I wanted to start the discussion. This also directly addresses a way to to work with v-model on writable computed properties.
This could also be a mixin or plugin opportunity which uses the configuration and creates the computed properties for you. Would love to hear thoughts.
@amanpatel imo this could be used in certain situations, but I would not put it into core. The point being that this makes it much less explicit about what is going on. It's fine if you build your own abstraction layer on top of Vuex to make this possible (e.g. a mixin), because it fits your mental model well. But I think Vuex itself should only provide the most explicit API.
@thelinuxlich For anyone else interested I had a slightly different requirement where there was lots of child data attributes.
@LinusBorg Helped point me in the right direction over here: https://forum.vuejs.org/topic/1546/vuex-state-mutation-error-on-data-stored-inside-component-data/4
<template>
<div>
<h2>Customer Needs Analysis</h2>
<input
:value="customerNeedsAnalysis.vehicleUsage"
v-on:input="update('vehicleUsage', $event)"
>
<textarea
:value="customerNeedsAnalysis.notes"
v-on:input="update('notes', $event)"
></textarea>
</div>
</template>
<script>
export default {
vuex: {
getters: {
customerNeedsAnalysis: state => state.quote.customerNeedsAnalysis
},
actions: {
update: ({ dispatch }, attribute, e) => {
dispatch('UPDATE_CUSTOMER_NEEDS_ANALYSIS', {[attribute]: e.target.value});
}
}
}
}
</script>
your solution is much better
@thelinuxlich Except for one small problem:
When I do this, it works well, but I've noticed an interesting artifact. If using the same model in more than one input, the mutation is called on all inputs when changing the input value in one. I could probably just check the value and abort if no change, but it would be nice to avoid calling the mutation on every input when a change is only made in one.
http://forum.vuejs.org/topic/2303/integrating-vuex-with-input-components-js-doesn-t-have-pointers/9
As a workaround for that extreme corner case, maybe you can use something like _.debounce ?
@leevigraham : Your solution only work with "native control" HTML, if we use plugin (example : Vuetify) it won't work correctly.
Example with number input component :value = ... => we send value from model to component v-on:input = ... => we get user input value and set to model but if user input characters (not number) the control won't display correct match with your model
How does this work with nested data or arrays? Unlike @leevigraham's example, I would like to be still able to use v-model
for all it's benefits and consistency.
P.S.: The use of two-way computed properties has been documented in the meantime.