2024年Web前端最新Vue-Router总结大全,从小白到精通,含vue3,我的阿里手淘面试经历分享

框架相关

原生JS虽能实现绝大部分功能,但要么就是过于繁琐,要么就是存在缺陷,故绝大多数开发者都会首选框架开发方案。现阶段较热门是React、Vue两大框架,两者工作原理上存在共通点,也存在一些不同点,对于校招来说,不需要两个框架都学得特别熟,一般面试官会针对你简历中写的框架进行提问。

在框架方面,生命周期、钩子函数、虚拟DOM这些基本知识是必须要掌握的,在学习的过程可以结合框架的官方文档

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

Vue框架

知识要点:
1. vue-cli工程
2. vue核心知识点
3. vue-router
4. vuex
5. http请求
6. UI样式
7. 常用功能
8. MVVM设计模式

React框架

知识要点:
1. 基本知识
2. React 组件
3. React Redux
4. React 路由

你可以在路由组件内直接定义路由导航守卫(传递给路由配置的)

可用的配置 API

你可以为路由组件添加以下配置:

  • 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

},

}

beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。

不过,你可以通过传一个回调给 next 来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数:

beforeRouteEnter (to, from, next) {

next(vm => {

// 通过 vm 访问组件实例

})

}

这个 离开守卫 通常用来预防用户在还未保存修改前突然离开。该导航可以通过返回 false 来取消。

beforeRouteLeave (to, from) {

const answer = window.confirm(‘Do you really want to leave? you have unsaved changes!’)

if (!answer) return false

}

完整的导航解析流程

  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 的回调函数,创建好的组件实例会作为回调函数的参数传入。

路由元信息


有时,你可能希望将任意信息附加到路由上,如过渡名称、谁可以访问路由等。这些事情可以通过接收属性对象的meta属性来实现,并且它可以在路由地址和导航守卫上都被访问到。

const routes = [

{

path: ‘/posts’,

component: PostsLayout,

children: [

{

path: ‘new’,

component: PostsNew,

// 只有经过身份验证的用户才能创建帖子

meta: { requiresAuth: true }

},

{

path: ‘:id’,

component: PostsDetail

// 任何人都可以阅读文章

meta: { requiresAuth: false }

}

]

}

]

我们称呼 routes 配置中的每个路由对象为 路由记录。路由记录可以是嵌套的,因此,当一个路由匹配成功后,它可能匹配多个路由记录。

一个路由匹配到的所有路由记录会暴露为  r o u t e  对象 ( 还有在导航守卫中的路由对象 ) 的 route 对象(还有在导航守卫中的路由对象)的 route 对象(还有在导航守卫中的路由对象)route.matched 数组。

我们需要遍历这个数组来检查路由记录中的 meta 字段,但是 Vue Router 还为你提供了一个 $route.meta 方法,它是一个非递归合并所有 meta 字段的(从父字段到子字段)的方法。这意味着你可以简单地写

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

// 而不是去检查每条路由记录

// to.matched.some(record => record.meta.requiresAuth)

if (to.meta.requiresAuth && !auth.isLoggedIn()) {

// 此路由需要授权,请检查是否已登录

// 如果没有,则重定向到登录页面

return {

path: ‘/login’,

// 保存我们所在的位置,以便以后再来

query: { redirect: to.fullPath },

}

}

})

TypeScript

可以通过扩展 RouteMeta 接口来输入 meta 字段:

// typings.d.ts or router.ts

import ‘vue-router’

declare module ‘vue-router’ {

interface RouteMeta {

// 是可选的

isAdmin?: boolean

// 每个路由都必须声明

requiresAuth: boolean

}

}

数据获取 数据获取 | Vue Router (vuejs.org)")


有时候,进入某个路由后,需要从服务器获取数据。例如,在渲染用户信息时,你需要从服务器获取用户的数据。我们可以通过两种方式来实现:

  • 导航完成之后获取:先完成导航,然后在接下来的组件生命周期钩子中获取数据。在数据获取期间显示“加载中”之类的指示。

  • 导航完成之前获取:导航完成前,在路由进入的守卫中获取数据,在数据获取成功后执行导航。

从技术角度讲,两种方式都不错 —— 就看你想要的用户体验是哪种。

导航完成后获取数据

当你使用这种方式时,我们会马上导航和渲染组件,然后在组件的 created 钩子中获取数据。这让我们有机会在数据获取期间展示一个 loading 状态,还可以在不同视图间展示不同的 loading 状态。

在导航完成前获取数据

通过这种方式,我们在导航转入新的路由前获取数据。我们可以在接下来的组件的 beforeRouteEnter 守卫中获取数据,当数据获取成功后只调用 next 方法:

在为后面的视图获取数据时,用户会停留在当前的界面,因此建议在数据获取期间,显示一些进度条或者别的指示。如果数据获取失败,同样有必要展示一些全局的错误提醒。

Vue Router 和 组合式 API


在 setup 中访问路由和当前路由

route 对象是一个响应式对象,所以它的任何属性都可以被监听,但你应该避免监听整个 route 对象:

因为我们在 setup 里面没有访问 this,所以我们不能再直接访问 this. r o u t e r  或  t h i s . router 或 this. router  this.route。作为替代,我们使用 useRouter 函数:

请注意,在模板中我们仍然可以访问  r o u t e r  和  router 和  router  route,所以不需要在 setup 中返回 router 或 route。

导航守卫

虽然你仍然可以通过 setup 函数来使用组件内的导航守卫,但 Vue Router 将更新和离开守卫作为 组合式 API 函数公开:

import { onBeforeRouteLeave, onBeforeRouteUpdate } from ‘vue-router’

export default {

setup() {

// 与 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()

// 与 beforeRouteLeave 相同,无法访问 this

onBeforeRouteUpdate(async (to, from) => {

//仅当 id 更改时才获取用户,例如仅 query 或 hash 值已更改

if (to.params.id !== from.params.id) {

userData.value = await fetchUser(to.params.id)

}

})

},

}

组合式 API 守卫也可以用在任何由  渲染的组件中,它们不必像组件内守卫那样直接用在路由组件上。

useLink

Vue Router 将 RouterLink 的内部行为作为一个组合式 API 函数公开。它提供了与 v-slot API 相同的访问属性:

过渡动效


想要在你的路径组件上使用转场,并对导航进行动画处理,你需要使用 v-slot API

对所有的路由使用相同的过渡

//把原来这个路由视图换成这个加动画的试图即可

单个路由的过渡

想让每个路由的组件有不同的过渡,你可以将元信息和动态的 name 结合在一起,放在 上:

const routes = [

{

path: ‘/custom-transition’,

component: PanelLeft,

meta: { transition: ‘slide-left’ },

},

{

path: ‘/other-transition’,

component: PanelRight,

meta: { transition: ‘slide-right’ },

},

]

基于路由的动态过渡

也可以根据目标路由和当前路由之间的关系,动态地确定使用的过渡。使用和刚才非常相似的片段:

我们可以添加一个 after navigation hook (后置钩子),根据路径的深度动态添加信息到 meta 字段。

router.afterEach((to, from) => {

const toDepth = to.path.split(‘/’).length

const fromDepth = from.path.split(‘/’).length

to.meta.transitionName = toDepth < fromDepth ? ‘slide-right’ : ‘slide-left’

})

滚动行为


使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样。 vue-router 能做到,而且更好,它让你可以自定义路由切换时页面如何滚动。

注意: 这个功能只在支持 history.pushState 的浏览器中可用。

当创建一个 Router 实例,你可以提供一个 scrollBehavior 方法:

const router = createRouter({

history: createWebHashHistory(),

routes: […],

scrollBehavior (to, from, savedPosition) {

// return 期望滚动到哪个的位置

}

})

scrollBehavior 函数接收 to和 from 路由对象,如 Navigation Guards。第三个参数 savedPosition,只有当这是一个 popstate 导航时才可用(由浏览器的后退/前进按钮触发)。

该函数可以返回一个 ScrollToOptions 位置对象:

const router = createRouter({

scrollBehavior(to, from, savedPosition) {

// 始终滚动到顶部

return { top: 0 }

},

})

你也可以通过 el 传递一个 CSS 选择器或一个 DOM 元素。在这种情况下,top 和 left 将被视为该元素的相对偏移量。

const router = createRouter({

scrollBehavior(to, from, savedPosition) {

// 始终在元素 #main 上方滚动 10px

return {

// 也可以这么写

// el: document.getElementById(‘main’),

el: ‘#main’,

top: -10,

}

},

})

如果返回一个 falsy 的值,或者是一个空对象,那么不会发生滚动。

返回 savedPosition,在按下 后退/前进 按钮时,就会像浏览器的原生表现那样:

const router = createRouter({

scrollBehavior(to, from, savedPosition) {

if (savedPosition) {

return savedPosition

} else {

return { top: 0 }

}

},

})

如果你要模拟 “滚动到锚点” 的行为:

const router = createRouter({

scrollBehavior(to, from, savedPosition) {

if (to.hash) {

return {

el: to.hash,

}

}

},

})

如果你的浏览器支持滚动行为,你可以让它变得更流畅:

const router = createRouter({

scrollBehavior(to, from, savedPosition) {

if (to.hash) {

return {

el: to.hash,

behavior: ‘smooth’,

}

}

}

})

延迟滚动

当处理过渡时,我们希望等待过渡结束后再滚动。要做到这一点,你可以返回一个 Promise,它可以返回所需的位置描述符。

const router = createRouter({

scrollBehavior(to, from, savedPosition) {

return new Promise((resolve, reject) => {

setTimeout(() => {

resolve({ left: 0, top: 0 })

}, 500)

})

},

})

我们可以将其与页面级过渡组件的事件挂钩,以使滚动行为与你的页面过渡很好地结合起来

路由懒加载


/ 将

// import UserDetails from ‘./views/UserDetails’

// 替换成

const UserDetails = () => import(‘./views/UserDetails’)

const router = createRouter({

// …

routes: [{ path: ‘/users/:id’, component: UserDetails }],

})

component (和 components) 配置接收一个返回 Promise 组件的函数,Vue Router 只会在第一次进入页面时才会获取这个函数,然后使用缓存数据。这意味着你也可以使用更复杂的函数,只要它们返回一个 Promise :

const UserDetails = () =>

Promise.resolve({

/* 组件定义 */

})

const router = createRouter({

routes: [{ path: ‘/users/:id’, component: UserDetails }],

})

一般来说,对所有的路由都使用动态导入是个好主意。

把组件按组分块

路由懒加载 | Vue Router (vuejs.org)")

扩展 RouterLink


扩展 RouterLink | Vue Router (vuejs.org)")

检测导航故障


如果导航被阻止,导致用户停留在同一个页面上,由 router.push 返回的 Promise 的解析值将是 Navigation Failure。否则,它将是一个 falsy 值(通常是 undefined)。这样我们就可以区分我们导航是否离开了当前位置:

const navigationResult = await router.push(‘/my-profile’)

if (navigationResult) {

// 导航被阻止

} else {

// 导航成功 (包括重新导航的情况)

this.isMenuOpen = false

}

Navigation Failure 是带有一些额外属性的 Error 实例,这些属性为我们提供了足够的信息,让我们知道哪些导航被阻止了以及为什么被阻止了。要检查导航结果的性质,请使用 isNavigationFailure 函数:

import { NavigationFailureType, isNavigationFailure } from ‘vue-router’

// 试图离开未保存的编辑文本界面

const failure = await router.push(‘/articles/2’)

/如果你忽略第二个参数: isNavigationFailure(failure),那么就只会检查这个 failure 是不是一个 Navigation Failure。/

if (isNavigationFailure(failure, NavigationFailureType.aborted)) {

// 给用户显示一个小通知

showToast(‘You have unsaved changes, discard and leave anyway?’)

}

鉴别导航故障

正如我们在一开始所说的,有不同的情况会导致导航的中止,所有这些情况都会导致不同的 Navigation Failure。它们可以用 isNavigationFailure 和 NavigationFailureType 来区分。总共有三种不同的类型:

  • aborted:在导航守卫中返回 false 中断了本次导航。

  • cancelled: 在当前导航还没有完成之前又有了一个新的导航。比如,在等待导航守卫的过程中又调用了 router.push。

  • duplicated:导航被阻止,因为我们已经在目标位置了。

导航故障的属性

所有的导航失败都会暴露 to 和 from 属性,以反映失败导航的当前位置和目标位置:

// 正在尝试访问 admin 页面

router.push(‘/admin’).then(failure => {

if (isNavigationFailure(failure, NavigationFailureType.redirected)) {

failure.to.path // ‘/admin’

failure.from.path // ‘/’

}

})//在所有情况下,to 和 from 都是规范化的路由地址。

检测重定向

当在导航守卫中返回一个新的位置时,我们会触发一个新的导航,覆盖正在进行的导航。与其他返回值不同的是,重定向不会阻止导航,而是创建一个新的导航。因此,通过读取路由地址中的 redirectedFrom 属性,对其进行不同的检查:

await router.push(‘/my-profile’) if (router.currentRoute.value.redirectedFrom) { // redirectedFrom 是解析出的路由地址,就像导航守卫中的 to和 from }

await router.push(‘/my-profile’)

if (router.currentRoute.value.redirectedFrom) {

// redirectedFrom 是解析出的路由地址,就像导航守卫中的 to和 from

}

动态路由


添加路由到你的路由上通常是通过 routes 配置来完成的,但是在某些情况下,你可能想在应用程序已经运行的时候添加或删除路由。

具有可扩展接口(如 Vue CLI UI )这样的应用程序可以使用它来扩展应用程序。

添加路由

动态路由主要通过两个函数实现。router.addRoute() 和 router.removeRoute()。它们只注册一个新的路由,也就是说,如果新增加的路由与当前位置相匹配,就需要你用 router.push() 或 router.replace() 来手动导航,才能显示该新路由。我们来看一个例子:

const router = createRouter({

history: createWebHistory(),

routes: [{ path: ‘/:articleName’, component: Article }],

})

进入任何页面,/about,/store,或者 /3-tricks-to-improve-your-routing-code 最终都会呈现 Article 组件。如果我们在 /about 上添加一个新的路由:

router.addRoute({ path: ‘/about’, component: About })

页面仍然会显示 Article 组件,我们需要手动调用 router.replace() 来改变当前的位置,并覆盖我们原来的位置(而不是添加一个新的路由,最后在我们的历史中两次出现在同一个位置):

router.addRoute({ path: ‘/about’, component: About })

// 我们也可以使用 this.$route 或 route = useRoute() (在 setup 中)

router.replace(router.currentRoute.value.fullPath)

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

在导航守卫中添加路由如果你决定在导航守卫内部添加或删除路由,你不应该调用 router.replace(),而是通过返回新的位

router.beforeEach(to => {

if (!hasNecessaryRoute(to)) {

router.addRoute(generateRoute(to))

// 触发重定向

return to.fullPath

}

})

上面的例子有两个假设:第一,新添加的路由记录将与 to 位置相匹配,实际上导致与我们试图访问的位置不同。第二,hasNecessaryRoute() 在添加新的路由后返回 false,以避免无限重定向。

因为是在重定向中,所以我们是在替换将要跳转的导航,实际上行为就像之前的例子一样。而在实际场景中,添加路由的行为更有可能发生在导航守卫之外,例如,当一个视图组件挂载时,它会注册新的路由。

删除路由

有几个不同的方法来删除现有的路由:

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

router.addRoute({ path: ‘/about’, name: ‘about’, component: About })

// 这将会删除之前已经添加的路由,因为他们具有相同的名字且名字必须是唯一的

router.addRoute({ path: ‘/other’, name: ‘about’, component: Other })

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

const removeRoute = router.addRoute(routeRecord)

removeRoute() // 删除路由如果存在的话

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

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

router.addRoute({ path: ‘/about’, name: ‘about’, component: About })

// 删除路由

router.removeRoute(‘about’)

框架相关

原生JS虽能实现绝大部分功能,但要么就是过于繁琐,要么就是存在缺陷,故绝大多数开发者都会首选框架开发方案。现阶段较热门是React、Vue两大框架,两者工作原理上存在共通点,也存在一些不同点,对于校招来说,不需要两个框架都学得特别熟,一般面试官会针对你简历中写的框架进行提问。

在框架方面,生命周期、钩子函数、虚拟DOM这些基本知识是必须要掌握的,在学习的过程可以结合框架的官方文档

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

Vue框架

知识要点:
1. vue-cli工程
2. vue核心知识点
3. vue-router
4. vuex
5. http请求
6. UI样式
7. 常用功能
8. MVVM设计模式

React框架

知识要点:
1. 基本知识
2. React 组件
3. React Redux
4. React 路由

er.addRoute({ path: ‘/about’, name: ‘about’, component: About })

// 这将会删除之前已经添加的路由,因为他们具有相同的名字且名字必须是唯一的

router.addRoute({ path: ‘/other’, name: ‘about’, component: Other })

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

const removeRoute = router.addRoute(routeRecord)

removeRoute() // 删除路由如果存在的话

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

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

router.addRoute({ path: ‘/about’, name: ‘about’, component: About })

// 删除路由

router.removeRoute(‘about’)

框架相关

原生JS虽能实现绝大部分功能,但要么就是过于繁琐,要么就是存在缺陷,故绝大多数开发者都会首选框架开发方案。现阶段较热门是React、Vue两大框架,两者工作原理上存在共通点,也存在一些不同点,对于校招来说,不需要两个框架都学得特别熟,一般面试官会针对你简历中写的框架进行提问。

在框架方面,生命周期、钩子函数、虚拟DOM这些基本知识是必须要掌握的,在学习的过程可以结合框架的官方文档

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

Vue框架

知识要点:
1. vue-cli工程
2. vue核心知识点
3. vue-router
4. vuex
5. http请求
6. UI样式
7. 常用功能
8. MVVM设计模式

[外链图片转存中…(img-pGGbGvOq-1715433359678)]

React框架

知识要点:
1. 基本知识
2. React 组件
3. React Redux
4. React 路由

[外链图片转存中…(img-f9iF8wpK-1715433359679)]

  • 19
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值