Vue Router

1、实现原理

前端路由主要有两种实现方法:Hash 路由 和 History 路由

  • hash

url 的 hash 是以 # 开头,原本是用来作为锚点,从而定位到页面的特定区域。当 hash 改变时,页面不会因此刷新,浏览器也不会向服务器发送请求。

http://www.xxx.com/#/home

hash 改变时,并会触发相应的 hashchange 事件。当 hash 路由发生了跳转,便会触发 hashchange 回调,回调里可以实现页面更新的操作,从而达到跳转页面的效果。

window.addEventListener('hashchange', function () {
  console.log('render');
});
  •  history

         HTML5 规范中提供了 history.pushState 和 history.replaceState 来进行路由控制。通过这两个方法,可以实现改变 url 且不向服务器发送请求。路径当中没有了#,更加美观。但是 History 路由需要服务器的支持,并且需将所有的路由重定向到根页面。

改变 url:1.调用 history.pushState 或 history.replaceState;2.点击浏览器的前进与后退。

 

2、基础知识

  • 使用步骤

 1. 定义 (路由) 组件。可以从其他文件 import 进来

const Foo = { template: '
foo
' } const Bar = { template: '
bar
' }

2. 定义路由  。每个路由应该映射一个组件。 其中"component" 可以是通过 Vue.extend() 创建的组件构造器,或者,只是一个组件配置对象。

const routes = [

  { path: '/foo', component: Foo },

  { path: '/bar', component: Bar }

]

 3. 创建 router 实例,然后传 `routes` 配置

const router = new VueRouter({

  routes // (缩写) 相当于 routes: routes

})

 4. 创建和挂载根实例。

const app = new Vue({

  router

}).$mount('#app')

5.使用

aaaa

 

  •  路由的配置项

routes:路由规则配置

mode:模式配置。hash模式,history模式。

  • 嵌套路由    以/开头的会被当作根路径

const router = new VueRouter({

  routes: [

    { path: '/user/:id', component: User,

      children: [

        {

          // 当 /user/:id/profile 匹配成功,

          // UserProfile 会被渲染在 User 的  中

          path: 'profile',

          component: UserProfile

        },

        {

          // 当 /user/:id/posts 匹配成功

          // UserPosts 会被渲染在 User 的  中

          path: 'posts',

          component: UserPosts

        }

      ]

    }

  ]

})
  •  动态路由

const router = new VueRouter({
  routes: [
    // 动态路径参数 以冒号开头
    { path: '/user/:id', component: User }
  ]
})

一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到 this.$route.params,可以在每个组件内使用。这时候增加了一个$route的属性。

$route.params 获取的是路由配置规则中匹配到的路由信息,通常称之为路由参数

this.$route.params.xxx 来拿到匹配的路由值

 

  • 编程式导航

1、router.push(location, onComplete?, onAbort?)

 Vue 实例内部,你可以通过 $router 访问路由实例。因此你可以调用 this.$router.push

2、router.replace(location, onComplete?, onAbort?)

跟 router.push 很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。

3、router.go(n)

这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)

  • 重定向   redirect

    const router = new VueRouter({
        routes: [
    
            { path: '/a', redirect: { name: 'foo' }}
    
        ]
    
    })

    当用户访问 /a时,URL 将会被替换成 /b,然后匹配路由为 /b

  • 别名   alias

const router = new VueRouter({
    routes: [

        { path: '/a', component: A, alias: '/b' }

    ]

})

/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。

3、导航守卫

  • 全局守卫

  1. 全局前置守卫:router.beforeEach
  2. 全局解析守卫:router.beforeResolve
  3. 全局后置钩子:router.afterEach
//全局前置守卫

const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {

    //to: Route: 即将要进入的目标 路由对象

    //from: Route: 当前导航正要离开的路由

    //next: Function: 一定要调用该方法来 resolve 这个钩子
        //next(): 进行管道中的下一个钩子。

        //next(false): 中断当前的导航。

        //next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。

})


//全局后置钩子
router.afterEach((to, from) => {
  
    //这些钩子不会接受 next 函数也不会改变导航本身
})
  • 路由独享守卫

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})
  • 组件内守卫

const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
  },
  beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  }
}
  • 完整的导航解析流程

1.导航被触发。

2.在失活的组件里调用离开守卫。

3.调用全局的 beforeEach 守卫。

4.在重用的组件里调用 beforeRouteUpdate 守卫 。

5.在路由配置里调用 beforeEnter。

6.解析异步路由组件。

7.在被激活的组件里调用 beforeRouteEnter。

8.调用全局的 beforeResolve 守卫 。

9.导航被确认。

10.调用全局的 afterEach 钩子。

11.触发 DOM 更新。

12.用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数

你可能感兴趣的:(Vue Router)