vue-admin-template登录以及权限使用

vue-admin-template是vue-element-admin的一个基础方案,很适合入门使用。
vue-element-admin官网
首先下载下来之后,

npm install

在项目主目录运行该命令完成项目依赖的下载

npn run dev

运行这个命令即可完成项目的运行。
下面介绍关于登录部分

自定义登录接口

该项目是通过login进行登录且每一次请求通过info请求进行验证用户身份,以及logout退出登录。
找到登录页面代码(src/views/login/index.vue)

 handleLogin() {
      this.$refs.loginForm.validate(valid => {
        if (valid) {
          this.loading = true
          this.$store.dispatch('user/login', this.loginForm).then(() => {
            this.$router.push({ path: this.redirect || '/' })
            this.loading = false
          }).catch(() => {
            this.loading = false
          })
        } else {
          console.log('error submit!!')
          return false
        }
      })
    }

这里会会找到user/login接口,原项目这里是通过mock创建的模拟数据,这里我们要改成我们的自定义后端接口(src/api/user.js)

export function login(data) {
  return request({
    url: '/user/login',
    method: 'post',
    data
  })
}

export function getInfo() {
  return request({
    url: '/user/info',
    method: 'get',
  })
}

export function logout() {
  return request({
    url: '/user/logout',
    method: 'get'
  })
}

这里login做的是关于登陆验证的,info用来获取用户信息,这里主要是用来获取权限的。
这里准备的是Java后台

public Result<Map> info(HttpServletRequest request) {
        User user = getByToken(request);
        ArrayList<String> roles = new ArrayList<>();
        Integer roleId = user.getRoleId();
        switch (roleId) {
            case 1:
                roles.add("admin");
                break;
        }
        Map<String, ArrayList> map = new HashMap<>();
        map.put("roles",roles);
        return Result.success(map);
    }

这里将获取到的角色放到一个map中,返回给前台,注意我这里只返回了role,相当于我的data里只放了role。
登录就到此做完了,后面来做关于权限部分的东西。

路由权限控制

首先该项目的路由权限控制在路由js中通过role标签来控制的。(src/router/index.js)
对于一般的公共的路由,我们可以放在constantRoutes里

  export const constantRoutes = [
{
  path: '/login',
  component: () => import('@/views/login/index'),
  hidden: true
}

然后对于需要权限部分的路由,我们放在asyncRoutes里

//异步挂载的路由
//动态需要根据权限加载的路由表 
export const asyncRoutes  = [
{
  path: '/*******',
  component: Layout,
  children: [
    {
      path: 'index',
      name: '******',
      component: () => import('@/views/****/index'),
      meta: { title: '用户管理', icon: 'form',roles:['admin']}
    }
  ]
},
{ path: '*', redirect: '/404', hidden: true }
];

这里需要注意的是,404一定要放到最后

这里就完成了路由的权限制定,那么是怎么来确定用户身份,并动态显示的呢?
登录过程首先会执行store/modules/user.js的方法

const getDefaultState = () => {
  return {
    token: getToken(),
    name: '',
    //这里我只需要roles,所以就留了roles,这里注意是roles是一个数组,所以我后台也是对的map传过来的。
    roles:[]
  }
}

const state = getDefaultState()

const mutations = {
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState())
  },
  SET_TOKEN: (state, token) => {
    state.token = token
  },
  SET_NAME: (state, name) => {
    state.name = name
  },
  //设置roles
  SET_ROLES: (state, roles) => {
    state.roles = roles
  }
}

const actions = {
  // user login
  login({ commit }, userInfo) {
    const { username, password } = userInfo
    return new Promise((resolve, reject) => {
      login({ username: username.trim(), password: password }).then(response => {
      //这里会请求到后台,后台返回用户名的名称,然后作为token存到cookie中,这一步看后台怎么写的,这里我是因为我每一个请求都要带token,后台做验证
        const { data } = response
        commit('SET_TOKEN', data)
        setToken(data)
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

  // get user info
  getInfo({ commit, state }) {
    return new Promise((resolve, reject) => {
      getInfo(state.token).then(response => {
        const { data } = response

        if (!data) {
          return reject('Verification failed, please Login again.')
        }
		//上面提到我后台的info方法里就放了roles,所以这里是直接获取
        const {  roles } = data
		//设置roles
        commit('SET_ROLES', roles)
        resolve(data)
      }).catch(error => {
        reject(error)
      })
    })
  },

  // user logout
  logout({ commit, state }) {
    return new Promise((resolve, reject) => {
      logout(state.token).then(() => {
        removeToken() // must remove  token  first
        resetRouter()
        commit('RESET_STATE')
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },

这里的每一个方法,执行过程中都会去调用我们的api里的方法,去请求后台

然后在info请求中,需要在请求头里进行防止token,所以我们在项目提供的request.js里进行修改一下。(对应后台进行修改),把登录设置的token拿出来设置到请求头里

// request interceptor
service.interceptors.request.use(
  config => {
    // do something before request is sent

    if (store.getters.token) {
      // let each request carry token
      // ['X-Token'] is a custom headers key
      // please modify it according to the actual situation
      // config.headers['X-Token'] = getToken()
      //这里根据后台进行设置
      config.headers.Token = getToken();
    }
    return config
  },
  error => {
    // do something with request error
    console.log(error) // for debug
    return Promise.reject(error)
  }
)

这个是该项目封装的一个拦截器,每一次请求都会走它

每一次路由的改变都会触发src/permission.js 的beforeEach方法进行跳转
判断是否登录已经身份

router.beforeEach(async(to, from, next) => {
  // start progress bar
  NProgress.start()

  // set page title
  document.title = getPageTitle(to.meta.title)

  // determine whether the user has logged in
  const hasToken = getToken()

  if (hasToken) {
    if (to.path === '/login') {
      // if is logged in, redirect to the home page
      next({ path: '/' })
      NProgress.done()
    } else {
      const hasGetUserInfo = store.getters.name
      if (hasGetUserInfo) {
        next()
      } else {
        try {
          // get user info
          // await store.dispatch('user/getInfo')
          //从请求中获取到角色
          const { roles } = await store.dispatch('user/getInfo')
          console.log("获取到的roles"+roles)

          // generate accessible routes map based on roles
          //这里从permission/generateRoutes拿到路由
          const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
          //刷新路由
          router.options.routes = store.getters.permission_routes
          // dynamically add accessible routes
          router.addRoutes(accessRoutes)

          // next({...to,replace:true})
          next()
        } catch (error) {
          // remove token and go to login page to re-login
          await store.dispatch('user/resetToken')
          Message.error(error || 'Has Error')
          next(`/login?redirect=${to.path}`)
          NProgress.done()
        }
      }
    }
  } else {
    /* has no token*/

    if (whiteList.indexOf(to.path) !== -1) {
      // in the free login whitelist, go directly
      next()
    } else {
      // other pages that do not have permission to access are redirected to the login page.
      next(`/login?redirect=${to.path}`)
      NProgress.done()
    }
  }
})

上面有一个步骤是从permission/generateRoutes拿到路由(src/store/module/permission.js)

import { asyncRoutes, constantRoutes } from '@/router'

/**
 * Use meta.role to determine if the current user has permission
 * @param roles
 * @param route
 */
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    return roles.some(role => route.meta.roles.includes(role))
  } else {
    return true
  }
}

/**
 * Filter asynchronous routing tables by recursion
 * @param routes asyncRoutes
 * @param roles
 */
export function filterAsyncRoutes(routes, roles) {
  const res = []

  routes.forEach(route => {
    const tmp = { ...route }
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })

  return res
}

const state = {
  routes: [],
  addRoutes: []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  }
}

const actions = {
  generateRoutes({ commit }, roles) {
    return new Promise(resolve => {
      let accessedRoutes
      if (roles.includes('admin')) {
      //路由是否有admin,有直接全部显示
        accessedRoutes = asyncRoutes || []
      } else {
      //accessedRoutes这个就是当前角色可见的动态路由
        accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      }
      commit('SET_ROUTES', accessedRoutes)
      resolve(accessedRoutes)
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

该文件该基础项目应该是没有的,需要自己创建,创建之后还要在module下的index.js进行注册

import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
import app from './modules/app'
import settings from './modules/settings'
import user from './modules/user'
import permission from '@/store/modules/permission'

Vue.use(Vuex)

const store = new Vuex.Store({
  modules: {
    app,
    settings,
    user,
    permission
  },
  getters
})

export default store

不然会爆找不到modules/permission的错误

最后就是怎么拿到路由和role
在module下的getter.js文件添加两行

const getters = {
  sidebar: state => state.app.sidebar,
  device: state => state.app.device,
  token: state => state.user.token,
  avatar: state => state.user.avatar,
  name: state => state.user.name,
  //添加以下两行
  roles: state =>state.user.roles,
  permission_routes: state=>state.permission.routes
}
export default getters

自此,一个简单的路由权限动态显示就完成了。

  • 12
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
vue-admin-template是一个基于Vue.js和Element UI的后台管理系统模板。它提供了一套完整的前端解决方案,包括路由、权限控制、布局等,可以帮助开发者快速搭建和开发后台管理系统。 使用vue-admin-template可以按照以下步骤进行: 1. 克隆或下载模板代码:你可以从GitHub上找到vue-admin-template的代码仓库,将代码克隆到本地或者直接下载压缩包。 2. 安装依赖:进入项目目录,在命令行中运行`npm install`或者`yarn install`命令,安装项目所需的依赖包。 3. 运行开发服务器:在命令行中运行`npm run dev`或者`yarn dev`命令,启动开发服务器。这将会在本地启动一个开发环境的服务器,并自动打开浏览器展示项目页面。 4. 开始开发:在浏览器中打开项目页面后,你可以根据需要修改和开发页面。vue-admin-template提供了一些示例页面和组件,你可以参考它们进行开发。 5. 构建生产版本:当你完成了开发并准备部署时,可以运行`npm run build`或者`yarn build`命令,构建生产版本的代码。构建完成后,你可以将生成的dist目录中的文件部署到服务器上。 6. 配置路由和权限vue-admin-template使用Vue Router来管理路由,你可以在src/router目录下的index.js文件中配置路由。同时,你可以在src/permission.js文件中配置权限控制逻辑。 7. 自定义主题:vue-admin-template使用Element UI作为UI组件库,你可以根据需要自定义主题。具体的自定义方法可以参考Element UI的官方文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值