美文网首页
Vue-router之导航守卫

Vue-router之导航守卫

作者: 王童孟 | 来源:发表于2018-09-11 08:42 被阅读0次

导航守卫

全局导航守卫

全局钩子

// client/index.js
router.beforeEach((to, from, next) => { // 跳转前
  console.log('before each invoked')
  next() // next 必须执行,才能跳转
})

router.beforeResolve((to, from, next) => {
  console.log('before resolve invoked')
  next()
})

router.afterEach((to, from) => { // 跳转后,不需要 next
  console.log('after each invoked')
})

beforeEach

进行数据校验,比如验证页面,用户需要登录后才能显示,设置跳转到 login 页面

// client/index.js
router.beforeResolve((to, from, next) => {
  console.log('before resolve invoked')
  if (to.fullPath === '/app') {
    next('/login')  // 或者 next({path: '/login})
  } else {
    next()
  }
})

路由配置中增加钩子

beforeEnter 调用顺序是在 beforeEach 和 beforeResolve 之间。

// client/config/routes.js
export default [
  {
    path: '/app',
    component: Todo,
    beforeEnter (to, from, next) {
      console.log(' app route before enter')
      next()
    }
  }
]

组件内部增加钩子

// todo.vue
export default {
  beforeRouteEnter (to, from, next) {
    console.log('todo before enter')
    next()
  },
  beforeRouteUpdate (to, from, next) {
    console.log('todo update enter')
    next()
  },
  beforeRouteLeave (to, from, next) {
    console.log('todo leave enter')
    next()
  },

点击跳转 login 时

控制台

todo leave enter  组件被离开
before each invoked 新路由进入之前
before resolve invoked
after each invoked

点击跳转 app 时

before each invoked
app route before enter 路由配置的 beforeEnter
todo before enter 组件内的 beforeEnter
before resolve invoked 而beforeResolve 要等全局的 beforeEach、路由配置的 beforeEnter、组件内都触发才出发
after each invoked

同一个组件在不同路由下面显示的情况下 beforeRouteUpdate 才会触发

例如路由传参的情况下,切换路由,组件会进行复用。如果不这样做,需要通过 watch 监听 id。

// routes.js
{
    path: '/app/:id',
    component: Todo
  },
// app.vue
<template>
  <div id="app">
    <div id="cover"></div>
    <router-link to="/app/123">app123</router-link>
    <router-link to="/app/456">app456</router-link>
    <router-link to="/login">login</router-link>
  </div>
</template>
// todo.vue
  beforeRouteEnter (to, from, next) {
    console.log('todo before enter', this)
    next(vm => {
      console.log('after enter vm.id is ', vm.id)
    })
  },
  beforeRouteUpdate (to, from, next) {
    console.log('todo update enter')
    next()
  },
  beforeRouteLeave (to, from, next) {
    console.log('todo leave enter')
    if (global.confirm('are you sure?')) {
      next()
    } else {
    }
  },

路由钩子在组件内部的应用

beforeRouteEnter 和 beforeRouteUpdate 获取数据,当我们进入页面,数据已经渲染好了

beforeRouteEnter (to, from, next) {
    console.log('todo before enter', this)
    next(vm => { 
      console.log('todo enter vm.id is ', vm.id)
    })
  },

beforeRouteLeave 弹出确认框,是否离开

beforeRouteLeave (to, from, next) {
    console.log('todo leave enter')
    if (global.confirm('are you sure?')) {
      next()
    } else {
    }
  },

关于 beforeRouteUpdate

路由参数不同,组件相同时,生命周期是不会触发,导致数据不更新,应该使用 beforeRouteUpdate 或者 watch

命名视图

不同的 router-view 显示不同的组件

// client/app.vue
<template>
  <div id="app">
    <transition name="fade">
      <router-view />
    </transition>
      <router-view name="a"/>
  </div>
</template>
// client/config/routes.js
export default [
  {
    path: '/app',
    components: {
      default: Todo,
      a: Login
    }
  },
  {
    path: '/login',
    components: {
      default: Login,
      a: Todo
    }
  }
]

常见的三栏布局,菜单切换,可以用这种方式,当然传统的 layout 也可以实现。

异步路由(异步加载组件)

当路由非常多时,通过 webpack 一次性打包所有代码,导致 js 文件非常大,初始加载时间非常长。

异步路由:对于不同的路由,只加载对应代码和项目核心代码;而对应页面的代码,访问时再加载。

使用

使用异步路由,只需在对应组件使用 import 引入对应组件即可,这样当我们访问路由时,才会加载。

// import Todo from '../views/todo/todo.vue'
// import Login from '../views/login/login.vue'

export default [
  {
    path: '/app/:id',
    props: 'true',
    component: () => import('../views/todo/todo.vue')
    }
  },
  {
    path: '/login',
    component: () => import('../views/login/login.vue')
  }
]

安装 babel 插件

程序不支持直接在 component 部分写 import,需要安装 babel 插件。

npm i babel-plugin-syntax-dynamic-import -D

// .babelrc
{
  "presets": [
    "env"
  ],
  "plugins": [
    "transform-vue-jsx",
    "syntax-dynamic-import"  // 添加配置
  ]
}

注意

核心代码中不要使用异步加载的组件,这样我们切换路由会没有效果。

相关文章

  • vue导航守卫

    导航守卫:vue-router主要提供跳转或取消的方式守卫导航, 导航守卫分为全局前置守卫、全局解析守卫、全局后置...

  • vue-router的导航守卫之在导航完成后获取数据

    需求:在导航完成之后加载数据。渲染DOM vue-router的导航守卫之导航完成之前获取数据 需求:在导航完成之...

  • vue-router进阶

    导航守卫 vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航(路由发生改变才会守卫)。参数 ...

  • 导航守卫以及keep-alive

    一 什么是导航守卫? vue-router提供的导航守卫主要用来监听监听路由的进入和离开的.vue-router提...

  • 导航守卫

    vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航 全局守卫 全局前置守卫 当一个导航触发时...

  • vue-router导航守卫&&滚动&&路由懒加载

    导航守卫 正如其名,vue-router提供的导航守卫主要用来通过跳转或取消的方式守卫,有多种机会植入路由导航过程...

  • web前端面试题@九(vue导航守卫)

    什么是导航守卫? 正如其名,vue-router提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入...

  • vue-router进阶

    导航守卫 vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。参数或查询的改变并不会触发进入...

  • vue导航守卫

    “导航”表示路由正在发生改变。 正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航...

  • beforeRouteEnter钩子处理页面刷新问题

    vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, ...

网友评论

      本文标题:Vue-router之导航守卫

      本文链接:https://www.haomeiwen.com/subject/xzjygftx.html