(一)用户登录页面的实现
1.登录页面静态页面
<div class="login">
<div class="loginFlat">
<h1>用户登录</h1>
<el-form>
<el-form-item label="账号:">
<el-input></el-input>
</el-form-item>
<el-form-item label="密码:">
<el-input></el-input>
</el-form-item>
</el-form>
<el-button>登录 </el-button>
</div>
</div>
配置路由
在router/index中:
{
path: '/login',
name: 'login',
component: () => import('@/views/Login.vue')
}
2.登录跳转
点击发送登录请求,将账号密码传给mock
在login中:
import { usePermitStore } from '@/stores/Permit';
const router = useRouter()
let loginForm = reactive({
name: '',
password: ''
})
const permitStore = usePermitStore()
async function handleLogin() {
// 发送登录请求
await login(loginForm).then((res: any) => {
if (res.code == 200) {
// 将登录token和menulist传给store
permitStore.setToken(res.data.token)
permitStore.setMenu(res.data.menuList)
router.push('/')
} else {
alert(res.data.message)
}
})
}
<el-button @click="handleLogin">登录</el-button>
mock请求根据不同账号发送不同的菜单list给login
import Mock from "mockjs";
import { nanoid } from "nanoid";
// 用于标志用户
let token = nanoid()
// 管理员
const adminUser = {
name: 'admin',
password: '123123'
}
// 一般用户
const normalUser = {
name: 'dogegg',
password: '12345'
}
// 管理员看到的菜单
const admiMenuListData = [
{
path: "/",
name: "home",
label: "首页",
icon: "house",
url: "Home/Home",
},
{
path: "/mall",
name: "mall",
label: "商品管理",
icon: "video-play",
url: "MallManage/MallManage",
},
{
path: "/user",
name: "user",
label: "用户管理",
icon: "user",
url: "UserManage/UserManage",
},
{
label: "其他",
icon: "location",
children: [
{
path: "/page1",
name: "page1",
label: "Page1",
icon: "setting",
url: "Other/PageOne",
},
{
path: "/page2",
name: "page2",
label: "Page2",
icon: "setting",
url: "Other/PageTwo",
},
],
},
]
// 普通用户看到的菜单
const normalMenuListData = [
{
path: "/",
name: "home",
label: "首页",
icon: "house",
url: "Home/Home",
},
{
path: "/user",
name: "user",
label: "用户管理",
icon: "user",
url: "UserManage/UserManage",
},
]
let menu = []
Mock.mock('/mock/permit/login', 'post', (config) => {
let { name, password } = JSON.parse(config.body)
if (name == adminUser.name && password == adminUser.password) {
menu = admiMenuListData
} else if (name == normalUser.name && password == normalUser.password) {
menu = normalMenuListData
} else { // 密码账号错误
return {
code: 201,
data: {
message: '账号或密码错误!'
}
}
}
// 成功就返回token和菜单
return {
code: 200,
data: {
token,
menuList: menu
}
}
})
新建usePermitStore用于存储跟登录有关的数据和方法
import { defineStore } from 'pinia'
import { ref } from 'vue'
import Cookies from 'js-cookie'
import { useRouter } from 'vue-router'
import { useMenuStore } from './Menu'
export const usePermitStore = defineStore('Permit', () => {
const router = useRouter()
let menuList: any = ref([])
function setToken(token: string) {
Cookies.set('token', token)
}
// 登录后存储menu在localStorage
function setMenu(menu: any) {
menuList.value = menu
// 菜单存储到本地
localStorage.setItem('menu', JSON.stringify(menu))
}
return {
setToken, setMenu, menuList,
}
})
获取对应的menulist后存储到store中,通过本地存储实现持久化处理,一刷新就重新获取menulist
在store/permit中:
// 获取menulist 实现持久化
function getMenu() {
if (!localStorage.getItem('menu')) return
menuList.value = JSON.parse(localStorage.getItem('menu') as string)
}
在commonAside中:
import { usePermitStore } from '@/stores/Permit';
const permitStore = usePermitStore()
// 从本地获取menu 每次刷新都重新获取在本地存储的menulist
permitStore.getMenu()
3.退出登录
点击commonHeader里的退出退出登录,返回到登录页
退出登录即删除token、删除本地存储的menulist、删除tagsList(存储在menuStore中,需要引入再操作)
在store/Permit中:
import { useMenuStore } from './Menu'
// 退出登录
function deleteMenu() {
localStorage.removeItem('menu')
Cookies.remove('token')
useMenuStore().clearTags()
router.push('/login')
}
在store/Menu中:
// 退出登录后清除tags
function clearTags() {
tagsList.value = [{
path: "/",
name: "home",
label: "首页",
icon: "house",
url: "Home/Home",
}]
}
(二)路由守卫
这个项目比较简单,只需要全局前置路由守卫
需要使用到cookie,若cookie存在即为登录状态
下载js-cookie(两个都需要下,否则报错)
npm i js-cookie
npm i @types/js-cookie
使用方法:
import Cookies from 'js-cookie'
Cookies.set('token', token)
Cookies.get('token')
Cookies.remove('token')
实现功能:
未登录时不能跳转到除登录页以外的页面;
登录后不能再跳转到登录页;
不能跳转到不存在的路由;
// 全局前置路由守卫
router.beforeEach((to, from, next) => {
// 判断是否为存在的路径 不是则回到主页路由
let check = router.getRoutes().filter((item) => {
return item.path == to.path
}).length
if (!check) {
next('/')
}
// 已登录
if (Cookies.get('token')) {
// 不能再跳转到login
if (to.fullPath == '/login') {
next(from.path)
} else {
next()
}
} else { // 未登录
if (to.path != '/login') {
// 不能访问登录页以外的页面
next('/login')
} else {
next()
}
}
})
(三)结束
搞完了。。这个项目功能感觉好少。。后面想把后端部分重新用node和mysql实现一下 加油