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 完毕

猜你喜欢

转载自blog.csdn.net/weixin_46048259/article/details/127462130