项目:
在线演示:https://fe-bigevent-web.itheima.net/login
接口文档: https://apifox.com/apidoc/shared-26c67aee-0233-4d23-aab7-08448fdf95ff/api-93850835
接口根路径: http://big-event-vue-api-t.itheima.net
一、登录页与注册页功能的实现
1、静态页面布局:
先做好静态登录与注册的页面布局(element-plus组件Container 布局容器),这个页面组件就叫做login/Login.vue吧(根据element-plus文档填写表单内容的相关属性)
=>最后得到登录与注册页面(这个两个页面属于同一个页面,用v-if.v-else做来回切换)
2、表单验证四部曲:
el-form 整个表单组件
el-form-item 表单的一行 (一个表单域)
el-input 表单元素(输入框)
2. 校验相关
(1) el-form => :model="ruleForm" 绑定的整个form的数据对象 { xxx, xxx, xxx }
(2) el-form => :rules="rules" 绑定的整个rules规则对象 { xxx, xxx, xxx }
(3) 表单元素 => v-model="ruleForm.xxx" 给表单元素,绑定form的子属性
(4) el-form-item => prop配置生效的是哪个校验规则 (和rules中的字段要对应)
注册页 :
①先声明整个用于提交的from数据对象
=>然后在表单Dom对象标签绑定 :model="formModel"属性
②绑定整个rules规则对象(用户名规则,密码规则,确认密码规则)
const rules = {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 5, max: 10, message: '用户名必须是 5-10位 的字符', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{
pattern: /^\S{6,15}$/,
message: '密码必须是 6-15位 的非空字符',
trigger: 'blur'
}
],
repassword: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{
pattern: /^\S{6,15}$/,
message: '密码必须是 6-15位 的非空字符',
trigger: 'blur'
},
{
validator: (rule, value, callback) => {
// 判断 value 和 当前 form 中收集的 password 是否一致
if (value !== formModel.value.password) {
callback(new Error('两次输入密码不一致'))
} else {
callback() // 就算校验成功,也需要callback
}
},
trigger: 'blur'
}
]
}
③给表单元素,绑定from子属性
④在表单元素,prop配置生效的是哪一个规则(这里是prop=username)
⑤最后,提交注册按钮时,进行整个表单验证:=>先获取表单DOM(这里给登录和注册绑定同一个ref值不影响,因为有v-if会自动销毁一个)
=>点击按钮时调用api( validate() 表单验证方法=>验证通过则弹出信息提示=>此时改变注册表单绑定v-if的值=>跳转到登录页)
const register = async () => {
// 注册成功之前,先进行校验,校验成功 → 请求,校验失败 → 自动提示
await form.value.validate() //校验(失败会自动提示)
await userRegisterService(formModel.value) //请求
ElMessage.success('注册成功')?//请求成功提示
isRegister.value = false//返回到登录页
}
登录页:
①也是四部曲
这里可以同注册表单使用同一个fromModel、rules(就不列举了),登录页唯一不同就是存token
②点击登录按钮时:
调用api(login)=>进行表单验证=>验证通过则调用封装好的获取token的接口=>接口返回的token存储到本地=>最后登录成功,跳转页面
③注册与登录页面切换的时候,记得重置表单
④给路由配置路由守卫
⑤注:以下是封装好的pinia仓库,router,api接口
*stores文件夹
*router文件夹
* api获取数据(图一封装所有请求接口,图二获取token接口)
⑥登录成功渲染数据
1.api/user.js
封装接口
// 获取用户基本信息 export const userGetInfoService = () => request.get('/my/userinfo')
2.stores/modules/user.js 定义数据
// 获取用户信息,本存到本地
const getUser = async () => {
const res = await userGetInfoService()//请求获取数据
user.value = res.data.data
}
3.layout/LayoutContainer(和登录都是一级路由,页面大框架)页面初始化就调用数据
4.渲染数据
<div>
黑马程序员:<strong>{{ userStore.user.nickname || userStore.user.username }}</strong>
</div>
<el-avatar :src="userStore.user.user_pic || avatar" />
⑦退出登录
1.注册点击事件(el-dropdown组件)
<el-dropdown placement="bottom-end" @command="handleCommand">//注册点击事件(handleCommand)
<!-- 展示给用户,默认看到的 -->
<span class="el-dropdown__box">
<el-avatar :src="userStore.user.user_pic || avatar" />//用户头像
<el-icon><CaretBottom /></el-icon>
</span>
<!-- 折叠的下拉部分 -->
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="profile" :icon="User"
>基本资料</el-dropdown-item
>
<el-dropdown-item command="avatar" :icon="Crop"
>更换头像</el-dropdown-item
>
<el-dropdown-item command="password" :icon="EditPen"
>重置密码</el-dropdown-item
>
<el-dropdown-item command="logout" :icon="SwitchButton"
>退出登录</el-dropdown-item
>
</el-dropdown-menu>
</template>
</el-dropdown>
2.点击时触发事件
const handleCommand = async (key) => {
if (key === 'logout') {
// 退出操作
await ElMessageBox.confirm('你确认要进行退出么', '温馨提示', {
type: 'warning',
confirmButtonText: '确认',
cancelButtonText: '取消'
})
// 清除本地的数据 (token + user信息)
userStore.removeToken()
userStore.setUser({})
router.push('/login')
} else {
// 跳转操作
router.push(`/user/${key}`)
}
}
3.stores/modules/ user.js 模块 提供 setUser 方法(退出传个空对象,清空用户数据)
const setUser = (obj) => (user.value = obj)
这里就完成了登录与注册的开发,同时也在登录成功时做了相应的数据渲染,以及退出登录操作