一、实验名称
使用Vuetify构建登录系统的UI并实现表单验证。
二、参考资料
《Vue 3官方网站:https://cn.vuejs.org》、《Vuetify界面设计框架:Release notes — Vuetify》
三、实验目的
1. 练习使用Vuetify组件设计界面。
2. 练习对表单数据进行验证。
四、实验内容
1. 用VS Code打开实验三创建的myweb项目文件夹。
2. 在VS Code中按下 【Ctrl+Shift+` 】组合键打开终端窗口,在窗口中输入:
pnpm add vuetify@^3.1.6 mosha-vue-toastify
该命令会在当前项目中安装Vuetify的3.1.6版本和一个显示短消息的插件Toastify。
Vuetify 是建立在Vue.js之上的完备的界面框架,Vuetify的最新版本是3版本,该版本支持Vue 3。Vuetify采用 Material设计规范,组件丰富,界面精美,易于使用。
Vuetify支持4种流行的图标字体,包括Google官方出品的图标库Material Icons,参见:Icon Fonts — Vuetify。
Material Icon图标库中的图标样式可以通过这个网站查看:Material Icons - Material UI,使用Material Icon图标库需要使用如下的命令进行安装:
pnpm add material-design-icons-iconfont -D
3. 打开项目的TS入口文件main.ts,修改该文件,添加对Vuetify的全局引用和对Toastify、Material Icon的样式文件的全局引用,修改后的main.ts的代码如下所示:
import { createApp } from 'vue'
import App from './App.vue'
import './assets/main.css'
import 'mosha-vue-toastify/dist/style.css'
import 'material-design-icons-iconfont/dist/material-design-icons.css'
// 全局引入Vuetify
import 'vuetify/styles'
import { createVuetify } from 'vuetify'
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'
import { aliases, md } from 'vuetify/iconsets/md'
const vuetify = createVuetify({
components,
directives,
icons: {
defaultSet: 'md',
aliases,
sets: {
md,
}
},
})
createApp(App).use(vuetify).mount('#app')
4. 删除asserts目录下main.css文件中的样式,把下列样式复制到main.css中:
body {
position: absolute;
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
background-color: #f0f0f0;
}
5. 删除UserLogin.vue中style元素中的样式定义,使用Vue的样式类(参见:Spacing — Vuetify)设置界面的样式。
6. 修改UserLogin.vue,使用Vuetify的v-card组件(参见:Card component — Vuetify)替换原来的div元素。
7. 修改表单定义,使用Vuetify的v-form组件(参见:Form component — Vuetify)替换原来的form元素,使用v-text-field组件替换原来的input元素,使用v-btn组件(参见:Button component — Vuetify)替换原来的button元素。修改后的UserLogin.vue的代码如下所示:
<script lang="ts" setup>
import {onMounted, ref, getCurrentInstance} from 'vue';
import {login} from '@/api/user'
import {createToast} from "mosha-vue-toastify";
const username = ref('')
const password = ref('')
const handleLogin = async () => {
if (username.value == '' || password.value == '') {
createToast('用户名或密码不能为空!', {position: 'top-center', showIcon: true})
} else {
try {
const res = await login({username: username.value, password: password.value})
createToast(res.data.msg, {position: 'top-center', showIcon: true})
} catch (e) {
alert(e)
}
}
}
let instance: any
onMounted(() => {
instance = getCurrentInstance()
})
const reset = () => {
instance.ctx.$refs.form.reset()
}
</script>
<template>
<v-container class="h-100 d-flex align-center justify-center">
<v-card width="500">
<v-card-title>用户登录</v-card-title>
<v-card-text class="pa-8">
<v-form ref="form">
<v-text-field variant="underlined" v-model="username" required
:counter="20"
label="账号"
prepend-icon="person"
></v-text-field>
<v-text-field variant="underlined" v-model="password" required
:counter="20"
label="密码"
prepend-icon="lock"
type="password"
></v-text-field>
<v-row class="mt-5">
<v-btn class="ml-5" @click="handleLogin">提交</v-btn>
<v-btn class="ml-5" @click="reset">复位</v-btn>
</v-row>
</v-form>
</v-card-text>
</v-card>
</v-container>
</template>
<style scoped>
</style>
运行项目,登录成功以后应该显示如下界面:
8. 前面我们只是实现了用户名和密码不能为空的简单表单验证,接下来我们要使用Vuetify的表单验证机制对表单数据进行更加完善的验证。
在src下新建hooks目录,在该目录下新建useValidRule.ts文件,在该文件中定义可以在多个组件中复用的Vuetify的表单验证规则(参见:Form component — Vuetify),内容如下:
import {ref} from "vue"
export const usernameRules = ref([
(v: string) => !!v || '必须输入账号!',
(v: string ) => (v && v.length <= 20 && v.length >= 3) || '账号的长度为3到20个字符!',
])
export const passwordRules = ref([
(v: string) => !!v || '必须输入密码!',
(v: string ) => (v && v.length <= 20 && v.length >= 8) || '密码的长度为8到20个字符!',
])
修改mock下index.ts中定义的密码,使其长度符合验证规则的要求。
9. 修改UserLogin.vue中的账号和密码字段,通过rules属性使用自定义的验证规则对用户名和密码进行验证,修改后的表单如下列代码所示:
<v-form ref="form">
<v-text-field variant="underlined" v-model="username" required
:counter="20"
label="账号"
prepend-icon="person"
:rules="usernameRules"
></v-text-field>
<v-text-field variant="underlined" v-model="password" required
:counter="20"
label="密码"
prepend-icon="lock"
type="password"
:rules="passwordRules"
></v-text-field>
<v-row class="mt-5">
<v-btn class="ml-5" @click="handleLogin">提交</v-btn>
<v-btn class="ml-5" @click="reset">复位</v-btn>
</v-row>
</v-form>
10. 修改handleLogin函数,增加验证判断,修改后的代码如下所示:
const handleLogin = async () => {
const {valid} = await instance.ctx.$refs.form.validate()
if (valid) {
if (username.value == '' || password.value == '') {
createToast('用户名或密码不能为空!', {position: 'top-center', showIcon: true})
} else {
try {
const res = await login({username: username.value, password: password.value})
createToast(res.data.msg, {position: 'top-center', showIcon: true})
} catch (e) {
alert(e)
}
}
}
}
11. 测试用户登录,当用户名和密码不符合验证规则时会显示验证错误信息并无法提交表单数据,如下图所示: