Vue框架(九)

一、路由守卫

 某商场详情页 => 点击购买

  1.   如果登录了,直接跳转到付款页。
  2.   如果没登录,直接跳转到登录页,登录后直接跳转到付款页。

  如何实现上面的功能?

  可以通过路由守卫实现。

  路由守卫一定会用到的api

  路由守卫也叫路由钩子,路由生命周期 => 路由守卫其实都是在路由跳转的特定阶段触发的函数。

  路由跳转都会经历那些阶段?

  从路由Home跳转到路由News

  路由跳转流程。

  1.   路由触发,准备跳转
  2.   触发Home组件的一个钩子函数,beforeRouteLeave (路由离开前)
  3.   调用全局的 beforeEach(所有路由跳转都会触发的一个钩子) 钩子
  4.   在重用的组件(动态路由组件)里调用 beforeRouteUpdate.(当前路由组件更新时)
  5.   在路由配置里调用 beforeEnter(路由选项独享守卫)
  6.   解析异步路由(路由懒加载)组件。
  7.   在News组件里调用 beforeRouteEnter (当前路由准备进入时)。
  8.   调用全局的 beforeResolve (完成跳转前)。
  9.   导航被确认。(完成路由跳转)
  10.   调用全局的 afterEach 钩子。
  11.   触发 DOM 更新(更新路由组件视图)
  12.   调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

  守卫分类:

  1:全局守卫

  •       beforeEach (很常用):一般用来做一些进入页面的限制。比如没有登录,就不能进入某些页面,只有登录了之后才有权限查看某些页面。。。简单说就是路由拦截。
  •       beforeResolve
  •       afterEach

  2:路由独享守卫

  •       beforeEnter

  3:组件独享守卫

  •       beforeRouteEnter (常用)
  •       beforeRouteUdpate (常用)
  •       beforeRouteLeave (常用)
<body>
  
  <div id='app'></div>
</body>

如何知道路由发生了跳转?
     beforeRouteLeave => 守卫(保安),可以让路由跳转被拦截。

     路由守卫的参数:
     1:to 目标路由的$route对象
     2:from 起始路由的$route对象
     3:next 回调函数,用于拦截路由或者路由传参
        next的参数:
          a:没参数 => 正常跳转
          b:false => 不让跳转
          c:字符串路径 => 重定向
          d:对象 => 重定向时路由传参.
          e:函数 => 跳转的最后节点触发,参数是当前的组件实例.

<script src="js/vue.js"></script>
  <script src="js/vue-router.js"></script>
  <script>

    const Home = {
      template: `
        <div>
          <h3>首页</h3>
        </div>
      `,
      // Home路由跳转到其他路由前触发的钩子守卫.
      beforeRouteLeave(to, from, next) {
        // console.log('准备离开Home');

        // 通过to对象,可以知道目标路由是哪个
        console.log('to', to.path);
        // 通过from对象,可以知道起始路由是哪个.
        console.log('from', from.path);
        // next是一个回调函数
        console.log('next', next);
        // 手动调用next才能正常跳转路由(一定不要忘记)
        next();

        // 参数写false就是跳转失败
        // next(false);
      }
    }

    const News = {
      template: `
        <div>
          <h3>新闻</h3>
        </div>
      `,
      data() {
        return { msg: 'News组件' }
      },
      // 组件进入前的守卫.(别的路由进入News路由时触发)
      // beforeRouteEnter钩子内部能使用this.
      // 这里的this不指向当前的News组件.而是window
      // beforeRouteEnter触发时,组件还没有创建
      beforeRouteEnter(to, from, next) {
        // undefined
        console.log('msg',this.msg);

        // next的参数可以是一个回调函数,在整个路由跳转的最后阶段触发
        // 这个回调函数的参数就是当前的News组件实例.
        // next((vm) => {
        //   console.log('msg', vm.msg)
        // });

        // 进入News前,重定向到sport。
        // next('/sport');

        // 进入News前,重定向到sport,并且传参msg给sport组件
        next({ path: '/sport', query: { msg: 10000 } });
      }
    }

    const Sport = {
      template: `
        <div>
          <h3>体育</h3>
        </div>
      `
    }

    // 实例化路由
    const router = new VueRouter({
      // 路由组件和路由路径的对应关系 => 路由选项
      routes: [
        {
          path: '/home',
          component: Home
        }, {
          path: '/news',
          component: News
        }, {
          path: '/sport',
          component: Sport
        }, {
          // 当你的路径是/时,把路径变成/home
          path: '/',
          // 重定向到home
          redirect: '/home'
        }
      ]
    })

    const App = {
      template: `
        <div>
          <router-link to='/home'>首页</router-link>
          <router-link to='/news'>新闻</router-link>
          <router-link to='/sport'>体育</router-link>
          <router-view />
        </div>
      `
    };

    new Vue({
      render: h => h(App),
      // 挂载路由
      router
    }).$mount('#app');

  </script>

二、组件路由守卫在组件组件中不触发 

<body>
  
  <div id='app'></div>
</body>

beforeRouteLeavebeforeRouteEnter只能在路由组件中触发.
在路由组件的子组件中是不触发的.
什么是路由组件?
routes中配置的组件. 

<script src="js/vue.js"></script>
  <script src="js/vue-router.js"></script>
  <script>

    const box = {
      template: `
        <h3>box子组件</h3>
      `,
      // 这里的leave的组件是不触发的
      beforeRouteLeave(to, from, next) {
        console.log('box的leave')
        next();
      }
    }

    const Home = {
      template: `
        <div>
          <h3>首页</h3>
          <box />
        </div>
      `,
      components: { box },
      beforeRouteLeave(to, from, next) {
        console.log('Home的leave')
        next();
      }
    }

    const News = {
      template: `
        <div>
          <h3>新闻</h3>
        </div>
      `,
    }

    const Sport = {
      template: `
        <div>
          <h3>体育</h3>
        </div>
      `
    }

    // 实例化路由
    const router = new VueRouter({
      // 路由组件和路由路径的对应关系 => 路由选项
      routes: [
        {
          path: '/home',
          component: Home
        }, {
          path: '/news',
          component: News
        }, {
          path: '/sport',
          component: Sport
        }, {
          // 当你的路径是/时,把路径变成/home
          path: '/',
          // 重定向到home
          redirect: '/home'
        }
      ]
    })

    const App = {
      template: `
        <div>
          <router-link to='/home'>首页</router-link>
          <router-link to='/news'>新闻</router-link>
          <router-link to='/sport'>体育</router-link>
          <router-view />
        </div>
      `
    };

    new Vue({
      render: h => h(App),
      // 挂载路由
      router
    }).$mount('#app');

  </script>

三、beforeRouteUpdate 

<body>
  
  <div id='app'></div>
</body>

动态路由间的切换时不会触发beforeRouteLeave和beforeRouteEnter
动态路由切换,可以通过beforeRouteUpdate来监测.
同样的.beforeRouteUpdate在路由组件的子组件中也不触发. 

<script src="js/vue.js"></script>
  <script src="js/vue-router.js"></script>
  <script>   

    const box = {
      template: `
        <h3>box子组件</h3>
      `,
      // 这里的leave的组件是不触发的
      beforeRouteUpdate(to, from, next) {
        console.log('box的Update')
        next();
      }
    }

    const Home = {
      template: `
        <div>
          <h3>首页--{{$route.path}}</h3>
          <box />
        </div>
      `,
      components: { box },
      // 动态路由中不触发beforeRouteLeave
      beforeRouteLeave(to, from, next) {
        console.log('Home的leave')
        next();
      },
      // 动态路由切换时触发.
      beforeRouteUpdate(to, from, next) {
        console.log(from.params.path + '到' + to.params.path);
        next();
      }
    }

    // 实例化路由
    const router = new VueRouter({
      routes: [
        {
          path: '/:path',
          component: Home
        }, {
          path: '/',
          redirect: '/home'
        }
      ]
    })

    const App = {
      template: `
        <div>
          <router-link to='/home'>首页</router-link>
          <router-link to='/news'>新闻</router-link>
          <router-link to='/sport'>体育</router-link>
          <router-view />
        </div>
      `
    };

    new Vue({
      render: h => h(App),
      // 挂载路由
      router
    }).$mount('#app');

  </script>

四、动态路由的路由守卫 

<body>
  
  <div id='app'></div>
</body>

从非动态路由跳转到动态路由,会触发动态路由内的Enter.
从动态路由跳转到非动态路由,会触发动态路由内的Leave.

<script src="js/vue.js"></script>
  <script src="js/vue-router.js"></script>
  <script>    

    const Login = {
      template: `
        <div>
          <input type='text' />
          <button @click='$router.push("/home")'>登录</button>
        </div>
      `
    }

    const Home = {
      template: `
        <div>
          <h3>首页--{{$route.path}}</h3>
        </div>
      `,
      // 动态路由中不触发beforeRouteLeave
      beforeRouteEnter(to, from, next) {
        console.log('Home的Enter')
        next();
      },
      // 动态路由切换时触发.
      beforeRouteUpdate(to, from, next) {
        console.log(from.params.path + '到' + to.params.path);
        next();
      }
    }

    // 实例化路由
    const router = new VueRouter({
      routes: [
        {
          path: '/login',
          component: Login
        }, {
          path: '/:path',
          component: Home
        }, {
          path: '/',
          redirect: '/login'
        }
      ]
    })

    const App = {
      template: `
        <div>
          <router-link to='/home'>首页</router-link>
          <router-link to='/news'>新闻</router-link>
          <router-link to='/sport'>体育</router-link>
          <router-view />
        </div>
      `
    };

    new Vue({
      render: h => h(App),
      // 挂载路由
      router
    }).$mount('#app');

  </script>

五、全局守卫 

<body>
  
  <div id='app'></div>
</body>

<script src="js/vue.js"></script>
  <script src="js/vue-router.js"></script>
  <script>

    const Home = {
      template: `
        <div>
          <h3>首页</h3>
        </div>
      `,
      // beforeRouteEnter(to, from, next) {
      //   console.log('进入' + to.path + '组件');
      //   next();
      // }
    }

    const News = {
      template: `
        <div>
          <h3>新闻</h3>
        </div>
      `,
      // beforeRouteEnter(to, from, next) {
      //   console.log('进入' + to.path + '组件');
      //   next();
      // }
    }

    const Sport = {
      template: `
        <div>
          <h3>体育</h3>
        </div>
      `,
      // beforeRouteEnter(to, from, next) {
      //   console.log('进入' + to.path + '组件');
      //   next();
      // }
    }

    // 实例化路由
    const router = new VueRouter({
      // 路由组件和路由路径的对应关系 => 路由选项
      routes: [
        {
          path: '/home',
          component: Home
        }, {
          path: '/news',
          component: News
        }, {
          path: '/sport',
          component: Sport
        }, {
          // 当你的路径是/时,把路径变成/home
          path: '/',
          // 重定向到home
          redirect: '/home'
        }
      ]
    });

    // 全局守卫,所有的路由跳转都会触发这个钩子.
    // beforeEach相对于是全局的beforeRouteEnter(没有全局的Leave守卫)
    router.beforeEach((to, from, next) => {
      console.log('进入' + to.path + '组件');
      next();
    });

    const App = {
      template: `
        <div>
          <router-link to='/home'>首页</router-link>
          <router-link to='/news'>新闻</router-link>
          <router-link to='/sport'>体育</router-link>
          <router-view />
        </div>
      `
    };

    new Vue({
      render: h => h(App),
      // 挂载路由
      router
    }).$mount('#app');

  </script>

六、登录的守卫逻辑 

<body>
  
  <div id='app'></div>
</body>

 一个App应用
     1:有写页面需要登录,有些页面不需要登录.
     2:跳转到需要登录的页面时,先检测你是不是已经登录了,如果没有登录直接跳转到登录页.,如果登录了,直接跳转.

<script src="js/vue.js"></script>
  <script src="js/vue-router.js"></script>
  <script>

    // 默认没有登录.
    let isLogin = false;

    const Login = {
      template: `
        <div>
          <input type='text' />
          <button @click='toPage'>登录</button>
        </div>
      `,
      props: ['name'],
      methods: {
        toPage() {
          // 切换登录状态
          isLogin = true;
          // 跳转到指定路由.
          this.$router.push({ name: this.name })
        }
      }
    }

    const Home = {
      template: `
        <div>
          <slot />
          <h3>首页</h3>
        </div>
      `,
    }

    const News = {
      template: `
        <div>
          <slot />
          <h3>新闻</h3>
        </div>
      `,
    }

    const Sport = {
      template: `
        <div>
          <slot />
          <h3>体育</h3>
        </div>
      `,
    }

    // 实例化路由
    const router = new VueRouter({
      // 路由组件和路由路径的对应关系 => 路由选项
      routes: [
        {
          path: '/home',
          component: Home,
          name: 'home',
          meta: {
            // 不需要登录
            authLogin: false
          }
        }, {
          path: '/news',
          component: News,
          name: 'news',
          meta: {
            authLogin: true
          }
        }, {
          path: '/sport',
          component: Sport,
          name: 'sport',
          meta: {
            authLogin: true
          }
        }, {
          path: '/login',
          component: Login,
          name: 'login',
          meta: {
            authLogin: false
          },
          props: true
        },{
          path: '/',
          redirect: '/home'
        }
      ]
    });

    // 全局守卫处理 登录逻辑
    router.beforeEach((to, from, next) => {
      if (to.meta.authLogin) {
        if (!isLogin) {
          // 重定向,并且传递目标路由的name
          next({ name: 'login', params: { name: to.name }})
        } else {
          next()
        }
      } else {
        next()
      }
    });

    const App = {
      template: `
        <div>
          <router-view>
            <router-link to='/home'>首页</router-link>
            <router-link to='/news'>新闻</router-link>
            <router-link to='/sport'>体育</router-link>
          </router-view>
        </div>
      `
    };

    new Vue({
      render: h => h(App),
      // 挂载路由
      router
    }).$mount('#app');

  </script>

七、路由独享守卫 

<body>
  
  <div id='app'></div>
</body>
<script src="js/vue.js"></script>
  <script src="js/vue-router.js"></script>
  <script>

    const Home = {
      template: `
        <div>
          <h3>首页</h3>
        </div>
      `
    }

    const News = {
      template: `
        <div>
          <h3>新闻</h3>
        </div>
      `,
      data() {
        return { msg: 'News组件' }
      }
    }

    const Sport = {
      template: `
        <div>
          <h3>体育</h3>
        </div>
      `
    }

    // 实例化路由
    const router = new VueRouter({
      // 路由组件和路由路径的对应关系 => 路由选项
      routes: [
        {
          path: '/home',
          component: Home
        }, {
          path: '/news',
          component: News,
          // News选项独享的守卫,写在这里和写在组件中的效果一致.
          // 这里没办法通过next的回调获取组件实例.
          beforeEnter(to, from, next) {
            console.log('Enter');
            next();
          }
        }, {
          path: '/sport',
          component: Sport
        }, {
          // 当你的路径是/时,把路径变成/home
          path: '/',
          // 重定向到home
          redirect: '/home'
        }
      ]
    })

    const App = {
      template: `
        <div>
          <router-link to='/home'>首页</router-link>
          <router-link to='/news'>新闻</router-link>
          <router-link to='/sport'>体育</router-link>
          <router-view />
        </div>
      `
    };

    new Vue({
      render: h => h(App),
      // 挂载路由
      router
    }).$mount('#app');

  </script>

八、一个路径对应多个路由视图 

<body>
  
  <div id='app'></div>
</body>

<script src="js/vue.js"></script>
  <script src="js/vue-router.js"></script>
  <script>

    const Home = {
      template: `
        <div>
          <h3>首页</h3>
        </div>
      `,
      name: 'Home'
    }

    const box = {
      template: `
        <div>
          <h3>box组件</h3>
        </div>
      `,
      name: 'box'
    }

    const News = {
      template: `
        <div>
          <h3>新闻</h3>
        </div>
      `
    }

    const Sport = {
      template: `
        <div>
          <h3>体育</h3>
        </div>
      `
    }

    // 实例化路由
    const router = new VueRouter({
      routes: [
        {
          path: '/home',
          components: { Home, box },
          // 对于选项的contents有意义
          beforeEnter(to, from, next ) {
            console.log('home和box的Enter')
            next();
          }
        }, {
          path: '/news',
          component: News,
        }, {
          path: '/sport',
          component: Sport
        }, {
          path: '/',
          redirect: '/home'
        }
      ]
    })

    const App = {
      template: `
        <div>
          <router-link to='/home'>首页</router-link>
          <router-link to='/news'>新闻</router-link>
          <router-link to='/sport'>体育</router-link>
          <router-view name='Home' />
          <router-view name='box' />
          <router-view />
        </div>
      `
    };

    new Vue({
      render: h => h(App),
      // 挂载路由
      router
    }).$mount('#app');

  </script>

九、如何监听路由跳转 

<body>
  
  <div id='app'></div>
</body>

 如何在路由跳转时实现一些额外的逻辑?
     如何监听路由的跳转?
     1:不缓存组件的情况
        a: created和mounted中监听.
        b: watch监听$route变化(任意组件中都可以使用)
        c: 路由守卫监听.(只能在路由组件中使用)
     2:缓存的组件.
        a: watch监听$route变化
        b: ativated和deactivated.(路由组件和路由组件的子组件都可以触发)
        c: 路由守卫监听.(只能在路由组件中使用)
     3:动态路由
        a: watch监听$route变化
        b: beforeRouteUpdate守卫监听.

<script src="js/vue.js"></script>
  <script src="js/vue-router.js"></script>
  <script> 

    const Home = {
      template: `
        <div>
          <h3>首页</h3>
        </div>
      `,
      created() {
        console.log('Home组件切换11');
      },
      watch: {
        // 每次路由发生跳转,路径都会改变,路径改变$route内的属性就会变,从而触发watch
        '$route': {
          immediate: true,
          handler() {
            console.log('Home组件切换22');
          }
        }
      },
      beforeRouteEnter(to, from, next) {
        console.log('Home组件切换33');
        next();
      }
    }

    const News = {
      template: `
        <div>
          <h3>新闻</h3>
        </div>
      `,
      data() {
        return { msg: 'News组件' }
      }
    }

    const Sport = {
      template: `
        <div>
          <h3>体育</h3>
        </div>
      `
    }

    // 实例化路由
    const router = new VueRouter({
      // 路由组件和路由路径的对应关系 => 路由选项
      routes: [
        {
          path: '/home',
          component: Home
        }, {
          path: '/news',
          component: News
        }, {
          path: '/sport',
          component: Sport
        }, {
          path: '/',
          redirect: '/home'
        }
      ]
    })

    const App = {
      template: `
        <div>
          <router-link to='/home'>首页</router-link>
          <router-link to='/news'>新闻</router-link>
          <router-link to='/sport'>体育</router-link>
          <router-view />
        </div>
      `,
      watch: {
        $route: {
          immediate: true,
          handler() {
            console.log('路由切换了')
          }
        }
      }
    };

    new Vue({
      render: h => h(App),
      // 挂载路由
      router
    }).$mount('#app');

  </script>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java Vue框架是指使用Java语言和Vue.js框架来开发Web应用程序的一种技术架构。Java是一种跨平台的编程语言,具有强大的面向对象特性和丰富的生态系统,被广泛应用于企业级应用程序开发。而Vue.js是一种轻量级的JavaScript框架,用于构建用户界面,具有简洁的语法和灵活的组件化开发模式。 Java Vue框架的优势在于它能够充分发挥Java的后端能力和Vue.js的前端特性。Java作为后端语言,可以处理各种复杂的业务逻辑和数据处理,同时提供了可靠的安全性和性能。而Vue.js作为前端框架,能够提供丰富的用户界面和良好的用户体验,支持响应式设计和组件化开发。 使用Java Vue框架可以迅速构建现代化的Web应用程序。Java提供了强大的后端支持,包括数据库访问、事务处理、安全认证等功能。Vue.js提供了灵活的前端组件化开发模式,可以构建出复杂的用户界面,并实现前后端数据的无缝交互。这使得开发人员可以按照自己的需求,选择合适的组件和技术,快速构建出高质量的Web应用程序。 此外,Java Vue框架也具有良好的可维护性和扩展性。Java的面向对象特性使得代码可以更加模块化和可复用,便于团队协作和项目管理。Vue.js的组件化开发模式使得前端代码可以更好地组织和维护,而且可以根据需求进行灵活的扩展和定制。 综上所述,Java Vue框架结合了Java的后端能力和Vue.js的前端特性,可以快速构建现代化的Web应用程序,具有良好的可维护性和扩展性。这使得Java Vue框架成为开发人员的首选技术之一。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值