Vue-Router 路由守卫导航守卫

by logan70

HTML

<script src="https://cdn.bootcss.com/vue/2.5.17/vue.min.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.0.1/vue-router.min.js"></script>

<div id="app">
  <h1>Vue-Router 导航守卫</h1>
  <h2>请打开控制台查看守卫执行顺序</h2>
  <p>
    <!-- 路由导航,to属性决定导航地址 -->
    <!-- router-link编译后默认渲染为a标签 -->
    <router-link to="/home/1">主页1(Home组件)</router-link>
    <router-link to="/home/2">主页2(Home组件)</router-link>
    <router-link to="/pagea">页面A(PageA组件)</router-link>
  </p>
  <!-- 路由渲染出口 -->
  <router-view></router-view>
</div>

JavaScript

console.log('%c 当匹配路由渲染组件时','background:#222;color:#bada55')
const Home = {
	template: `<div><p>主页(Home组件)</p></div>`,
  created() {
    console.log('组件生命周期:created')
  },
  mounted() {
    console.log('组件生命周期:mounted')
  },
  // 【组件守卫beforeRouteEnter】
  beforeRouteEnter (to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`,可以传一个回调给 next,将组件实例作为参数来访问组件实例
    console.log('组件守卫:beforeRouteEnter')
    next(vm => {
      // vm即为组件实例
      console.log('组件守卫:beforeRouteEnter的next回调')
    })
  },
  // 【组件守卫beforeRouteUpdate】
  beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用,例如动态路由
    // 可以访问组件实例 `this`
		console.log('')
		console.log('%c 当导航更新时(例如动态路由间跳转时)','background:#222;color:#bada55')
    console.log('组件守卫:beforeRouteUpdate')
    next() // 确保要调用 next 方法
  },
  // 【组件守卫beforeRouteLeave】
  beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
		console.log('')
		console.log('%c 当离开路由时(此处为前往其他路由)','background:#222;color:#bada55')
    console.log('组件守卫:beforeRouteLeave')
    next() // 确保要调用 next 方法
  },
}
const PageA = {template: `<div><p>页面A(PageA组件)</p></div>`}


const router = new VueRouter({
  routes : [
    {
    	path: '/home/:id',
      component: Home,
      // 【路由守卫beforeEnter】
      beforeEnter(to, from, next) {
        console.log('路由守卫:beforeEnter')
        // ...
        next() // 确保要调用 next 方法
      }
    },
    {path: '/pagea',component: PageA},
    {path: '/',redirect: '/home/1'}
  ]
})

// 【全局前置守卫beforeEach】
router.beforeEach((to, from, next) => {
  console.log('全局前置守卫:beforeEach')
  // ...
  next() // 确保要调用 next 方法,否则钩子就不会被 resolved
})

// 【全局解析守卫beforeResolve】
router.beforeResolve((to, from, next) => {
  console.log('全局解析守卫:beforeResolve')
  // ...
  next() // 确保要调用 next 方法,否则钩子就不会被 resolved
})

// 【全局后置钩子afterEach】
router.afterEach((to, from) => {
  console.log('全局后置钩子:afterEach')
  // ...
})

window.vueApp = new Vue({
  router
}).$mount('#app')