Vue-Router 面试题汇总
1. 怎么重定向页面
第一种:
const router = new VueRouter({
routes: [
{ path: '/a', redirect: '/b' } // 可以是路径
]
})
第二种:
const router = new VueRouter({
routes: [
{ path: '/a', redirect: { name: 'foo' }} // 也可以是组件名
]
})
第三种:
const router = new VueRouter({
routes: [
{
path: '/a',
redirect: to =>{
const { hash, params, query } = to
if (query.to === 'foo') {
return { path: '/foo', query: null }
}else{
return '/b'
}
}
}
]
})
2. 怎么配置404页面
const router = new VueRouter({
routes: [
{
path: '*', redirect: {path: '/'}
}
]
})
3. 路由两种模式的区别
hash: 兼容所有浏览器,包括不支持 HTML5 History Api 的浏览器,例www.abc.com/#/index,has… hash的改变会触发hashchange事件,通过监听hashchange事件来完成操作实现前端路由。hash值变化不会让浏览器向服务器请求。
// 监听hash变化,点击浏览器的前进后退会触发
window.addEventListener('hashchange', function(event){
let newURL = event.newURL; // hash 改变后的新 url
let oldURL = event.oldURL; // hash 改变前的旧 url
},false)
复制代码
history: 兼容能支持 HTML5 History Api 的浏览器,依赖HTML5 History API来实现前端路由。没有#,路由地址跟正常的url一样,但是初次访问或者刷新都会向服务器请求,如果没有请求到对应的资源就会返回404,所以路由地址匹配不到任何静态资源,则应该返回同一个index.html 页面,需要在nginx中配置。
4. 导航守卫流程
-
导航被触发。
-
在失活的组件里调用离开守卫
beforeRouteLeave(to,from,next)。 -
调用全局的
beforeEach( (to,from,next) =>{} )守卫。 -
在重用的组件里调用
beforeRouteUpdate(to,from,next)守卫。 -
在路由配置里调用
beforeEnter(to,from,next)路由独享的守卫。 -
解析异步路由组件。
-
在被激活的组件里调用
beforeRouteEnter(to,from,next)。 -
在所有组件内守卫和异步路由组件被解析之后调用全局的
beforeResolve( (to,from,next) =>{} )解析守卫。 -
导航被确认。
-
调用全局的
afterEach( (to,from) =>{} )钩子。 -
触发 DOM 更新。
-
用创建好的实例调用beforeRouteEnter守卫中传给 next 的回调函数
beforeRouteEnter(to, from, next) {
next(vm => {
//通过vm访问组件实例
})
},
5. 路由导航守卫和Vue生命周期钩子函数的执行顺序?
路由导航守卫都是在Vue实例生命周期钩子函数之前执行的。
6. 导航守卫三个参数的含义
to:即将要进入的目标 路由对象。
from:当前导航正要离开的路由对象。
next:函数,必须调用,不然路由跳转不过去。
next():进入下一个路由。next(false):中断当前的导航。next('/')或next({ path: '/' }): 跳转到其他路由,当前导航被中断,进行新的一个导航。
7. afterEach 钩子中可以使用 next()吗
不可以,不接受next参数
8. 全局导航守卫有哪些
router.beforeEach:全局前置守卫。router.beforeResolve:全局解析守卫。router.afterEach:全局后置钩子。
import VueRouter from 'vue-router';
const router = new VueRouter({
mode: 'history',
base: '/',
routes,
// 新页面滚动到顶部
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition;
} else {
return { x: 0, y: 0 };
}
}
作者:红尘炼心
链接:https://juejin.cn/post/6844903961745440775
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
})
router.beforeEach((to, from, next) => {
//...
next();
})
router.beforeResolve((to, from, next) => {
//...
next();
})
router.afterEach((to, from) => {
//...
});
9. 组件内使用的导航守卫有哪些
beforeRouteLeave:在失活的组件里调用离开守卫。beforeRouteUpdate:在重用的组件里调用,比如包含<router-view />的组件。beforeRouteEnter:在进入对应路由的组件创建前调用。
beforeRouteLeave(to, from, next) {
//...
},
beforeRouteUpdate(to, from, next) {
//...
},
beforeRouteEnter(to, from, next) {
//...
},
10. 对router-link的了解
<router-link>是Vue-Router的内置组件,在具有路由功能的应用中作为声明式的导航使用。
<router-link>有8个props,其中几个作用是:
-
to:必填,表示目标路由的链接。当被点击后,内部会立刻把 to 的值传到
router.push(),所以这个值可以是一个字符串或者是描述目标位置的对象。<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>注意
path存在时params不起作用,只能用query -
replace:默认值为false,若设置的话,当点击时,会调用router.replace()而不是router.push(),于是导航后不会留下 history 记录。 -
append:设置 append 属性后,则在当前 (相对) 路径前添加基路径。 -
exact:是否精确匹配,默认为false。
<!-- 这个链接只会在地址为 / 的时候被激活 --><router-link to="/" exact></router-link> -
event:声明可以用来触发导航的事件。可以是一个字符串或是一个包含字符串的数组,默认是click。
11. 在组件中监听路由参数变化
有两种方法可以监听路由参数的变化,但是只能用在包含<router-view />的组件内。
-
第一种
watchwatch: { '$route'(to, from) { //这里监听 },}, -
第二种
beforeRouteUpdatebeforeRouteUpdate (to, from, next) { //这里监听},
12. 嵌套路由的使用
比如管理系统,顶部栏和左侧菜单栏是全局通用的,那就应该放在父路由,而右下的页面内容部分放在子路由。
app.vue
<template> <div> <router-view/> </div></template>
layout.vue
<template> <div> <div> //...头部导航 </div> <div> //...侧边栏导航 </div> <div> //...主内容 <router-view/> </div> </div></template
13. 命名视图
比如想同级展示多个视图,而不是嵌套展示。例如项目首页,有头部导航,侧边栏导航、主内容区域。头部导航、侧边栏导航我们不想用组件方式引入,想用视图方式展示。那么这个首页上,就有三个视图,头部导航视图,侧边栏导航视图、主内容区域视图同级展示。
layout.vue
<template> <div> <div> //...头部导航 <router-view name='header'></router-view> <div> //...侧边栏导航 <router-view name='sider'></router-view> </div> <div> //...主内容 <router-view/> </div> </div></template>
如果 router-view 没有设置name,那么默认为default。一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components 配置 (记得加上s)。
router.js
function load(component) {
return resolve => require([`views/${component}`], resolve);
}
const routes=[
{
path: '/',
redirect: '/home',
name: 'layout',
component: load('layout'),
children: [
{
path: '/home',
name: 'home',
components: {
default: load('main'),
header: load('header'),
sider: load('sider')
},
meta: {
title: '首页'
},
},
]
}
]
14. 获取路由传参
- query:
this.$route.push({
path:'/home',
query:{
userId:123
}
})
复制代码
浏览器地址:http://localhost:8036/home?userId=123 获取方式:this.$route.query.userId
-
params:
(1) 首先要在地址上做配置
{
path: '/home/:userId',
name: 'home',
component: load('home'),
meta: {
title: '首页'
},
},
(2) 访问传参
const userId = '123'
this.$router.push({ name: 'home', params: { userId } })
注意用params传参,只能用命名的路由(用name访问),如果用path,params不起作用。this.$router.push({ path: '/home', params: { userId }})不生效。
(3) 浏览器地址:http://localhost:8036/home/123
(4) 获取方式:this.$route.params.userId
15. 路由跳转的方式
-
声明式 通过使用内置组件
<router-link :to="/home">来跳转 -
编程式 通过调用router实例的push方法
router.push({ path: '/home' })或replace方法router.replace({ path: '/home' })
16. 使用history模式部署要注意什么
要注意404的问题,因为在history模式下,只是动态的通过js操作window.history来改变浏览器地址栏里的路径,并没有发起http请求,当直接在浏览器里输入这个地址的时候,就一定要对服务器发起http请求,但是这个目标在服务器上又不存在,所以会返回404。
所以要在Ngnix中将所有请求都转发到index.html上就可以了。
17. route和router区别
route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。
而router是“路由实例对象”,包括了路由的跳转方法,钩子函数等。