登录的写法,routerHook具体配置,流程
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 = newValuewindow.localStorage.setItem('token', token)}// 清除token,退出的时候const clear_token = (newValue) => {token = newValuewindow.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 } = ethis.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.usernameloginObj.password = this.loginForm.pwdloginObj.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到vuexttacLinkStore.set_token(token)//验证token是否通过的字段let tokenIsValidate = falsetry {//验证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 {//通过了再存一次tokenttacLinkStore.set_token(token)//是否是管理员登录//如果不是管理员,是普通用户if (ttacLinkStore.currentUserInfo.userinfo.username != 'admin') {//这个是当前登陆用户被分配的所有页面的数据//用户被分配权限的页面let selfmenus = await getSelfMenus()//存一下vuexttacLinkStore.save_menuSelfData(selfmenus.data)//这玩意是根据当前页面和所有路由对照,取出来的当前用户的有的路由let cuteuserroutes = cutePermissionRoutes(selfmenus.data, allroutes)//存一下ttacLinkStore.updateRoutes(cuteuserroutes)let path = null//跳到当前用户所有权限的路由的第一个界面,看需求用不用,用就下面的next,不用就直接nextfor (let index = 0; index < cuteuserroutes.length; index++) {const element = cuteuserroutes[index]if (!element.children || element.children.length < 1) {continue}path = element.children[0].pathbreak}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了,大头在用户分配权限这里