一、想要实现的效果
二、搭建登录静态
1、实现左边背景和右边登录栏的总体布局布局:
<el-row class="content"><!--el-col 列: --><el-col :span="16" :xs="0" class="content-left"></el-col><el-col :span="8" :xs="24" class="content-right">
<el-row>
2、账号密码登录和手机号码登录切换使用<el-tabs>组件实现:
3、其他省略
4、全部代码:
<el-row class="content"><!--el-col 列: --><el-col :span="16" :xs="0" class="content-left"></el-col><el-col :span="8" :xs="24" class="content-right"><div class="loginContent"><div class="loginContentTop"><div class="header"><div class="logo"><img src="../assets/images/logo.png" alt="" class="image" /></div><div class="fontSize">JinPiKa</div></div><span class="introduce">全球最大的代码托管平台</span></div><div class="loginContentForm"><div class="loginMethods"><el-tabs><el-tab-panelabel="账号密码登录"class="toLogin":class="{ option: !option }"@click="toOption(0)"><!-- loginForm: 表单数据对象--><el-form:model="loginForm":rules="loginFormRules"style="width: 208px"><el-form-item label="" prop="username"><el-input:prefix-icon="User"placeholder="用户名:user"v-model="loginForm.username"inline-message></el-input></el-form-item><el-form-item label="" prop="password"><el-input:prefix-icon="Lock"placeholder="密码:user"show-passwordv-model="loginForm.password"inline-message></el-input></el-form-item></el-form></el-tab-pane><el-tab-panelabel="手机号码登录"class="toLogin":class="{ option: !option }"@click="toOption(0)"><!-- loginForm: 表单数据对象--><el-form:model="loginFormPhone":rules="loginFormPhoneRules"style="width: 208px"prop="phone"><el-form-item label=""><el-input:prefix-icon="User"placeholder="请输入手机号"v-model="loginFormPhone.phone"inline-message></el-input></el-form-item><el-form-item label="" prop="code"><el-input:prefix-icon="Lock"placeholder="请输入验证码"v-model="loginFormPhone.code"inline-message></el-input></el-form-item></el-form></el-tab-pane></el-tabs></div></div><div class="loginContentButton"><div class="buttonTop"><el-checkbox v-model="checked" label="自动登录" size="small" /><el-link type="primary" :underline="false"><span style="font-size: 12px">忘记密码</span></el-link></div><el-button type="primary" class="loginButton" @click="tologin">登录</el-button><el-divider><span class="fengexian">其他登录方式</span></el-divider><div class="svgItems"><div class="svgItem"><svg-iconname="zhifubao"width="18px"height="18px"color="pink"></svg-icon></div><div class="svgItem"><svg-iconname="taobao"width="18px"height="18px"color="pink"></svg-icon></div><div class="svgItem"><svg-iconname="weibo"width="18px"height="18px"color="pink"></svg-icon></div></div></div></div></el-col></el-row>
三、封装接口
1、首先需要对axios进行一个二次封装,实现请求和响应拦截器,在utils文件夹(一般用于存放封装的文件)下创建一个request.ts文件,
import axios from 'axios'
const requeset=axios.create({baseURL: import.meta.env.BASE_URL, //基础路径timeout:5000 //发请求超时时间为5s
})
//给request实例添加请求拦截器
request.interceptors.request.use((config)=>{// config:配置对象:里面有个headers属性请求头,经常给服务器端通过请求头携带公共参数return config
})
//配置响应拦截器
request.interceptors.response.use(//成功响应:返回服务端的数据 (response)=>{return response.data},//失败响应:会返回错误对象,用来处理http网络错误(error)=>{// 存储网络错误信息let message = ''// 根据http状态码判断网络错误const status = error.response.statusswitch (status) {case 401:message = '登录已过期,请重新登录'breakcase 403:message = '没有权限,请联系管理员'breakcase 404:message = '请求资源不存在'breakcase 500:message = '服务器内部错误'breakdefault:// eslint-disable-next-line @typescript-eslint/no-unused-varsmessage = '网络错误'break}// 提示错误信息ElMessage({type: 'error',message,})// 返回一个失败的promise对象return Promise.reject(error)})
2、引入pinia
(1)在store文件夹下创建pinia仓库,
// 引入 pinia
import { createPinia } from 'pinia'
// 创建大仓库
const pinia = createPinia()
// 对外暴露
export default pinia
(2)在main.ts中,引入仓库并全局使用pinia
// 引入仓库
import pinia from './store'
// 全局使用 pinia
app.use(pinia)
3、在api文件夹下,封装登录接口,用于统一管理用户相关的接口
// 引入封装好的 request
import request from '@/plugins/request'
// 引入用户相关的 ts 类型检测
import { loginForm, loginResponseData } from './type'
//用户相关接口的请求地址
enum API{//用户登录的请求地址:在接口文档中,去掉默认请求地址baseURL后剩下的部分LOGIN='/admin/login'
}
//登录接口
export const reqLogin=(data:loginForm)=>{request.post<any,loginResponseData>(API.LOGIN,data)
}
或者第二种普通封装方式:
// 封装登录相关接口
import { loginForm } from '@/apis/user/type'
import request from '@/utils/request'
export function useLoginAPI(data: loginForm) {return request({url: 'http://monitor-spring.jinxinapp.cn/api/v1/admin/login',method: 'POST',data,})
}
3、在store文件夹下创建用户相关的小仓库
// 用户相关的小仓库
import { defineStore } from 'pinia'
//引入登录接口
import {reqLogin} from '@/api/user/index.ts'
const useUserStore=defineStore('user',{state:()=>{return{token:localStorage.getItem('token'),}},actions:{//用户登录的方法,data是登录时传入的账号密码async useLogin(data:loginForm){//登录请求const result=awiat reqLogin(data)if(result.code==200){this.token=result.data.tokenlocalStorage.getItem('token',result.data.token)return 'ok'}else{return Promise.reject(new Error(result.data.message))}}},getters:{}
})
export default useUserStore
4、在登录页面,点击登录按钮调用tologin方法
const tologin=async ()=>{try{//调用仓库里的登录方法,传入的loginForm里面是账号密码await useStore.userLogin(loginForm)$router.push('/home') //登录成功跳转首页,ElNotification({title: '成功',message: '登录成功',type: 'success',})}catch(error){ElNotification({message: (error as Error).message,type: 'error',})}
}