09-vue-cli-导航钩子和权限控制

一、导航钩子

1.记录用户登录没,之前是将用户登录信息放到session中,在过滤器中去看用户登录没。现在不行,要使用

        vue-router 提供的导航钩子主要用来拦截导航,让它完成跳转或取消。其实就是和java的过滤器一个原理。

        导航钩子函数:router.beforeEach ( )

        一般用来做一些进入页面的限制。比如没有登录,就不能进入某些页面,只有登录了之后才有权限查看某些页面。。说白了就是路由拦截。

        说明:实现用户访问某个vue组件需要登录才能访问,实现步骤如下:

1 在vue-cli的路由配置index.js里给某个vue组件设置 meta:{"isLogin":true} 配置,子路由也要配置isLogin’ 是自定义建名,代码如下:

{
      path: '/index',  //首页
      name: 'index',
      meta:{"isLogin":true}, //访问这个页面,需要登录才能访问
      redirect:"/welcome",//默认打开index页面,子路由地址指向的地址
      component: index,
      children:[      //配置子路由
        {
          path: "/welcome",
          name: 'welcome',
          meta:{"isLogin":true},
          component: welcome
        }
      ],
    },

2 在入门文件main.js文件,添加导航钩子函数,配置权限过滤。此导航钩子和java过滤器类似,访问任意vue组件都先访问这个函数,所以在这里可以写用户访问控制逻辑,代码如下

/* 定义一个导航钩子函数
    to:到达的下一个路由对象
    from:从那个路由来的路由对象
    next:相当于java的放行函数,next("/index");
*/
router.beforeEach(function(to,from,next){
  //会拦截所有的地址
  var name = localStorage.getItem("userName");
  //拦截逻辑
//判断到达的路由对象meta值是否需要访问
if(to.meta.isLogin){
  //判断是否登录过
  if(name != null){
    //登陆过,放行
    next();
  }else{
    //没有登录回到登录页面
    return next("/login");
  }
}else{
  //没有配置,放行
  next();
  }
})

二、权限控制

<!-- router 开启路由地址配置-->
        <el-menu
        :default-openeds="['1','2']"
        text-color="white"
        background-color="#333333"
        router>
             <!-- 一级菜单-->
             <!-- index 菜单索引-->
             <template v-for="x in node ">
               <el-submenu :index="x.index">
                     <template slot="title">
                          <i :class="x.icon"></i>
                          <span>{{x.name}}</span>
                       </template>
                      <!-- 二级菜单-->
                      <template v-if="x.children!=null">

                        <template v-for="y in x.children">
                          <!-- index 路由地址-->
                           <el-menu-item :index="y.url">
                                  <template>
                                      <i :class="y.icon"></i>
                                      {{y.name}}
                                    </template>
                          </el-menu-item>
                        </template>
                      </template>
               </el-submenu>
             </template>
        </el-menu>

说明:实现用户根据角色不同,在登录系统主页面看到的权限连接也不同

1 数据库准备,创建用户表,角色表,权限表,用户角色中间表,角色权限中间表,表结构如下:

#用户表
DROP TABLE IF EXISTS `user_info`;
CREATE TABLE `user_info` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(25) DEFAULT NULL,
  `user_pwd` varchar(100) DEFAULT NULL,
  `user_salt` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
#角色表
DROP TABLE IF EXISTS `role_info`;
CREATE TABLE `role_info` (
  `role_id` int(11) NOT NULL AUTO_INCREMENT,
  `role_name` varchar(28) DEFAULT NULL,
  PRIMARY KEY (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
#权限表
DROP TABLE IF EXISTS `power`;
CREATE TABLE `power` (
  `power_id` int(11) NOT NULL AUTO_INCREMENT,
  `power_name` varchar(25) DEFAULT NULL,
  `power_index` varchar(5) DEFAULT NULL,
  `power_url` varchar(25) DEFAULT NULL,
  `parent_id` int(11) DEFAULT NULL,
  `node_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`power_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
#用户角色中间表
DROP TABLE IF EXISTS `user_role_rel`;
CREATE TABLE `user_role_rel` (
  `ur_id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `role_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`ur_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
#角色权限中间表
DROP TABLE IF EXISTS `role_power_rel`;
CREATE TABLE `role_power_rel` (
  `rp_id` int(11) NOT NULL AUTO_INCREMENT,
  `role_id` int(11) DEFAULT NULL,
  `power_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`rp_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;



2 根据5张表,我们分析出根据用户名查询用户拥有的权限的sql语句,代码如下:

SELECT p.* from user_info u INNER JOIN user_role_rel urr
on u.user_id = urr.user_id INNER JOIN role_info  r
on r.role_id = urr.role_id INNER JOIN role_power_rel rpr
on r.role_id = rpr.role_id INNER JOIN power p
on p.power_id = rpr.power_id
where u.user_name='admin'

         

3 根据查询语句得出的表结构,我们定义描述这个表结构的pojo类,代码如下:

@Data
public class MyNode {

    private Integer powerId;
    private String name;
    private String icon;
    private String index;
    private String url;
    //记录子菜单
    private List<MyNode> children;

    private Integer parentId;
    private Integer nodeId;

}

4 定义查询sql的dao层接口

public interface MyNodeMapper {

    List<MyNode> selectPower(String userName);
}

5 定义dao 层接口的sql映射文件xml,UserInfoMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.hqyj.dao.UserInfoDao" >
    <resultMap id="MyMap" type="com.hqyj.pojo.MyNode">
        <result property="powerId" column="power_id" jdbcType="INTEGER"></result>
        <result property="index" column="power_index" jdbcType="VARCHAR"></result>
        <result property="name" column="power_name" jdbcType="VARCHAR"></result>
        <result property="url" column="power_url" jdbcType="VARCHAR"></result>
        <result property="parentId" column="parent_id" jdbcType="INTEGER"></result>
        <result property="nodeId" column="node_id" jdbcType="INTEGER"></result>
    </resultMap>

    <select id="queryPowerByName" resultMap="MyMap" parameterType="java.lang.String">
            SELECT p.* from user_info u INNER JOIN user_role_rel urr
on u.user_id = urr.user_id INNER JOIN role_info  r
on r.role_id = urr.role_id INNER JOIN role_power_rel rpr
on r.role_id = rpr.role_id INNER JOIN power p
on p.power_id = rpr.power_id
where u.user_name=#{userName}
    </select>
</mapper>

6 定义service接口

public interface MyNodeService {
    //查询权限
    HashMap<String,Object> selectPower(String userName);
}

7 定义service接口实现类,这里有一个逻辑:如何把查询的权限结果,分析出他们的父子关系,代码如下

@Override
    public ResultVo queryPowerByName(String userName) {
        ResultVo resultVo = new ResultVo();
        List<MyNode> nodeList = userInfoDao.queryPowerByName(userName);

        List<MyNode> newList = new LinkedList<>();

        //构建树形结构
        if (nodeList.size() > 0){
            //遍历权限集合
            for (MyNode myNode : nodeList){
                //查找一级菜单
                if (myNode.getParentId() == 0){
                    //创建一级菜单的子菜单集合对象
                    List<MyNode> childRenList = new LinkedList<>();
                    //查找一级菜单的子菜单
                    for (MyNode n : nodeList){
                        //看当前的菜单是不是一级菜单的子菜单
                        if (n.getParentId() == myNode.getNodeId()){
                            childRenList.add(n);
                        }
                    }
                    //设置子菜单到一级菜单
                    myNode.setChildren(childRenList);
                    //添加树形节点
                    newList.add(myNode);
                }
            }
            resultVo.setSuccess(true);
            resultVo.setData(newList);
        }
        return resultVo;
    }

8 控制器方法

  //查询权限
    @GetMapping("/queryPower")
    public ResultVo queryPowerByName(String userName){
        return userInfoService.queryPowerByName(userName);
    }

9 vue登录前端,用本地存储记录登录用户名

 localStorage.setItem("userName",mythis.userInfo.name);

10 在vue系统主页面取出登录用户名,访问服务端,得到结果集赋值给绑定的权限集合node

<script>

  export default {
    name: "index",
    data() {
      return {
        userName:"",//登录用户名
        node:[],   //树节点
      }
    },
    methods:{
        backIndex(){   //返回欢迎页面地址
          this.$router.push("/welcome");

        },
        backLogin(){   //退出
          //回到登录页面
          this.$router.push("/login");
          //清除登录信息
          localStorage.removeItem("userName");
          //刷新
          this.$router.go(0);
        }
    },
    mounted(){
      //获取存在本地存储的cookie的用户名
      this.userName = localStorage.getItem("userName");
      //加载权限菜单
      var self = this;
      this.$http.get("/userInfo/queryPower",
                      {params:
                            {"userName":this.userName},
                            }).then(function(rs){
                              self.node = rs.data.data;
                            }).catch(function(rs){
                              console.log(rs);
                              console.log("连接服务器错误!");
                            })

      //获取存在本地存储的sesssion的用户名
      // this.userName = sessionStorage.getItem("userName");
    }

  }
</script>

11 这里用element-ui的权限菜单组件 显示登录用户的权限信息,代码如下

 <el-menu :default-openeds="['1','2','3','4','5']" router >

         <template v-for="x in node">
            <el-submenu :index="x.index">
                   <template slot="title"><i class="el-icon-message"></i>{{x.name}}
                   </template>
                   <template v-for="y in x.children">
                         <el-menu-item :index="y.url"><i class="el-icon-message"></i>{{y.name}}</el-menu-item>
                     </template>
              </el-submenu>
         </template>


      </el-menu>

12 完毕

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
课程简介:历经半个多月的时间,Debug亲自撸的 “企业员工角色权限管理平台” 终于完成了。正如字面意思,本课程讲解的是一个真正意义上的、企业级的项目实战,主要介绍了企业级应用系统中后端应用权限的管理,其中主要涵盖了六大核心业务模块、十几张数据库表。 其中的核心业务模块主要包括用户模块、部门模块、岗位模块、角色模块、菜单模块和系统日志模块;与此同时,Debug还亲自撸了额外的附属模块,包括字典管理模块、商品分类模块以及考勤管理模块等等,主要是为了更好地巩固相应的技术栈以及企业应用系统业务模块的开发流程! 核心技术栈列表: 值得介绍的是,本课程在技术栈层面涵盖了前端和后端的大部分常用技术,包括Spring Boot、Spring MVC、Mybatis、Mybatis-Plus、Shiro(身份认证与资源授权跟会话等等)、Spring AOP、防止XSS攻击、防止SQL注入攻击、过滤器Filter、验证码Kaptcha、热部署插件Devtools、POI、Vue、LayUI、ElementUI、JQuery、HTML、Bootstrap、Freemarker、一键打包部署运行工具Wagon等等,如下图所示: 课程内容与收益: 总的来说,本课程是一门具有很强实践性质的“项目实战”课程,即“企业应用员工角色权限管理平台”,主要介绍了当前企业级应用系统中员工、部门、岗位、角色、权限、菜单以及其他实体模块的管理;其中,还重点讲解了如何基于Shiro的资源授权实现员工-角色-操作权限、员工-角色-数据权限的管理;在课程的最后,还介绍了如何实现一键打包上传部署运行项目等等。如下图所示为本权限管理平台的数据库设计图: 以下为项目整体的运行效果截图: 值得一提的是,在本课程中,Debug也向各位小伙伴介绍了如何在企业级应用系统业务模块的开发中,前端到后端再到数据库,最后再到服务器的上线部署运行等流程,如下图所示:

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值