1
0
mirror of synced 2024-11-22 05:16:05 +03:00

Fixes an insideous bug that was causing vuex mutations in deeply linked prop data

This commit is contained in:
Justin Schroeder 2018-02-02 12:07:51 -05:00
parent b061bda3a2
commit 8efe308f98
8 changed files with 158 additions and 15 deletions

View File

@ -57,14 +57,20 @@ root store:
**Root Store**
```js
import {formulateState, formulateGetters, formulateMutation} from 'vue-formulate'
import Vue from 'vue'
import Vuex from 'vuex'
import {formulateState, formulateGetters, formulateMutations} from 'vue-formulate'
Vue.use(Vuex)
const state = () => ({
// your own state data can live next to vue-formulate's data
your: 'data',
...formulateState()
})
const getters = {
// Your own getters can live next to vue-formulate's getters
yourGetter (state) {
return state.your
},
@ -72,17 +78,18 @@ const getters = {
}
const mutations = {
// Your own mutations can live next to vue-formulate's mutations
setYour (state, payload) {
state.your = payload
},
...formulateMutations()
}
export default {
export default new Vuex.Store({
state,
getters,
mutations
}
})
```
### Usage

44
dist/index.js vendored

File diff suppressed because one or more lines are too long

88
package-lock.json generated
View File

@ -1943,6 +1943,32 @@
"wordwrap": "0.0.2"
}
},
"clone-deep": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-3.0.1.tgz",
"integrity": "sha512-kWn5hGUnIA4algk62xJIp9jxQZ8DxSPg9ktkkK1WxRGhU/0GKZBekYJHXAXaZKMpxoq/7R4eygeIl9Cf7si+bA==",
"requires": {
"for-own": "1.0.0",
"is-plain-object": "2.0.4",
"kind-of": "6.0.2",
"shallow-clone": "2.0.2"
},
"dependencies": {
"for-own": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
"integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
"requires": {
"for-in": "1.0.2"
}
},
"kind-of": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
}
}
},
"co": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
@ -3053,8 +3079,7 @@
"for-in": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
"integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
"dev": true
"integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA="
},
"for-own": {
"version": "0.1.5",
@ -4587,6 +4612,21 @@
"integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
"dev": true
},
"is-plain-object": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
"integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
"requires": {
"isobject": "3.0.1"
},
"dependencies": {
"isobject": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
}
}
},
"is-posix-bracket": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
@ -5163,6 +5203,25 @@
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
"dev": true
},
"mixin-object": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-3.0.0.tgz",
"integrity": "sha512-RsUqTd3DyF9+UPqhLzJIWwGm4ZGIPYOu6WcQhQuBqqVBGhc6LOC8LrFk9KD7PvVwmqri45IJT88WLrNNrMWjxg==",
"requires": {
"for-in": "1.0.2",
"is-extendable": "1.0.1"
},
"dependencies": {
"is-extendable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
"integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
"requires": {
"is-plain-object": "2.0.4"
}
}
}
},
"mkdirp": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
@ -6303,6 +6362,31 @@
"safe-buffer": "5.1.1"
}
},
"shallow-clone": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-2.0.2.tgz",
"integrity": "sha512-2o81AG/RpLTAG/ZXQekPtH/6yTffzKlJ+i6UhtVTtnP6zWQaNo9vt6LI28bhZLSesB12VQSfJYtXopTogVBveg==",
"requires": {
"is-extendable": "1.0.1",
"kind-of": "6.0.2",
"mixin-object": "3.0.0"
},
"dependencies": {
"is-extendable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
"integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
"requires": {
"is-plain-object": "2.0.4"
}
},
"kind-of": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
"integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA=="
}
}
},
"shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",

View File

@ -59,6 +59,7 @@
]
},
"dependencies": {
"clone-deep": "^3.0.1",
"shortid": "^2.2.8"
}
}

View File

@ -9,6 +9,7 @@
<script>
import {equals} from '../utils'
import cloneDeep from 'clone-deep'
export default {
props: {
@ -49,7 +50,7 @@ export default {
return this.$store.getters[`${this.m}hasErrors`][this.name] || false
},
values () {
return this.$store.getters[`${this.m}formValues`][this.name] || {}
return cloneDeep(this.$store.getters[`${this.m}formValues`][this.name] || {})
},
errors () {
return this.$store.getters[`${this.m}formErrors`][this.name] || {}
@ -79,9 +80,10 @@ export default {
methods: {
registerField (field, data) {
this.$store.commit(`${this.m}setFieldMeta`, {form: this.name, field, data})
this.updateFormValidation()
},
hydrate (values) {
for (let field of this.fields) {
for (let field in this.fields) {
if (field.type !== 'submit') {
this.$store.commit(`${this.m}setFieldValue`, {
field: field.name,

View File

@ -97,7 +97,7 @@
</template>
<script>
import {inputTypes, equals, reduce} from '../utils'
import {inputTypes, equals, reduce, filter} from '../utils'
import shortid from 'shortid'
export default {
@ -197,11 +197,10 @@ export default {
if (value === undefined) {
switch (this.type) {
case 'color':
value = '#000000'
break
return '#000000'
case 'checkbox':
if (this.optionList.length > 1) {
value = []
return []
}
break
}
@ -279,7 +278,10 @@ export default {
}
},
created () {
this.form.registerField(this.name, this.$props)
this.form.registerField(
this.name,
filter(this.$props, (prop, value) => ['name', 'type', 'id', 'label', 'validation'].includes(prop)),
)
if (this.initial !== false) {
this.form.hydrate({[this.name]: this.initial})
}

View File

@ -27,7 +27,10 @@ export const formulateGetters = (moduleName = '', getters = {}) => Object.assign
return state.validationErrors
},
formMeta (state) {
return map(state.meta, (form, fields) => Object.entries(fields).map(([key, value]) => value))
return reduce(state.meta, (forms, form, fields) => {
forms[form] = reduce(fields, (arr, field, data) => arr.concat(data), [])
return forms
}, {})
},
hasErrors (state) {
return map(state.errors, (form, errors) => {

View File

@ -1,3 +1,5 @@
import cloneDeep from 'clone-deep'
/**
* Compare the equality of two arrays.
* @param {Array} arr1
@ -20,7 +22,7 @@ export function equals (arr1, arr2) {
* @param {Function} callback
*/
export function map (original, callback) {
let obj = Object.assign({}, original)
let obj = cloneDeep(original)
for (let key in obj) {
obj[key] = callback(key, obj[key])
}