Vue Router 章节系列传送门
第一章:初始 Vue Router @3.x 搭建配置项
第二章:Vue Router 路由间的通讯参数传递!
第三章:路由导航守卫!
第四章:本章节内容
前言
随着 Vue3 的迭代升级,其围绕在身边的 生态库也迎来了更新迭代。在过去 Vue Router @3.x 版本,主要是作用于 Vue2 的生态支持,现在为了适应 Vue3 的生态支持, Vue Router 也迎来了@ 4.x 版本的迭代升级, 相较于 @3.x 版本, @4.x 版本的 核心部分 API 并没有多大改变,但任然带来了一些新特性
的支持!本章节 就将主要为大家 讲解 Vue Router @4.x 的新特征,以及如何在 Vue3 中 去配置使用它。
1. 什么是 Vue Router ?
Vue Router 是 Vue.js 的官方路由。主要作用于为 构建 单页应用 (SPA)开发而服务, 它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用 (SPA) 变得轻而易举。主要功能包括:
- 嵌套路由映射
- 动态路由选择
- 模块化、基于组件的路由配置
- 路由参数、查询、通配符
- 展示由 Vue.js 的过渡系统提供的过渡效果
- 细致的导航控制
- 自动激活 CSS 类的链接
- HTML5 history 模式或 hash 模式
- 可定制的滚动行为
- URL 的正确编码
2. 安装 Vue Router
npm install vue-router@4 //可指定 具体版本号。
//#######
yarn add vue-router@4
备注:本文目前 vue-router 是 4.1.6 版本
2.1 挂载实例
对比 Vue Router @3.x 中实例化
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const router = new VueRouter({
mode: "history", //hash abstract
routes:[], //router list
})
export default router
现在Vue Router 在实例化构造时,将不再是一个类,而是一组函数。现在你不用再写 new Router(),而是需要调用 createRouter 函数
import { createRouter, createWebHashHistory, createWebHistory, createMemoryHistory } from "vue-router" // API 集中式 管理,
const router = createRouter({ //createRouter 相当于是vue2中 的 new Vue
history: createWebHistory(), //createWebHashHistory ,v3文档 API里有 ,将模式修改 ,Vue2中是mode :history
routes: [], //router list
})
export default router
新的 history 配置取代 mode
在 Vue Router @3.x 中 路由 的模式需要通过一个 mode 字段 来定义,现在 @4.x 版本中 mode 已经被一个更灵活的 history 配置所取代。参数也不再是 一个 String 字符串了,它将根据你使用的模式,选用适当的函数替换它:
- “history”:
createWebHistory()
- “hash”:
createWebHashHistory()
- “abstract”:
createMemoryHistory()
main.js 中 挂载
import { createApp } from 'vue';
import router from './router/index';
import App from './App.vue'
const app = createApp(App)
app.use(router); //通过Use 挂载
app.mount('#app')
3. 新特征!
3.1. 动态路由: addRoute
addRoute 常作用于 权限控制时 动态追加路由
router.addRoute("home", {
path: "detailed",
name: "detailed",
component: () => import('./component/detailed.vue')
})
当接受两个参数时 第一个参数为父级路由 name 的字符串,第二个为要添加的路由记录的对象
如果只接收一个参数时,参数就只是要添加的路由记录对象。默认添加在根层级
router.addRoute({
path: "/detailed",
name: "detailed",
component: () => import('./component/detailed.vue')
})
注意:
:如果所添加的新路由 name 和之前已存在的路由 name 重名了的话,它会先删除之前的路由。
3.2 Composition API
3.2.1 新增 useRoute 和 useRouter
在 setup 中访问路由和当前路由地址:
由于我们在 setup 里面没有访问 this,所以我们不能再直接访问 this. r o u t e r 或 t h i s . router 或 this. router或this.route。作为替代,我们使用 useRouter 和 useRoute 函数:
import { useRouter, useRoute } from 'vue-router'
export default {
setup() {
const router = useRouter() //拿到路由实例,相当于在模板中使用 $router。必须在 setup() 中调用。
const route = useRoute() //拿到当前路由地址,相当于在模板中使用 $route。必须在 setup() 中调用。
function pushWithQuery(query) {
router.push({
name: 'search',
query: {
...route.query,
},
})
}
},
}
route 对象是一个响应式对象,所以它的任何属性都可以被监听,但你应该避免监听整个 route 对象。在大多数情况下,你应该直接监听你期望改变的参数。
import { useRoute } from 'vue-router'
import { ref, watch } from 'vue'
export default {
setup() {
const route = useRoute()
const userData = ref()
// 当参数更改时获取用户信息
watch(() => route.params.id,
async newId => {
userData.value = await fetchUser(newId)
}
)
},
}
3.2.2 导航守卫
添加一个导航守卫,在当前位置的组件状态发生变更时触发。它可以在任何组件中使用。当组件被卸载时,导航守卫将被移除。
onBeforeRouteLeave: 类似于 beforeRouteLeave => 在当前位置的组件将要离开时触发。
onBeforeRouteUpdate:类似于 beforeRouteUpdate => 在当前位置即将更新时触发。
<script>
import { useRouter, useRoute, onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
export default {
name: 'home',
setup(props) {
onBeforeRouteLeave((to, from) => {
console.log(to, from)
console.log("在当前位置的组件将要离开时触发。如果返回 false 就阻止离开");
return false
})
onBeforeRouteUpdate((to, from) => {
console.log(to, from)
console.log("在当前位置即将更新时触发");
})
},
}
</script>
3.2.3 路由守卫
4. 对比@3.x 版本的破坏性变更!
4.1 移除了 fallback 属性
原 fallback 属性
4.2 将 onReady
变更为 isReady
---------在V3 中
现有的 router.onReady() 函数已被 router.isReady() 取代,该函数不接受任何参数并返回一个 Promise 对象
// 将
router.onReady(onSuccess, onError)
// 替换成
router.isReady().then(onSuccess).catch(onError)
// 或者使用
let Callback = () => {
let Ready = router.isReady().then((onSuccess) => {
return onSuccess
}).catch((onError) => {
return onError
})
return Ready // 返回Promise
}
Callback()
4.3 删除 <router-link>
中的 append
,event
,tag
,exact
属性
将
<router-link to="child-route" append>to relative child</router-link>
替换成
<router-link :to="append($route.path, 'child-route')">
to relative child
</router-link>
并且你必须在 App 实例上定义一个全局的 append 函数:
app.config.globalProperties.append = (path, pathToAppend) =>
path + (path.endsWith('/') ? '' : '/') + pathToAppend
4.4 移动了 base 配置
原 base 属性
现在,base 配置被作为 createWebHistory (其他 history 也一样)的第一个参数传递:
import { createRouter, createWebHistory } from 'vue-router'
createRouter({
history: createWebHistory('/base-directory/'),
routes: [],
})
4.5 删除了 通配符 模糊查询路由 ( * )
原属性
现在必须使用自定义的 regex 参数来定义所有路由(、/):
const routes = [
// pathMatch 是参数的名称,例如,跳转到 /not/found 会得到
// { params: { pathMatch: ['not', 'found'] } }
// 这要归功于最后一个 *,意思是重复的参数,如果你
// 打算直接使用未匹配的路径名称导航到该路径,这是必要的
{ path: '/:pathMatch(.*)*', name: 'not-found', component: NotFound },
// 如果你省略了最后的 `*`,在解析或跳转时,参数中的 `/` 字符将被编码
{ path: '/:pathMatch(.*)', name: 'bad-not-found', component: NotFound },
]
// 如果使用命名路由,不好的例子:
router.resolve({
name: 'bad-not-found',
params: { pathMatch: 'not/found' },
}).href // '/not%2Ffound'
// 好的例子:
router.resolve({
name: 'not-found',
params: { pathMatch: ['not', 'found'] },
}).href // '/not/found'
4.6 transition 和 keep-alive 现在必须通过 v-slot API 在 RouterView 内部使用:
在v3 中 路由缓存 页面 是通过 keep-alive 包裹 视图展示 router-view 达到视图缓存的效果。
<keep-alive>
<router-view></router-view>
</keep-alive>
现在V4 中, component 是一个特殊组件,:is 用来绑定指定的组件,这里与路由对应的页面绑定。
<router-view v-slot="{ Component }">
<transition>
<keep-alive>
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
4.7 scrollBehavior 变更
当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样。 vue-router 能做到,而且更好,它让你可以自定义路由切换时页面如何滚动。
当创建一个 Router 实例,你可以提供一个 scrollBehavior 方法:
const router = createRouter({
history: createWebHashHistory(),
routes: [...],
scrollBehavior (to, from, savedPosition) {
// return 期望滚动到哪个的位置
}
})
scrollBehavior 函数接收 to和 from 路由对象,如 Navigation Guards。第三个参数 savedPosition,只有当这是一个 popstate 导航时才可用(由浏览器的后退/前进按钮触发)。
const router = createRouter({
scrollBehavior(to, from, savedPosition) { //该函数可以返回一个 ScrollToOptions 位置对象
// 始终滚动到顶部
return { top: 0 }
},
})
4.8 嵌套路由,子级路由的的 path 可以 不用再以 / 开头
并且,带有空 path 的命名子路由不再添加斜线
const routes = [
{
path: '/dashboard',
name: 'dashboard-parent',
component: DashboardParent,
children: [
{ path: '', name: 'dashboard', component: DashboardDefault },
{
path: 'settings',
name: 'dashboard-settings',
component: DashboardSettings,
},
],
},
]
…
这里列举了些典型的变更特性,想了解更多 Vue-Router @4.x 点击这里查看详情
总结
以上就是本章节 为大家带来的 关于 Vue Router 4 版本的一些特征变化,当然 知识点 肯定来源于 官方文档,大家可以去 官方文档,了解更多新特性。
🚵♂️ 博主座右铭:向阳而生,我还在路上!
——————————————————————————————
🚴博主想说:将持续性为社区输出自己的资源,同时也见证自己的进步!
——————————————————————————————
🤼♂️ 如果都看到这了,博主希望留下你的足迹!【📂收藏!👍点赞!✍️评论!】
——————————————————————————————