routerHook挂在在index.js/main.js下的,找不到可以去那边看一下
vuex需要做的:
//创建token的sate,从本地取
let token = window.localStorage.getItem('token')
// 存储用户登录信息
let currentUserInfo = reactive({
userinfo: {}
})
//存根据不同权限分配的路由界面的数据
const permission_routes = reactive({
permission_routes: []
})
//存token,登陆时和rookhooks的时候存
const set_token = (newValue: any) => {
token = newValue
window.localStorage.setItem('token', token)
}
// 清除token,退出的时候
const clear_token = (newValue) => {
token = newValue
window.localStorage.removeItem('token')
}
//存用户信息
const set_currentUserInfo = (newValue: any) => {
currentUserInfo.userinfo = newValue
}
//清除用户信息
const clear_currentUserInfo = (newValue) => {
currentUserInfo.userinfo = newValue
}
//存当前的路由
const updateRoutes = (newRoutes) => {
permission_routes.permission_routes = [...newRoutes] // 确保数组是响应式的
}
1.第一步构建页面,这一步就是点击登录全部的流程,输入账密,点击调接口,存token
<el-form ref="loginForm" :model="loginForm" style="background-color:white;width:410px;margin-block-end:0em;" autocomplete="on"
label-position="left">
<div class="flexLeft" style="width: 100%;height: 84px;margin-bottom:36px">
<span class="loginForm-title" style="font-weight: 500;font-size: 38px;color: black;"> 欢迎登陆选型计算 </span>
<span class="loginForm-title" style="font-weight: 600;font-size: 24px;color: #18AEB7;">账户密码登录</span>
</div>
<el-form-item prop="username" style="margin-bottom: 24px;">
<!-- <span class="svg-contain1er">
<svg-icon icon-class="user" />
</span> -->
<span style="color: #9A9CA1;display: block;font-size: 18px;">用户名</span>
<el-input ref="username" v-model.trim="loginForm.username" placeholder="" name="username" type="text" tabindex="1" autocomplete="off" />
</el-form-item>
<el-tooltip v-model="capsTooltip" content="Caps lock is On" placement="right" manual>
<el-form-item prop="pwd">
<!-- <span class="svg-container">
<svg-icon icon-class="password" />
</span> -->
<span style="color: #9A9CA1;display: block;font-size: 18px;">密码</span>
<el-input :key="passwordType" ref="pwd" v-model.trim="loginForm.pwd" :type="passwordType" placeholder="" name="pwd" tabindex="2"
autocomplete="off" @keyup.native="checkCapslock" @blur="capsTooltip = false" @keyup.enter.native="handleLogin" />
<span class="show-pwd" @click="showPwd">
<span :style="{ 'display': passwordType === 'password' ? '' : 'none' }">
<Sunny></Sunny>
</span>
<span :style="{ 'display': passwordType === 'password' ? 'none' : '' }">
<Moon></Moon>
</span>
<!-- <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" /> -->
</span>
</el-form-item>
</el-tooltip>
<el-button :loading="loading" type="primary" class="login-button" @click.native.prevent="handleLogin">
登录
</el-button>
</el-form>
//下面是字段和方法
passwordType: 'password',
checkCapslock(e) {
const { key } = e
this.capsTooltip = key && key.length === 1 && key >= 'A' && key <= 'Z'
},
async handleLogin() {
window.localStorage.removeItem('token')
if (this.validateUser() && this.validatePass()) {
let loginObj = {}
loginObj.username = this.loginForm.username
loginObj.password = this.loginForm.pwd
loginObj.machineType = Number(1)
loginObj.machineName = ''
loginObj.machineId = ''
try {
// 登录接口,输入账号密码的
let token = await LoginWithPassword(loginObj)
// 存到vuex里一份
ttacLinkStore.set_token(token.data)
this.$router.push({ path: '/home' })
} catch (error) {
ElMessage({
message: error,
type: 'error'
})
}
// let token = 'asdfasdf'
}
}
2.路由跳转的时候的操作,点击登陆后针对不同用户不同操作
//所有的路由
import allroutes from './routes'
//跳转守卫
const router_beforeEach = async (to, from, next) => {
//去登录页,直接放
if (to.path == '/adminLogin') {
next()
return
} else {
//不然就是走具体方法
await hasTokenFromUrl(to, from, next)
}
}
//地址不是登录页就走这
async function hasTokenFromUrl(to, from, next) {
//从本地拿token,看有没有
let token = window.localStorage.getItem('token')
//本项目拿vuex的写法
let ttacLinkStore = useTTACLinkStore()
if (token) {
//存token到vuex
ttacLinkStore.set_token(token)
//验证token是否通过的字段
let tokenIsValidate = false
try {
//验证token是否通过,并且返回登录用户数据的
tokenIsValidate = await checkToken()
//保存用户数据到vuex的
ttacLinkStore.set_currentUserInfo(tokenIsValidate.data)
} catch (error) {}
//token验证不通过直接毙掉,回登录页
if (tokenIsValidate === false || tokenIsValidate.data === false) {
// await hasTokeLocal(to, from, next, type)
next('/adminLogin')
} else {
//通过了再存一次token
ttacLinkStore.set_token(token)
//是否是管理员登录
//如果不是管理员,是普通用户
if (ttacLinkStore.currentUserInfo.userinfo.username != 'admin') {
//这个是当前登陆用户被分配的所有页面的数据
//用户被分配权限的页面
let selfmenus = await getSelfMenus()
//存一下vuex
ttacLinkStore.save_menuSelfData(selfmenus.data)
//这玩意是根据当前页面和所有路由对照,取出来的当前用户的有的路由
let cuteuserroutes = cutePermissionRoutes(selfmenus.data, allroutes)
//存一下
ttacLinkStore.updateRoutes(cuteuserroutes)
let path = null
//跳到当前用户所有权限的路由的第一个界面,看需求用不用,用就下面的next,不用就直接next
for (let index = 0; index < cuteuserroutes.length; index++) {
const element = cuteuserroutes[index]
if (!element.children || element.children.length < 1) {
continue
}
path = element.children[0].path
break
}
next()
//next(path[0])
} else {
//管理员就存一下所有路由,
ttacLinkStore.updateRoutes(allroutes)
next()
}
}
} else {
//没token直接回登录
next('/adminLogin')
}
}
//用户被分配权限的页面,所有路由
function cutePermissionRoutes(userRoleMenus, allroutes) {
let res = []
const keysSet = new Set(userRoleMenus.map((item) => item.menuPath)) // 提取数组 A 的字段 'a'[^3] [ 'adminglog' ,'home'...... ,]
allroutes.forEach((item2) => {
if (keysSet.has(item2.path)) {
// 检查数组 B 的 'id' 是否存在于 keysSet 中
res.push(item2) // 如果匹配,则将该项添加到结果数组中
}
})
debugger
//返回的是分配的页面的路由数据,用于展示
return res
}
//基本上就ojbk了,大头在用户分配权限这里