Vue-Router 面试题 (2023-09-13更新)
路由导航守卫 和 Vue 实例生成周期钩子函数的执行顺序?
路由导航守卫 都是在 Vue 实例生命周期钩子函数 之前执行的
Vue-Router 有哪几种导航钩子?
1. 全局守卫
- 全局前置守卫:
beforeEach
router.beforeEach((to, from, next) => {
// 必须调用next
})
- 全局解析守卫:
beforeResolve
router.beforeResolve((to, from, next) => {
// 必须调用next
})
- 全局后置钩子:
afterEach
router.afterEach((to, from) => {})
- 路由独享守卫
- beforeEnter
const router = new VueRouter({
routes: [
{
path: '/home',
beforeEnter: (to, from, next) => {
//...
}
}
]
})
- 组件内的守卫
- beforeRouteEnter
- beforeRouteUpdate
- beforeRouteLeave
const Foo = {
template: `...`,
beforeRouteEnter(to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate(to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave(to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。
不过,你可以通过传一个回调给 next 来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。
beforeRouteEnter (to, from, next) {
next(vm => {
// 通过 `vm` 访问组件实例
})
}
注意:只有 beforeRouteEnter 支持给 next 传递回调
讲一下完整的导航解析流程?
- 导航被触发
- 在失活的组件里调用 beforeRouteLeave 守卫
- 调用全局的 beforeEach 守卫
- 在重用的组件里调用 beforeRouteUpdate 守卫
- 在路由配置里调用 beforeEnter 守卫
- 解析异步路由组件
- 在被激活的组件里调用 beforeRouteEnter
- 在所有组件内守卫和异步路由被解析之后,调用全局的解析守卫 beforeResolve
- 导航被确认
- 调用全局后置钩子 afterEach
- 触发 DOM 更新
- 用创建好的组件实例,传给 beforeRouteEnter 中的 next 回调函数
导航守卫三个参数的含义?
- to:即将要进入的目标路由对象
- from:当前导航正要离开的路由对象
- next:一定要调用该方法来 resolve 这个钩子,不然路由跳转不过去
- next():进入下一个路由
- next(false):中断当前的导航
- next('/') 或 next({path: '/'}):当前导航被中断,进行新的一个导航
route 和 router 有什么区别?
this.$route
是当前路由信息对象,包括 path、params、hash、query、fullPath、matched、name 等路由信息参数this.$router
是路由实例对象,包括了路由的跳转方式 push()、go(),钩子函数等this.$routes
是创建路由实例的配置项,用来配置多个 route 路由对象
路由之间跳转有哪些方式?
- 声明式导航: 通过内置组件
router-link
跳转
<router-link :to="/home"></router-link>
- 编程式导航: 通过调用
router
实例的方法跳转
- 使用 push 方法跳转
this.$router.push({
path: '/home'
})
- 使用 repalce 方法跳转
this.$router.replace({
path: '/home'
})
Vue-Router 传参有哪些方式?
-
query 传参和接参
- 传参
this.$router.push({ path: '/home', query: { id: 1 } })
- 接参
this.$router.query.id
-
params 传参和接参
- 传参
this.$router.push({ name: 'Home', params: { id: 1 } })
- 接参
this.$route.params.id
注意: params 传参,push 里面只能是 name: 'xxx',不能是 path: '/xxx',因为 params 只能用 name 来引入路由,如果这里写成了 path,目标页面接收参数会是 undefined
query 和 params 的区别?
- query 刷新页面参数不会消失,params 传参页面参数会消失,可以考虑本地存储解决
- query 传参会显示在 url 地址上,params 传参不会显示地址上
如何监听路由参数的变化?
有两种方法可以监听路由参数的变化,但是只能用在包含 <router-view/>
的组件内
- watch 监听$route 对象
watch: {
$route(to, from) {
console.log(to, from)
}
}
- 调用组件内的守卫 beforeRouteUpdate
beforeRouteUpdate(to, from, next) {
console.log(to, from)
next()
}
谈谈你对 router-link 的了解?
router-link 是 vue-router 的内置组件,在具有路由功能的应用中,作为声明式导航使用
router-link 有 8 个 props,如下:
-
to
必填,标识目标路由的链接,当被点击后,内部会立刻把 to 的值传到 router.push(),所以这个值可以是一个字符串或者描述目标路由的对象 -
repalce
默认值 false,若设置的话,当点击时,会调用router.replace()
而不是router.push()
-
append
设置append
属性后,则在当前 (相对) 路径前添加基路径。例如,我们从 /a 导航到一个相对路径 b,如果没有配置append
,则路径为 /b,如果配了,则为 /a/b -
tag
让<router-link>
渲染成tag
设置的标签,如tag="li"
,就会渲染成<li>跳转</li>
-
active-class
默认值为router-link-acitve
,设置链接激活时使用的 CSS 类名,默认值可以通过路由的构造选项linkActiveClass
来全局配置 -
exact-active-class
默认值为router-link-exact-active
,设置链接被精确匹配的时候应该激活的 class,默认值可以通过路由构造函数选项linkExactActiveClass
进行全局配置 -
exact
是否精确匹配,默认为 false -
event
声明可以用来触发导航的事件,可以是一个字符串或是一个包含字符串的数组,默认是click
<router-link to="home">Home</router-link>
<router-link :to="'home'">Home</router-link>
<router-link :to="{ path: 'home' }">Home</router-link>
<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
<router-link :to="{ path: 'user', query: { userId: 123 }}">User</router-link>
说说 active-class 是哪个组件的属性?
<router-link/>
组件的属性,设置连接激活时使用的 css 类名,默认值可以通过路由的构造选项 linkActiveClass
来全局配置
css
.nav .active{
color: red;
}
router.js
export default new Router({
linkActiveClass: 'active',
routes: []
})
怎么重定向页面?
- 重定向 path
const router = new Router({
routes: [{ path: '/a', redirect: '/b' }]
})
- 重定向到命名的路由
const router = new Router({
routes: [{ path: '/a', name: 'Baa' }]
})
- 可以写成一个方法,动态返回重定向的目标
const router = new Router({
routes: [
{
path: '/a',
redirect: (to) => {
return { path: '/bbb', query: { a: 1 } }
}
}
]
})
vue-router 怎么配置 404 页面?
在 router.js 中,由于路由是从上到下执行的,只要在路由配置中最后面放个*号就可以了
const router = new Router({
routes: [
{
path: '*',
redirect: '/404'
}
]
})
切换路由时,需要保存草稿的功能,怎么实现?
使用<keep-alive>
包裹<router-view>
<keep-alive>
<router-view></router-viewe
</keep-alive>
vue 路由中去掉
在路由 router.js 中配置 mode:'history'
const router = new Router({
mode: 'history'
})
hash 模式和 history 模式相比较
1. hash 模式:
优点:
hash 值会出现在 URL 中,但不会包含在 http 请求中,所以改变 hash 值时不会刷新页面,也不会向服务器发送请求
hash 值的改变会触发 hashchange 事件,通过监听 hasChange 事件来完成操作实现前端路由
兼容性比较好,能兼容 IE8
缺点:
url 路径会出现”#“字符
hash 有体积限制
- history 模式:
优点:
history 模式利用 HTML5 History Interface 中新增的 pushState()
和 replaceState()
方法,这两个方法应用于浏览器的历史记录栈,提供了对历史记录进行修改的功能,
url 值不会出现“#”字符
缺点:
url 的改变属于 http 请求,借助 history.pushState 实现页面的无刷新跳转,因此会重新请求服务器,所以需要服务器的配置,否则会 404
兼容性差,IE10,特定浏览器支持
本文来自博客园,作者:时光凉忆,转载请注明原文链接:https://www.cnblogs.com/naturl/p/15173914.html