A tiny change management library. Useful for validation and making sure that unchecked, unvalidated state does not leak / persist into your main data store.
Inspired by Ecto Changeset and ember-changeset.
As opposed to ember-changeset this has just a core tiny feature set and does not support a lot of features like rollbacks, snapshots and nested data handling.
- Vue 3 support
- Vue 2 + composition API support
- createChangeset
- useChangeset (createChangeset + cleanup on unmount)
- nested data handling
-
changeset.assign()
-
changeset.assignIfValid()
-
changeset.validate()
vue-changeset tries to not stand in the way and for simple usecases allows you just to pass validation function to rule them all:
import { defineComponent } from 'vue';
import { useChangeset } from 'vue-changeset';
export default defineComponent({
setup() {
const model = { firstName: 'John', lastName: 'Doe', };
const userChangeset = useChangeset(model, {
validate: (prop, value) => {
if (prop === 'firstName') {
return value.length > 2 || 'First Name must be at least 2 characters long';
}
if (prop === 'lastName') {
return value.length > 2 || 'Last Name must be at least 2 characters long';
}
}
});
return { useChangeset };
}
});
<form @submit.prevent="changeset.assignIfValid">
<label>First name</label>
<input :model="changeset.firstName">
<span v-if="changeset.changes.firstName.error"> {{ changeset.changes.firstName.error }} </span>
<button type="submit">Save</button>
</form>
If your validations needs are more advanced, you can use the createValidator function, maybe even together with a separate validation library. I'm using favalid in this example.
import { defineComponent } from 'vue';
import { useChangeset, createValidator } from 'vue-changeset';
//
import { tester, combine, minLength, regexp } from 'favalid';
export default defineComponent({
setup() {
const model = { firstName: 'John', lastName: 'Doe', };
const userChangeset = useChangeset(model, {
validate: createValidator({
firstName: (value) => value && value.length > 2,
lastName: combine(
minLength(3, () => 'too few letters'),
regexp(/^[a-zA-Z]+$/, () => 'invalid format', {}),
tester(() => {
// some other custom validation here
}, () => 'Invalid input'))
})
});
return { useChangeset, onSubmit };
}
});
createChangeset
accepts options as a second argument
// These are the defaults
const options = {
autoValidate: false,
validate: (prop, value) => true,
copy: obj => ({ ...obj }), // shallow copy
checkifDirty: ({ key, oldValue, newValue }) => oldValue !== newValue
};
const changeset = useChangeset(model, options);
autoValidate
will validate a prop on any change
validate
is a function that is used to validate all data (see examples above)
These functions can be passed to alter the behavior of vue-changeset:
copy
is used to create a copy of the object, it's a shallow copy by default. You can use deep copy via JSON.stringify()
and JSON.parse()
or use a library like fast-copy if you need.
checkIfDirty
is used to handle the isDirty
flags and is very naive by default, you can pass your own implementation that suits your needs
WIP