持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第10天,点击查看活动详情
前言
结合前面的教程Vue 3.0教程(for beginner):Vue Cli(上篇),基于vue-cli创建一个web-form项目应用
删掉其中无用的组件和内容,将App.vue组件内容替换为:
<template>
<SignupForm></SignupForm>
</template>
<script>
import SignupForm from './components/SignupForm.vue'
export default {
name: 'App',
components: { SignupForm },
}
</script>
SignupForm则是我们要创建的表单组件。在components目录新建SignupForm.vue文件,填充内容为:
<template>
<form>
<label>邮箱:</label>
<input type="email" required />
</form>
</template>
<script>
export default {
name: 'SignupForm',
}
</script>
结合一些自定义的css样式,我们看到如下效果:
接着,我们开始书写表单组件内的逻辑。
两种数据绑定的方式
- 使用
v-model获取用户输入的表单值:
<template>
<form>
<label>邮箱:</label>
<input type="email" required v-model="email" />
<label>密码:</label>
<input type="password" required v-model="password" />
</form>
<p>邮箱: {{ email }}</p>
<p>密码: {{ password }}</p>
</template>
<script>
export default {
name: 'SignupForm',
data() {
return {
email: '',
password: '',
}
},
}
</script>
这里另外新增了一个密码输入框,同时分别用两个变量email和password保存输入的值,并在最后输出的页面。
通过v-model指令,将输入框的值与eamil等变量进行绑定,程序可以正确获取到输入值并显示(到其他地方),这其实就是vue的数据双向绑定。
我们也可以给邮箱设置一个默认值:
<template>
<form>
<label>邮箱:</label>
<input type="email" required v-model="email" />
<label>密码:</label>
<input type="password" required v-model="password" />
<label>角色:</label>
<select v-model="role">
<option value="开发">开发</option>
<option value="产品">产品</option>
</select>
</form>
<p>邮箱: {{ email }}</p>
<p>密码: {{ password }}</p>
<p>角色: {{ role }}</p>
</template>
<script>
export default {
name: 'SignupForm',
data() {
return {
email: '',
password: '',
role: '开发',
}
},
}
</script>
这里增加了一个select选择框并绑定了role变量,同时给它设置了初始值。
Checkbox
前面展示了input和select组件的用法,接着我们继续看checkbox的使用:
<template>
<form>
// ...省略
<div class="terms">
<input type="checkbox" v-model="terms" required />
<label>同意条款</label>
</div>
</form>
// ...省略
<p>条款: {{ terms }}</p>
</template>
<script>
export default {
name: 'SignupForm',
data() {
return {
email: '',
password: '',
role: '开发',
terms: false,
}
},
}
</script>
上面展示的是单个checkbox的情形,如果有多个复选框支持多选,要如何做呢?
<template>
<form>
// ...
<div class="terms">
<input type="checkbox" v-model="terms" required />
<label>同意条款</label>
</div>
<div>
<input type="checkbox" value="javascript" v-model="langs" />
<label>javascript</label>
</div>
<div>
<input type="checkbox" value="css" v-model="langs" />
<label>css</label>
</div>
<div>
<input type="checkbox" value="html" v-model="langs" />
<label>html</label>
</div>
</form>
// ...
<p>语言: {{ langs }}</p>
</template>
<script>
export default {
name: 'SignupForm',
data() {
return {
email: '',
password: '',
role: '开发',
terms: false,
langs: [],
}
},
}
</script>
我们使用一个数组变量langs与v-model进行绑定,vue程序会自动帮我们把选中的值push进数组中,及其方便。
键盘事件
为演示键盘事件的绑定,这里新增了一个技能项,绑定了键盘按键弹起事件keyup,并在addSkill里面处按键事件的逻辑,仅当用户按下Enter键时才处理用户输入的内容,收集并打印出来:
<template>
<form>
// ...
<label>技能:</label>
<input type="text" v-model="skill" @keyup="addSkill" />
<div class="skills">
<span v-for="item in skills" :key="item">{{ item }}</span>
</div>
<div class="terms">
<input type="checkbox" v-model="terms" required />
<label>同意条款</label>
</div>
</form>
// ...
</template>
<script>
export default {
name: 'SignupForm',
data() {
return {
// ...
skill: '',
skills: [],
}
},
methods: {
addSkill(e) {
if (e.key === 'Enter' && this.skill) {
this.skills.push(this.skill)
this.skill = ''
}
},
},
}
</script>
在addSkill事件中,我们通过e.key === 'Enter'过滤了键盘事件,但在vue的鼠标事件中,它支持事件修饰符,通过绑定enter事件修饰符,能够达到同样的目的效果:
<input type="text" v-model="skill" @keyup.enter="addSkill" />
小挑战:删除技能项
我们给每个技能项绑定一个点击事件,在点击的时候删除该技能:
<div class="skills">
<span v-for="item in skills" :key="item" @click="deleteSkill(item)">{{
item
}}</span>
</div>
处理事件deleteSkill:
<script>
export default {
name: 'SignupForm',
// ...
methods: {
// ...
deleteSkill(skill) {
this.skills = this.skills.filter((v) => {
return skill !== v
})
},
},
}
</script>
表单提交
最后,我们需要提交创建的表单,form支持@submit事件去提交表单:
<template>
<form @submit.prevent="handleSubmit">
<label>邮箱:</label>
<input type="email" required v-model="email" />
<label>密码:</label>
<input type="password" required v-model="password" />
<div class="error" v-if="passwordError">{{ passwordError }}</div>
// ...
<div class="submit">
<button>创建账户</button>
</div>
</form>
// ...
</template>
<script>
export default {
name: 'SignupForm',
data() {
return {
// ...
passwordError: '',
}
},
methods: {
// ...
handleSubmit() {
// 校验密码
this.passwordError = this.password.length > 5 ? '' : '密码至少6位'
if (!this.passwordError) {
alert('提交成功!')
}
},
},
}
</script>
在提交表单事件中,我们增加了一个prevent事件修饰符,它表示阻止表单的默认行为,这样我们才能在handleSubmit方法中处理表单提交的行为,否则表单会刷新提交,无法进入handleSubmit的事件处理程序中。