Vue3第三篇之Vue-Router

3,648 阅读4分钟

Vue-router

  • 前置知识,关于hash和history

url的hash和html的history,都是用来实现url变化但是页面不刷新

默认使用的是hash,路径中会带上一个#

1. location.hash

//将当前路径最后一层更新为当前hash值
location.hash = 'test'

image-20210709133258250


2. history

//类似入栈
history.pushState({data},'title',url)
//类似出栈
history.back()
history.go(-1)
//替换操作,不可返回
history.replaceState({data},'title',url)


history.go(数字)
history.go(-1)等同于history.back()
history.go(1)等同于history.forward()

image-20210709134125753

如果不使用默认的hash模式,即不想要那个#号,可以通过更改路由模式来实现

模式有

  • createWebHistory(history路由)
  • createWebHashHistory(hash路由)
  • createMemoryHistroy(带缓存的history路由)`
//vue3的语法
const routes = [{path: , name: , component: }]

const router = createRouter({
  //采用history模式
    history: createWebHistory(),
    routes
})

export default router

image-20210709135755091


一、router-link

常用属性:

  • to

    image-20210711190613944

  • replace

    image-20210711101923609

  • active-class

    image-20210711190738277

  • exact-active-class

    image-20210711191031853

  • aria-current-value

    image-20210711190832771

  • custom

    image-20210711190956362


二、动态路由

在某些情况下,一个页面的path路径可能是不确定的,比如我们进入用户详情页面时,希望带上用户id,如user/userId这种形式,除了固定的路径外,还用上了用户的id,这种pathComponent的匹配关系,我们称之为动态路由,也是路由传递数据的一种方式。

用法router.ts文件中配置动态属性,router-link标签中使用v-bind绑定,vue3中通过routeparams属性来获取具体属性。

image-20210711195219623

注意:嵌套路由使用时,在子组件的path不能加/开始,如上面的user/userId,如果使用了/将会变为基于基本路径,在router-link中需要使用完整路径,如上面的需要使用/test/user/userId


三、默认路由

使用重定向实现默认路由

{
    path: '/',
    redirect: '/login'
 },

四、参数传递

传递参数有paramsquery两种方式

params方式是restful方式的传参

query方式是在url后面拼接?key1=value2@key2=value2

通过route.params.xxxroute.query.xxx来取值,其中route = useRoute()表示当前激活路径

image-20210711211658491


五、导航守卫

Vue-router提供的导航守卫主要用来监听路由的进入和离开,提供了beforeEach和afterEach的钩子函数,他们会在路由即将改变前和改变后触发,说白了,就是用来监听路由跳转的

  • 我们可以在路由中定义一些标题、可以使用meta来定义,在导航守卫中修改标题
  1. 全局前置守卫,使用router.beforeEach()

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

    • from当前当行即将要离开的路由对象

    • next:可选参数,也是一个函数,如果使用了next参数,必须调用该方法后,才能进入到下一个钩子,next()中可以使用参数,如

      //跳转到Login路由
      next({name: 'Login'})
      
      //可以用来进行判断,如果用户登录成功则正常跳转,否则继续登录
      router.beforeEach((to, from, next) => {
        if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
        else next()
      })
      
    • 返回值:

      • false:取消当前导航,url重置为from路由对应的地址
      • 一个路由地址:通过一个路由地址跳转到一个不同的地址

image-20210711220333038

  1. 全局后置钩子,使用router.afterEach()

    与守卫不同,这些钩子不接受next函数,也不会改变导航本身,不过可以接受navigation failures作为第三个参数

  2. 路由独享守卫,在路由配置中定义beforeEnter((to, from) => {})

    可以传入一个函数数组

  3. 组件内守卫

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

完整的导航解析流程

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

六、 keep-alive/transation

transitionkeep-alive 现在必须通过v-slot APIRouterView内部使用:

<router-view v-slot="{ Component }">
  <transition>
    <keep-alive>
      <component :is="Component" />
    </keep-alive>
  </transition>
</router-view>