Vue-router:11、addRoutes动态路由添加

Vue-router:11、addRoutes动态路由添加

在前面的案例中,我们都是将路由定义好,然后通过路由守卫来判断,某个用户是否登录,从而决定能否访问某个路由规则对应的组件内容。

但是,如果某些路由规则只能用户登录以后才能够访问,那么我们也可以不用提前定义好,而是在登录后,通过addRoutes方法为其动态的添加。

首先这里需要,还需要全局的路由守卫来进行校验判断,只不过这里全局路由守卫的逻辑发生了变化。

router.beforeEach((to, from, next) => {
        //to:去哪个页面,from来自哪个页面,next继续执行.
        if (window.isLogin) {
          //用户已经登录
          if (to.path === "/login") {
            // 用户已经登录了,但是又访问登录页面,这里直接跳转到用户列表页面
            next("/");
          } else {
            //用户已经登录,并且访问其它页面,则运行访问
            next();
          }
        } else {
          //用户没有登录,并且访问的就是登录页,则运行访问登录页
          if (to.path === "/login") {
            next();
          } else {
            //用户没有登录,访问其它页面,则跳转到登录页面。
            next("/login?redirect=" + to.fullPath);
          }
        }
      });

下面对登录组件进行修改

const Login = {
        data() {
          return {
            isLogin: window.isLogin,
          };
        },

        template: `<div>
            <button @click="login" v-if="!isLogin">登录</button>
            <button @click="logout" v-else>注销</button>
            </div>`,
        methods: {
          login() {
            window.isLogin = true;
            if (this.$route.query.redirect) {
              //动态添加路由:
              this.$router.addRoutes([
                {
                  path: "/",
                  component: App,
                  redirect: "/users",
                  children: [
                    {
                      path: "/users",
                      component: Users,
                      meta: {
                        auth: true,
                      },
                      // beforeEnter(to, from, next) {
                      //   if (window.isLogin) {
                      //     next();
                      //   } else {
                      //     next("/login?redirect=" + to.fullPath);
                      //   }
                      // },
                    },
                    { path: "/userinfo/:id", component: UserInfo, props: true },
                    { path: "/rights", component: Rights },
                    { path: "/goods", component: Goods },
                    { path: "/orders", component: Orders },
                    { path: "/settings", component: Settings },
                  ],
                },
              ]);
              this.$router.push(this.$route.query.redirect);
            } else {
              this.$router.push("/");
            }
          },
          logout() {
            this.isLogin = window.isLogin = false;
          },
        },
      };

在登录成功后,通过addRoutes方法动态的添加路由规则,也就是所添加的路由规则只能是在登录以后才能够访问,所以全局守卫的判断条件发生了变化,不在判断是否有元数据,而只是判断是否登录。如果登录了,想访问上面的路由规则,则运行访问,如果没有登录则不允许访问。

注意:对应的原有的路由规则应该注释掉。

完整代码如下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>基于vue-router的案例</title>
    <!-- <script src="./lib/vue_2.5.22.js"></script> -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <!-- <script src="./lib/vue-router_3.0.2.js"></script> -->
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <style type="text/css">
      html,
      body,
      #app {
        margin: 0;
        padding: 0px;
        height: 100%;
      }
      .header {
        height: 50px;
        background-color: #545c64;
        line-height: 50px;
        text-align: center;
        font-size: 24px;
        color: #fff;
      }
      .footer {
        height: 40px;
        line-height: 40px;
        background-color: #888;
        position: absolute;
        bottom: 0;
        width: 100%;
        text-align: center;
        color: #fff;
      }
      .main {
        display: flex;
        position: absolute;
        top: 50px;
        bottom: 40px;
        width: 100%;
      }
      .content {
        flex: 1;
        text-align: center;
        height: 100%;
      }
      .left {
        flex: 0 0 20%;
        background-color: #545c64;
      }
      .left a {
        color: white;
        text-decoration: none;
      }
      .right {
        margin: 5px;
      }
      .btns {
        width: 100%;
        height: 35px;
        line-height: 35px;
        background-color: #f5f5f5;
        text-align: left;
        padding-left: 10px;
        box-sizing: border-box;
      }
      button {
        height: 30px;
        background-color: #ecf5ff;
        border: 1px solid lightskyblue;
        font-size: 12px;
        padding: 0 20px;
      }
      .main-content {
        margin-top: 10px;
      }
      ul {
        margin: 0;
        padding: 0;
        list-style: none;
      }
      ul li {
        height: 45px;
        line-height: 45px;
        background-color: #a0a0a0;
        color: #fff;
        cursor: pointer;
        border-bottom: 1px solid #fff;
      }

      table {
        width: 100%;
        border-collapse: collapse;
      }

      td,
      th {
        border: 1px solid #eee;
        line-height: 35px;
        font-size: 12px;
      }

      th {
        background-color: #ddd;
      }
    </style>
  </head>
  <body>
    <div id="app"><router-view></router-view></div>
    <script>
      const App = {
        template: `<div>
        <!-- 头部区域 -->
        <header class="header">传智后台管理系统</header>
        <!-- 中间主体区域 -->
        <div class="main">
          <!-- 左侧菜单栏 -->
          <div class="content left">
            <ul>
              <li><router-link to="/users"> 用户管理</router-link></li>
              <li><router-link to="/rights"> 权限管理</router-link></li>
              <li><router-link to="/goods"> 商品管理</router-link></li>
              <li><router-link to="/orders"> 订单管理</router-link></li>
              <li><router-link to="/settings"> 系统设置</router-link></li>
            </ul>
          </div>
          <!-- 右侧内容区域 -->
          <div class="content right"><div class="main-content"> <router-view /></div></div>
        </div>
        <!-- 尾部区域 -->
        <footer class="footer">版权信息</footer>
      </div>`,
      };
      const Users = {
        data() {
          return {
            userlist: [
              { id: 1, name: "张三", age: 10 },
              { id: 2, name: "李四", age: 20 },
              { id: 3, name: "王五", age: 30 },
              { id: 4, name: "赵六", age: 40 },
            ],
          };
        },
        methods: {
          goDetail(id) {
            console.log(id);
            this.$router.push("/userinfo/" + id);
          },
        },
        template: `<div>
          <h3>用户管理区域</h3>
          <table>
            <thead>
              <tr><th>编号</th><th>姓名</th><th>年龄</th><th>操作</th></tr>
            </thead>
            <tbody>
              <tr v-for="item in userlist" :key="item.id">
                <td>{{item.id}}</td>
                <td>{{item.name}}</td>
                <td>{{item.age}}</td>
                <td>
                  <a href="javascript:;" @click="goDetail(item.id)">详情</a>
                </td>
              </tr>
            </tbody>
          </table>
        </div>`,
        // beforeRouteEnter(to, from, next) {
        //   if (window.isLogin) {
        //     next();
        //   } else {
        //     next("/login?redirect=" + to.fullPath);
        //   }
        // },
      };
      //用户详情组件
      const UserInfo = {
        props: ["id"],
        template: `<div>
            <h5>用户详情页 --- 用户Id为:{{id}}</h5>
            <button @click="goback()">后退</button>
          </div>`,
        methods: {
          goback() {
            // 实现后退功能
            this.$router.go(-1);
          },
        },
      };

      const Rights = {
        template: `<div>
          <h3>权限管理区域</h3>
        </div>`,
      };
      const Goods = {
        template: `<div>
          <h3>商品管理区域</h3>
        </div>`,
      };
      const Orders = {
        template: `<div>
          <h3>订单管理区域</h3>
        </div>`,
      };
      const Settings = {
        template: `<div>
          <h3>系统设置区域</h3>
        </div>`,
      };
      const Login = {
        data() {
          return {
            isLogin: window.isLogin,
          };
        },

        template: `<div>
            <button @click="login" v-if="!isLogin">登录</button>
            <button @click="logout" v-else>注销</button>
            </div>`,
        methods: {
          login() {
            window.isLogin = true;
            if (this.$route.query.redirect) {
              //动态添加路由:
              this.$router.addRoutes([
                {
                  path: "/",
                  component: App,
                  redirect: "/users",
                  children: [
                    {
                      path: "/users",
                      component: Users,
                      meta: {
                        auth: true,
                      },
                      // beforeEnter(to, from, next) {
                      //   if (window.isLogin) {
                      //     next();
                      //   } else {
                      //     next("/login?redirect=" + to.fullPath);
                      //   }
                      // },
                    },
                    { path: "/userinfo/:id", component: UserInfo, props: true },
                    { path: "/rights", component: Rights },
                    { path: "/goods", component: Goods },
                    { path: "/orders", component: Orders },
                    { path: "/settings", component: Settings },
                  ],
                },
              ]);
              this.$router.push(this.$route.query.redirect);
            } else {
              this.$router.push("/");
            }
          },
          logout() {
            this.isLogin = window.isLogin = false;
          },
        },
      };

      // 创建路由对象
      const router = new VueRouter({
        routes: [
          { path: "/login", component: Login },
          // {
          //   path: "/",
          //   component: App,
          //   redirect: "/users",
          //   children: [
          //     {
          //       path: "/users",
          //       component: Users,
          //       meta: {
          //         auth: true,
          //       },
          //       // beforeEnter(to, from, next) {
          //       //   if (window.isLogin) {
          //       //     next();
          //       //   } else {
          //       //     next("/login?redirect=" + to.fullPath);
          //       //   }
          //       // },
          //     },
          //     { path: "/userinfo/:id", component: UserInfo, props: true },
          //     { path: "/rights", component: Rights },
          //     { path: "/goods", component: Goods },
          //     { path: "/orders", component: Orders },
          //     { path: "/settings", component: Settings },
          //   ],
          // },
        ],
      });
      //实现全局守卫
      // router.beforeEach((to, from, next) => {
      //   //to:去哪个页面,from来自哪个页面,next继续执行.
      //   //判断哪个路由需要进行守卫,这里可以通过元数据方式
      //   if (to.meta.auth) {
      //     if (window.isLogin) {
      //       next();
      //     } else {
      //       next("/login?redirect=" + to.fullPath);
      //     }
      //   } else {
      //     next();
      //   }
      // });

      router.beforeEach((to, from, next) => {
        //to:去哪个页面,from来自哪个页面,next继续执行.
        if (window.isLogin) {
          //用户已经登录
          if (to.path === "/login") {
            // 用户已经登录了,但是又访问登录页面,这里直接跳转到用户列表页面
            next("/");
          } else {
            //用户已经登录,并且访问其它页面,则运行访问
            next();
          }
        } else {
          //用户没有登录,并且访问的就是登录页,则运行访问登录页
          if (to.path === "/login") {
            next();
          } else {
            //用户没有登录,访问其它页面,则跳转到登录页面。
            next("/login?redirect=" + to.fullPath);
          }
        }
      });

      const vm = new Vue({
        el: "#app",
        router,
      });
    </script>
  </body>
</html>

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值