Vue-Router面试题汇总

怎么重定向页面?

第一种方法:

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' 
                }
            }
            
        }
    ]
})

怎么配置404页面?

const router = new VueRouter({
    routes: [
        {
            path: '*', redirect: {path: '/'}
        }
    ]
})

切换路由时,需要保存草稿的功能,怎么实现呢?


    
 

其中include可以是个数组,数组内容为路由的name选项的值。

路由有几种模式?说说它们的区别?

hash: 兼容所有浏览器,包括不支持 HTML5 History Api 的浏览器,例http://www.abc.com/#/index,hash值为#/index, 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中配置。
abstract: 支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式。

讲一下完整的导航守卫流程?

导航被触发。
在失活的组件里调用离开守卫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访问组件实例
})
},

路由导航守卫和Vue实例生命周期钩子函数的执行顺序?

路由导航守卫都是在Vue实例生命周期钩子函数之前执行的。

讲一下导航守卫的三个参数的含义?

to:即将要进入的目标 路由对象。
from:当前导航正要离开的路由对象。
next:函数,必须调用,不然路由跳转不过去。

next():进入下一个路由。
next(false):中断当前的导航。
next('/')或next({ path: '/' }) : 跳转到其他路由,当前导航被中断,进行新的一个导航。

在afterEach钩子中可以使用next()吗?

不可以,不接受next的参数。

全局导航守卫有哪些?怎么使用?

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 };
        }
    }
})
router.beforeEach((to, from, next) => {
    //...
    next();
})
router.beforeResolve((to, from, next) => {
    //...
    next();
})
router.afterEach((to, from) => {
    //...
});

什么是路由独享的守卫,怎么使用?

是beforeEnter守卫

const router = new VueRouter({
    routes: [
        {
            path: '/foo',
            component: Foo,
            beforeEnter: (to, from, next) => {
            // ...
            }
        }
    ]
})

在组件内使用的导航守卫有哪些?怎么使用?

beforeRouteLeave:在失活的组件里调用离开守卫。
beforeRouteUpdate:在重用的组件里调用,比如包含的组件。
beforeRouteEnter:在进入对应路由的组件创建前调用。

beforeRouteLeave(to, from, next) {
    //...
},
beforeRouteUpdate(to, from, next) {
    //...
},
beforeRouteEnter(to, from, next) {
    //...
},

在beforeRouteEnter导航守卫中可以用this吗?

不可以,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。
可以通过传一个回调给next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。

beforeRouteEnter(to, from, next) {
    next(vm => {
        console.log(vm)
    })
}

说说你对router-link的了解

是Vue-Router的内置组件,在具有路由功能的应用中作为声明式的导航使用。
有8个props,其作用是:

to:必填,表示目标路由的链接。当被点击后,内部会立刻把to的值传到router.push(),所以这个值可以是一个字符串或者是描述目标位置的对象。

Home
Home
Home
User
User

注意path存在时params不起作用,只能用query
replace:默认值为false,若设置的话,当点击时,会调用router.replace()而不是router.push(),于是导航后不会留下 history 记录。
append:设置 append 属性后,则在当前 (相对) 路径前添加基路径。
tag:让渲染成tag设置的标签,如tag:'li,渲染结果为

  • foo

  • active-class:默认值为router-link-active,设置链接激活时使用的 CSS 类名。默认值可以通过路由的构造选项 linkActiveClass 来全局配置。
    exact-active-class:默认值为router-link-exact-active,设置链接被精确匹配的时候应该激活的 class。默认值可以通过路由构造函数选项 linkExactActiveClass 进行全局配置的。
    exact:是否精确匹配,默认为false。

    
    

    event:声明可以用来触发导航的事件。可以是一个字符串或是一个包含字符串的数组,默认是click。

    怎么在组件中监听路由参数的变化?

    有两种方法可以监听路由参数的变化,但是只能用在包含的组件内。

    第一种watch: {
        '$route'(to, from) {
            //这里监听
        },
    },
    
    第二种beforeRouteUpdate (to, from, next) {
        //这里监听
    },
    

    切换路由后,新页面要滚动到顶部或保持原先的滚动位置怎么做呢?

    滚动顶部const router = new Router({
    mode: 'history',
    base: process.env.BASE_URL,
    routes,
    scrollBehavior(to, from, savedPosition) {
    if (savedPosition) {
    return savedPosition;
    } else {
    return { x: 0, y: 0 };
    }
    }
    });
    复制代码
    滚动原先位置

    在什么场景下会用到嵌套路由?

    做个管理系统,顶部栏和左侧菜单栏是全局通用的,那就应该放在父路由,而右下的页面内容部分放在子路由。
    比如在app.vue文件中

    复制代码在layout.vue文件中