Vue Router 是 Vue 生态系统的一部分,是一个获得 MIT 许可的开源项目。vue-router4.x适用于vue3.x版本,在vue-router3.x的基础上添加了一些改动和新增,接下来看看vue-router4.x的使用教程吧
安装
使用createRouter替换new Router()
- 以前版本写法
// router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import routes from './routes'
Vue.use(Router)
const router = new Router({
routes
})
export default router
// main.js
import Vue from 'vue'
import router from './router'
// ...
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
vue-router 4.x版本写法
// router/index.js
import { createRouter } from 'vue-router'
import routes from './routes'
const router = createRouter({
routes
})
// main.js
import { createApp } from 'vue'
import router from './router'
const app = createApp(App)
app.use(router)
app.mount('#app')
所有导航都是异步的,如果使用transition,需要在安装应用程序之前等待路由器准备就绪
app.use(router)
// router.onReady() 已经替换为 router.isReady()
// 不带任何参数并返回 Promise
router.isReady().then(() => app.mount('#app'))
mode修改
mode: 'history'选项已替换为更灵活的名称history
| vue-router 3.x | vue-router 4.x |
|---|---|
| history | createWebHistory() |
| hash | createWebHashHistory() |
| abstract | createMemoryHistory() |
base选项移除,修改为createWebHistory等方法的第一个参数传递
// 原写法
import Vue from 'vue'
import Router from 'vue-router'
import routes from './routes'
Vue.use(Router)
const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
// 新写法
import { createRouter, createWebHistory } from 'vue-router'
import routes from './routes'
const router = createRouter({
// history: createWebHistory(),
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
- 在
SSR中,需要手动传递适当的history
let history = isServer ? createMemoryHistory() : createWebHistory()
let router = createRouter({ routes, history })
// somewhere in your server-entry.js
router.push(req.url) // request url
router.isReady().then(() => {
// resolve the request
})
Composition API
useRouter、useRoute
// 返回 name 是 About 的路由
// 不存在会报错
console.log(router.resolve({ name: 'About' }))
watch(
() => route.params,
async newParams => {
userData.value = await fetchUser(newParams.id)
}
)
function pushWithQuery(query) {
router.push({
name: 'search',
query: {
...route.query
}
})
}
return {
pushWithQuery,
userData
}
}
}
onBeforeRouteLeave、onBeforeRouteUpdate
import { ref } from 'vue'
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
async function fetchUser(id) {}
export default {
setup() {
const userData = ref()
onBeforeRouteLeave((to, from) => {
const answer = window.confirm(
'Do you really want to leave? you have unsaved changes!'
)
if (!answer) return false
})
onBeforeRouteUpdate(async (to, from) => {
if (to.params.id !== from.params.id) {
userData.value = await fetchUser(to.params.id)
}
})
return {
userData
}
}
}
动态路由
router.addRoute(route: RouteRecord):动态添加路由router.removeRoute(name: string | symbol):动态删除路由router.hasRoute(name: string | symbol): 判断路由是否存在router.getRoutes(): 获取路由列表 每当删除路由时,其所有别名和后代路由都会随之删除
router.addRoute({ path: '/about', name: 'about', component: About })
// name 应该是唯一的。会先删除原路由再添加新路由
router.addRoute({ path: '/other', name: 'about', component: Other })
const removeRoute = router.addRoute(routeRecord)
// 删除添加的路由
removeRoute()
router.addRoute({ path: '/about', name: 'about', component: About })
// 添加的时候有name的话,可以直接使用删除对应name的路由
router.removeRoute('about')
// 嵌套路由
router.addRoute({ name: 'admin', path: '/admin', component: Admin })
// 第一个参数admin是父路由的名称
router.addRoute('admin', { path: 'settings', component: AdminSettings })
const routeRecords = router.getRoutes()
导航守卫
通常用于检查用户是否有权限访问某个页面,验证动态路由参数,或者销毁监听器
自定义逻辑运行后,next 回调用于确认路由、声明错误或重定向
vue-router 4.x中可以从钩子中返回一个值或Promise来代替
返回值:
false:取消当前导航。如果浏览器URL被更改(由用户手动或通过后退按钮更改),它将被重置为该from路由的URL
一个router location:重定向到不同的位置,通过传递,如果你是调用路径位置router.push(),它允许您通过类似的选项replace: true或name: 'home'。删除当前导航,并使用导航创建新导航from
什么也不返回,undefined或者true返回任何内容,则导航被验证,并调用下一个
引发异常:取消导航并调用回调router.onError()
// 原写法
router.beforeEach((to, from, next) => {
if (!isAuthenticated) {
next(false)
} else {
next()
}
})
// 新写法
router.beforeEach(() => isAuthenticated)
router-view、keep-alive、transition
transition和keep-alive必须放在router-view里面
<router-view v-slot="{ Component }">
<transition>
<keep-alive>
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
新东西和前后对比大概就这些,有什么不足欢迎指正,后面将进行vue-router4.x源码的解析