11、springboot3 vue3开发平台-前端-系统登录, token , 用户,菜单路由本地存储

1. 登录流程

  • 提交用户名密码
  • 后端校验成功后返回及用户相关信息
  • 本地存储相关信息
  • 跳转首页

2. 使用pinia保存用户信息

在src/stores/userInfo.ts, 创建pina 保存用户信息

import { defineStore } from "pinia"
import {ref} from 'vue'

export const useUserInfoStore = defineStore('userInfo', () => {
    const userInfo = ref<Record<string, any>>()
    const permissionList = ref<Array<string>>([])
    const roleList = ref<Array<string>>([])
    
    const setInfo = (newInfo: Record<string, any>, newPermissionList: Array<string>, newRoleList: Array<string> ) => {
        userInfo.value = newInfo
        permissionList.value = newPermissionList
        roleList.value = newRoleList
    }

    const removeInfo = () => {
        userInfo.value = {}
        permissionList.value = []
        roleList.value = []
    }

    return {userInfo, setInfo, removeInfo, permissionList, roleList}
},
{
    persist: true
}
)

3. 使用ts接口规范数据

在src/interface/auth/LoginData.ts


// 登录数据接口
export interface LoginData {
    username: string,
    password: string,
    rememberMe: boolean
}

4. 封装axios请求函数

在src/api/auth/index.ts

import axiosInstance from '@/request/axios-config'
import type { LoginData } from '@/interface/auth/index'

// 登录 
export const loginService = (longData: LoginData): Promise<any> =>{
    return axiosInstance.post('/auth/login', longData)
}

5. 登录

src/views/Login.vue

<template>
    <!-- 根div -->
    <div class="login_container">
        <div class="login_form">
            <h2 class="title">Vue3 TS Vite Springboot3 快速开发平台</h2>
            <el-form :model="loginForm" ref="ruleFormRef" :rules="rules">
                <!-- 用户名 -->
                <el-form-item prop="username">
                    <el-input v-model="loginForm.username" placeholder="请输入账号">
                        <template #prefix>
                            <el-icon class="el-input__icon"><i-ep-User /></el-icon>
                        </template>
                    </el-input>
                </el-form-item>
                <!-- 密码 -->
                <el-form-item prop="password">
                    <el-input v-model="loginForm.password" type="password" placeholder="请输入密码">
                        <template #prefix>
                            <el-icon class="el-input__icon"><i-ep-Lock /></el-icon>
                        </template>
                    </el-input>
                </el-form-item>
                <!-- 记住我和忘记密码 -->
                <div class="rememberMe">
                    <el-checkbox v-model="loginForm.rememberMe" label="记住我" size="large" />
                    <!-- 忘记密码 -->
                    <el-text class="forgetpass mx-1" type="primary">忘记密码?</el-text>
                </div>
                <!-- 分割线 -->
                <el-divider>其他登录方式</el-divider>
                
                <!-- 其他的登录方式 -->
                <div class="other_login">
                    <el-icon class="other_login_item"><i-epChromeFilled /></el-icon>
                    <el-icon class="other_login_item"><i-ep-ElemeFilled /></el-icon>
                    <el-icon class="other_login_item"><i-ep-wind-power /></el-icon>
                </div>
                <el-form-item>
                    <!-- 按钮 -->
                    <el-button style="width: 100%;" type="primary" @click="handleLogin">登录</el-button>
                </el-form-item>
            </el-form>
            
        </div>
    </div>

</template>

<script setup lang="ts">
    import { reactive, ref } from  'vue';
    // 导入login方法
    import { loginService } from '@/api/auth'
    import type { LoginData } from '@/interface/auth/index'
    import type { FormInstance, FormRules } from 'element-plus'
    import {useTokenStore } from '@/stores/token'
    import {useUserInfoStore} from '@/stores/userInfo'
    import {useRouter} from 'vue-router'

    const tokenStore = useTokenStore()
    const userInfoStore = useUserInfoStore()
    const router = useRouter()

    // 声明表单绑定值
    const loginForm = reactive<LoginData>({
        username: 'admin',
        password: '123456',
        rememberMe: false
    })

    // 声明 登录 方法
    const handleLogin = async () => {
        // 校验表单
		if (!ruleFormRef.value) return
        let validata

		try {
            await ruleFormRef.value.validate(async (valid) => {
			console.log("login validate", valid)
                if (valid) {
                    // 调用接口,完成登录
                   try {
                        let result = await loginService(loginForm)
                        if (result.code == 0) {
                            ElMessage.success(result.messge ? result.messge : '登录成功')
                            //token存储到pinia中
                            let tokenInfo = result.data.saTokenInfo;
                            tokenStore.setToken(tokenInfo.tokenName, tokenInfo.tokenValue)
                            // 存储用户信息
                            let data = result.data;
                            userInfoStore.setInfo(data.userInfo, data.permissionList, data.roleLabelList)
                            //跳转到首页 路由完成跳转
                            router.push('/index')
                            return
                        } else {
                            ElMessage.error(result.messge ? result.messge : '登录失败')
                        }
                   } catch (e) { 
                        console.error("login:", e)
                   }
                } else {
                    //console.log("输入信息校验失败")
                    return
                }
		    })
        } catch (e) {
            console.log("exception:", e)
            ElMessage.info('登录信息校验失败')
        }
    }

// 定义表单组件的引用
const ruleFormRef = ref<FormInstance>()
//定义表单校验规则
const rules = ref<FormRules<LoginData>>({
    username: [{
            required: true,
            message: '请输入用户名',
            trigger: 'blur'
        },
        {
            min: 5,
            max: 16,
            message: '长度为5~16位非空字符',
            trigger: 'blur'
        }
    ],
    password: [{
            required: true,
            message: '请输入密码',
            trigger: 'blur'
        },
        {
            min: 4,
            max: 16,
            message: '长度为5~16位非空字符',
            trigger: 'blur'
        }
    ]
})

</script>

<style lang="scss" scoped>
.login_container {
    // 背景图
    background-image: url('../assets/bgimg/bg1.jpg');
    background-size: 100%;
    height: 100vh;
    display: flex;
    justify-content: flex-end;
    .login_form {
        display: flex;
        justify-content: center;
        align-items: center;
        //设置换行
        flex-direction: column;
        width: 50%;
        background-color: #fff;

        .title {
            margin-bottom: 80px;
        }
        .rememberMe {
            display: flex;
            justify-content: space-between;
            align-items: center;
            .forgetpass {
                cursor: pointer;
            }
        }
        // 其他登录
        .other_login {
            display: flex;
            justify-content: center;
            margin-bottom: 20px;
            .other_login_item {
                margin-right: 60px;
                cursor: pointer;
            }
        }

    }
}

// 设置form的宽度
.el-form {
    width: 60%;
}
.el-form-item {
    width: 100%;
}

</style>
  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不知所云,

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值