一、导航守卫
残缺的导航解析流程:

  1. 导航被触发
  2. 在失活的组件里调用beforeRouteLeave
  3. 调用全局的beforeEach
  4. 在重用的组件里调用beforeRouteUpdate
  5. 在路由配置里调用beforeEnter
  6. 解析异步路由组件
  7. 在被激活的组件里调用beforeRouteEnter
  8. 调用全局的beforeResolve
  9. 导航被确认
  10. 调用全局的afterEach
  11. 触发DOM更新
  12. 调用beforeRouteEnter守卫中传给next的回调函数,创立好的组件实例会作为回调函数的参数传入。

参数或查问的扭转并不会触发进入/来到的导航守卫。能够通过观察$route对象来应答这些变动,或应用beforeRouteUpdate的组件内守卫。
1、全局前置守卫
router.beforeEach

const router = new VueRouter({...})router.beforeEach(to,from,next) => {  /*to:Route--行将要进入的指标路由对象*/  /*from:Route--以后导航正要来到的路由*/  /*next:function--必须要调用该办法来resolve这个钩子。执行成果依赖next办法的调用参数。*/  next()  /*进行管道中的下一个钩子,若全副执行完了,则导航的状态就是confirmed。*/  next(false)  /*中断以后的导航。如果浏览器的url扭转了(可能是用户手动或浏览器后退),那么url会重置到from路由对应的地址。*/  next('/')  /*同下*/  next({path:'/'})  /*跳转到一个不同的地址。*/  next(error)  /*导航被终止,且谬误会传递给router.onError()注册过的回调。*/}

确保next函数在任何给定的导航守卫中都被严格调用一次。可呈现多于一次,但只能在所有的逻辑门路都不重叠的状况下,否则钩子永远都不会被解析或报错。

/* BAD */router.beforeEach((to, from, next) => {  if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })  /*如果用户未能验证身份,则 `next` 会被调用两次*/  next()})/* GOOD */router.beforeEach((to, from, next) => {  if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })  else next()})

2、全局解析守卫
router.beforeResolve--与router.beforeEachj相似,区别为:在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。
3、全局后置钩子
router.afterEach()--无next(),也不会扭转导航自身

router.afterEach(to,from)=>{  //...}

路由配置形式:
1、路由独享的守卫--间接在路由配置上定义beforeEnter守卫

const router = new VueRouter({  routes: [    {      path: '/user',      component: User,      beforeEnter: (to,from,next)=>{}    }  ]})

2、组件内的守卫
能够在路由组件内间接定义以下路由导航守卫
beforeRouteEnter
beforeRouteUpdate
beforeRouteLeave

const Foo = {  template: `...`,  beforeRouteEnter(to, from, next) {    /* 在渲染该组件的对应路由被 confirm 前调用*/    /*不能!获取组件实例 `this`*/    /*因为当守卫执行前,组件实例还没被创立,能够通过传一个回调给next来拜访组件实例,仅该守卫反对此办法*/    next(vm => {      /*通过vm拜访组件实例*/    })    },  beforeRouteUpdate(to, from, next) {    /* 在以后路由扭转,然而该组件被复用时调用*/    /* 举例来说,对于一个带有动静参数的门路 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候*/    /* 因为会渲染同样的 Foo 组件,因而组件实例会被复用。而这个钩子就会在这个状况下被调用。*/    /* 能够拜访组件实例 `this`*/    this.name = to.params.name    next()  },  beforeRouteLeave(to, from, next) {    /* 导航来到该组件的对应路由时调用*/    /* 能够拜访组件实例 `this`*/    /*该守卫能够用来禁止用户在还未保留批改前忽然来到,导航能够通过next(false)勾销*/    const answer = window.confirm('还没有保留,确定要来到吗')    if(answer){      next()    }else{      next(false)    }  }}

二、路由元信息-meta

路由登录拦挡

/*1、在须要做登录验证的路由中设置meta*/requireAuth值为trueconst router = new VueRouter({  routes = [    {      path: '/detail',      name: 'detail',      component: Detail,      meta: {        requireAuth: true      }    },    {      path: '/login',      name: 'login',      component: Login    }  ]})/*2、router.beforeEach()钩子函数,会在进入每个网页之前被调用,可在该钩子函数内做路由拦挡*/router.beforeEach((to,from,next) => {  /*判断将进入的路由是否须要路由拦挡*/  if(to.matched.some(record => record.meta.requireAuth){    /*vuex.state判断token是否存在*/    if(store.state.token){      /*已登录*/      next()    }else{      next({        path: '/login',        query: {redirect: to.fullPath}      })    }  } else {    next()  }})

三、过渡动效
应用<transition>标签将<router-view>标签包裹能够增加一些过渡成果,会给在这个router-view中的路由都加上同一种成果。
若想给不同的路由加不同的成果,能够在路由组件中设置<transition>增加成果

const Foo = {  template: `    <transition name="slide">      <div class="foo">...</div>    </transition>  `}const Bar = {  template: `    <transition name="fade">      <div class="bar">...</div>    </transition>  `}

设置动静过渡

<!-- 应用动静的 transition name --><transition :name="transitionName">  <router-view></router-view></transition>//...// 接着在父组件内// watch $route 决定应用哪种过渡watch: {  '$route' (to, from) {    const toDepth = to.path.split('/').length    const fromDepth = from.path.split('/').length    this.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left'  }}

四、数据获取
在进入某个路由后,须要从服务器获取数据,有两种形式:
1、导航实现之后获取:
在路由组件的created钩子函数中调用获取数据的办法

export default{  data (){    return {      loading: false    }  },  created(){    //组件创立实现后获取数据,此时data曾经被observed了    this.fetchData()  },  methods: {    fetchData() {      this.loading = true      //发动数据申请,此时能够通过$route.params获取url上的数据      getPost(this.$route.params.id,(res)=>{        //...      })    }  }}

2、在导航前获取数据
在要跳转的路由组件中的beforeRouteEnter守卫中获取数据,当数据获取胜利后只调用next()办法。

export default {  data () {    return {      post: null,      error: null    }  },  beforeRouteEnter (to, from, next) {    getPost(to.params.id, (err, post) => {      next(vm => vm.setData(err, post))    })  },  // 路由扭转前,组件就曾经渲染完了  // 逻辑稍稍不同  beforeRouteUpdate (to, from, next) {    this.post = null    getPost(to.params.id, (err, post) => {      this.setData(err, post)      next()    })  },  methods: {    setData (err, post) {      if (err) {        this.error = err.toString()      } else {        this.post = post      }    }  }}

五、滚动行为
当切换到新路由时,页面滚动到顶部或放弃原先的滚动地位,能够在router实例中提供一个scrollBehavior办法。

const router = new VueRouter({  routes: [...],  scrollBehavior(to,from,savedPosition){    //return 冀望滚动到的地位    //return {x: number, y: number}    //滚动到顶部    //return {x:0,y:0}        //savedPosition在按下后退和后退按钮时可用    if(savedPosition) {      return savedPosition    } else {      return {x:0,y:0}    }  }})

模仿滚动到锚点

scrollBehavior(to,from,savedPosition){  if(to.hash) {    return {      selector: to.hash,      //设置平滑滚动      behavior: 'smooth'    }  }}

六、路由懒加载
为进步加载效率,应用懒加载,让路由被拜访时才加载对应组件。需联合Vue异步组件和webpack

//1、将异步组件定义为返回一个promise的工厂函数。const Foo = ()=>{  Promise.resolve({    //组件定义对象  })}//2、应用import引入组件import('./Foo.vue')  //import返回一个promise//可联合两者const Foo = ()=> import('./Foo.vue')//路由在实例化时跟一般的一样