# Router路由

router路由的基础内容基本都和vue2的一样,只是在setup中使用的方式不同。

# 创建路由实例

// router/index.ts
import { createRouter, createWebHistory } from 'vue-router'

const HomeComponent = () => import(/* webpackChunkName: 'home' */ '../views/home/index.vue')
const MineComponent = () => import(/* webpackChunkName: 'mine' */ '../views/mine/index.vue')

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'Home',
      component: HomeComponent,
      meta: { title: '主页', icon: 'favorites', keepAlive: false, isAuth: true, permission: 'home' }
    },
    {
      path: '/mine',
      name: 'Mine',
      component: MineComponent,
      meta: { title: '我的', icon: 'mine', keepAlive: false, isAuth: true, permission: 'mine' }
    }
  ]
})

export default router

在main.ts中引入

import { createApp } from 'vue'

import App from './App.vue'
import router from './router'
import store from './stores'


const app = createApp(App)

app.use(store)
app.use(router)

app.mount('#app')

# 在setup中使用

setup 里面没有访问 this,所以我们不能再直接访问 this.$routerthis.$route。作为替代,我们使用 useRouteruseRoute 函数


<script setup>
import { watch } from 'vue'
import { useRouter, useRoute } from 'vue-router'

const router = useRouter()
const route = useRoute()

const pushWithQuery = (id) => {
  router.push({
    name: 'search',
    query: {
      id
    }
  })
}

// 监听路由
watch(() => route.params.id, (newVal, oldVal) => {
    console.log(newVal)
    console.log(oldVal)
  }
)

</script>
<template>
  <div>当前路由信息: {{ route }}</div>
</template>

# 导航守卫

<script setup>
import { ref } from 'vue'
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'

// 与 beforeRouteLeave 相同,无法访问 `this`
onBeforeRouteLeave((to, from) => {
  const answer = window.confirm(
    'Do you really want to leave? you have unsaved changes!'
  )
  // 取消导航并停留在同一页面上
  if (!answer) return false
})

const userData = ref()

// 与 beforeRouteUpdate 相同,无法访问 `this`
onBeforeRouteUpdate(async (to, from) => {
  //仅当 id 更改时才获取用户,例如仅 query 或 hash 值已更改
  if (to.params.id !== from.params.id) {
    userData.value = await fetchUser(to.params.id)
  }
})
</script>

# 动态路由

有时候路由不是设定不变的,就像路由权限一样,要根据角色动态设置和删除路由,我们可以使用router.addRoute()router.removeRoute()进行添加和删除路由。

添加路由

router.addRoute()添加路由,它只注册一个新的路由,添加好后并不会直接跳过去,要使用router.push()router.replace() 来手动导航,才能显示该新路由。

router.addRoute({ path: '/about', component: About })
router.replace(router.currentRoute.value.fullPath)

// 如果你需要等待新的路由显示,可以使用 await router.replace()

删除路由

1、通过添加一个名称冲突的路由。如果添加与现有途径名称相同的途径,会先删除路由,再添加路由:

router.addRoute({ path: '/about', name: 'about', component: About })
// 这将会删除之前已经添加的路由,因为他们具有相同的名字且名字必须是唯一的
router.addRoute({ path: '/other', name: 'about', component: Other })

2、通过调用 router.addRoute() 返回的回调:

const removeRoute = router.addRoute(routeRecord)
removeRoute() // 删除路由如果存在的话

// 当路由没有名称时,这很有用。

3、通过使用 router.removeRoute() 按名称删除路由:

router.addRoute({ path: '/about', name: 'about', component: About })
// 删除路由
router.removeRoute('about')
// 需要注意的是,如果你想使用这个功能,但又想避免名字的冲突,可以在路由中使用 Symbol 作为名字。

当路由被删除时,所有的别名和子路由也会被同时删除

添加嵌套路由

router.addRoute({ name: 'admin', path: '/admin', component: Admin })
router.addRoute('admin', { path: 'settings', component: AdminSettings })

查看现有路由

// 检查路由是否存在
router.hasRoute()
// 获取一个包含所有路由记录的数组
router.getRoutes()

# 在组件外使用

在非vue组件的地方使用router,如在permission.js中使用路由导航守卫来。