Skip to content

Commit 8924681

Browse files
authored
Feat: add validation (#142)
* feat(validation): Add validation * improve validation * improvement on validate and add example * fix validate example * improve validation, track dependencies on validate * convert the return to reactive, this will allow the render to not required `.value` at the end vuejs/core#738 * improve test coverage * WIP add validation docs * validation docs * added validation to readme and changelog * add warning to validation docs
1 parent ea48246 commit 8924681

File tree

18 files changed

+1136
-167
lines changed

18 files changed

+1136
-167
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1717
- [Chrome](https://pikax.me/vue-composable/composable/breakpoint/breakpointChrome) - reactive chrome breakpoints
1818
- [TailwindCSS](https://pikax.me/vue-composable/composable/breakpoint/breakpointTailwindCSS) - reactive TailwindCSS breakpoints
1919
- [format](https://pikax.me/vue-composable/composable/format/format) - Reactive string format
20+
- [Validation](https://pikax.me/vue-composable/composable/validation/validation) - model based validation inspired by [vuelidate](https://vuelidate.js.org/)
2021

2122
## 1.0.0-dev.9
2223

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<template>
2+
<div class="about">
3+
<h1>Form validation</h1>
4+
<form @submit="onSubmit">
5+
<input v-model="form.firstName.$value" placeholder="firstName" />
6+
<input v-model="form.lastName.$value" placeholder="lastName" />
7+
<input v-model="form.password.$value" placeholder="password" />
8+
<input v-model="form.samePassword.$value" placeholder="password2" />
9+
<p v-if="form.samePassword.$dirty && form.samePassword.match.$invalid">
10+
{{ form.samePassword.match.$message }}
11+
</p>
12+
13+
<br />
14+
<input
15+
type="submit"
16+
v-model="submitText"
17+
:class="{
18+
invalid: form.$anyDirty && form.$anyInvalid,
19+
dirty: form.$anyDirty && !form.$anyInvalid,
20+
error: form.$errors.length > 0
21+
}"
22+
/>
23+
</form>
24+
</div>
25+
</template>
26+
27+
<script>
28+
import { createComponent, ref, reactive, computed } from "@vue/composition-api";
29+
import { useValidation } from "vue-composable";
30+
31+
const required = x => !!x;
32+
33+
export default createComponent({
34+
setup() {
35+
const name = ref("");
36+
const surname = ref("");
37+
const password = ref("");
38+
39+
const form = useValidation({
40+
firstName: {
41+
$value: name,
42+
required
43+
},
44+
lastName: {
45+
$value: surname,
46+
required
47+
},
48+
password: {
49+
$value: password,
50+
required: {
51+
$validator: required,
52+
$message: ref("password is required")
53+
}
54+
},
55+
samePassword: {
56+
$value: ref(""),
57+
58+
match: {
59+
$validator(x) {
60+
return x === password.value;
61+
},
62+
$message: "Password don't match"
63+
}
64+
}
65+
});
66+
67+
const submitText = computed(() => {
68+
if (form.$anyDirty && form.$anyInvalid) {
69+
return "Invalid form";
70+
}
71+
if (!form.$anyDirty) {
72+
return "Please populate the form";
73+
}
74+
if (form.$errors.length > 0) {
75+
console.log(form.$errors);
76+
return "Error";
77+
}
78+
79+
return "Submit";
80+
});
81+
82+
const onSubmit = e => {
83+
e.preventDefault();
84+
if (form.$anyInvalid) {
85+
alert("invalid form");
86+
} else {
87+
alert("submit form");
88+
}
89+
};
90+
91+
return {
92+
onSubmit,
93+
submitText,
94+
form
95+
};
96+
}
97+
});
98+
</script>
99+
100+
<style scoped>
101+
.invalid {
102+
color: #aa2233;
103+
background: grey;
104+
}
105+
106+
.dirty {
107+
color: yellow;
108+
background: grey;
109+
}
110+
111+
.error {
112+
color: red;
113+
background: grey;
114+
}
115+
</style>

docs/.vuepress/config.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,12 @@ module.exports = {
169169
["composable/web/geolocation", "Geolocation API"]
170170
]
171171
},
172+
{
173+
title: "Validation",
174+
sidebarDepth: 1,
175+
collapsable: false,
176+
children: [["composable/validation/validation", "Validation"]]
177+
},
172178
{
173179
title: "External",
174180
sidebarDepth: 1,

docs/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ Check out the [examples folder](examples) or start hacking on [codesandbox](http
103103
- [BroadcastChannel](composable/web/broadcastChannel) - reactive `BroadcastChannel API`
104104
- [Geolocation](composable/web/geolocation) - reactive `Geolocation API`
105105

106+
### Validation
107+
108+
- [Validation](composable/validation/validation) - model based validation inspired by [vuelidate](https://vuelidate.js.org/)
109+
106110
### External
107111

108112
> New packages needed

0 commit comments

Comments
 (0)