基本示例:
<from id="app" @submit="checkForm" action="https://##" method="post">
<p v-if="errors.length">
<b>Please correct the following error(s):</b>
<ul>
<li v-for="error in errors">
{{error}}
</li>
</ul>
</p>
<p>
<label for="name">Name</label>
<input
id="name"
v-model="name"
type="text"
name="name">
</p>
<p>
<input type="submit" value="提交" />
</p>
</form>
<script>
const app=new Vue({
el:"#app",
data:{
errors:[],
name:null.
age:null,
movie:null
},
methods:{
checkForms:function(e){
if(this.name && this.age){ return true;}
this.errors = [];
if (!this.name) {
this.errors.push('Name required.');
}
if (!this.age) {
this.errors.push('Age required.');
}
e.preventDefault();
},
},
});
</script>
另一个自定义校验的例子:
<form
id="app"
@submit="checkForm"
action="https://vuejs.org/"
method="post"
novalidate="true"
>
<p v-if="errors.length">
<b>Please correct the following error(s):</b>
<ul>
<li v-for="error in errors">{{ error }}</li>
</ul>
</p>
<p>
Given a budget of 100 dollars, indicate how much
you would spend on the following features for the
next generation Star Destroyer. Your total must sum up to 100.
</p>
<p>
<input
v-model.number="weapons"
type="number"
name="weapons"
> Weapons <br/>
<input
v-model.number="shields"
type="number"
name="shields"
> Shields <br/>
<input
v-model.number="coffee"
type="number"
name="coffee"
> Coffee <br/>
<input
v-model.number="ac"
type="number"
name="ac"
> Air Conditioning <br/>
<input
v-model.number="mousedroids"
type="number"
name="mousedroids"
> Mouse Droids <br/>
</p>
<p>
Current Total: {{total}}
</p>
<p>
<input
type="submit"
value="Submit"
>
</p>
</form>
注意顶端的 novalidate="true"。但是这很重要,因为浏览器会尝试在 type="email" 的字段校验邮件地址。坦白说在这个案例中浏览器的校验规则是值得信任的,不过我们想要创建一个自定义校验的例子,所以把它禁用了。
这组输入框覆盖了五个不同的部件。注意这里为 v-model attribute 添加了 .number。它会告诉 Vue 将其值作为数字来使用。
const app = new Vue({
el: '#app',
data:{
errors: [],
weapons: 0,
shields: 0,
coffee: 0,
ac: 0,
mousedroids: 0
},
computed: {
total: function () {
// 必须解析,因为 Vue 会将空值转换为字符串
return Number(this.weapons) +
Number(this.shields) +
Number(this.coffee) +
Number(this.ac+this.mousedroids);
}
},
methods:{
checkForm: function (e) {
this.errors = [];
if (this.total != 100) {
this.errors.push('Total must be 100!');
}
if (!this.errors.length) {
return true;
}
e.preventDefault();
}
}
})
Ajax发送:
const apiUrl = 'https://vuecookbook.netlify.com/.netlify/functions/product-name?name=';
const app = new Vue({
el: '#app',
data: {
errors: [],
name: ''
},
methods:{
checkForm: function (e) {
e.preventDefault();
this.errors = [];
if (this.name === '') {
this.errors.push('Product name is required.');
} else {
fetch(apiUrl + encodeURIComponent(this.name))
.then(async res => {
if (res.status === 204) {
alert('OK');
} else if (res.status === 400) {
let errorResponse = await res.json();
this.errors.push(errorResponse.error);
}
});
}
}
}
})