跳到主内容

Vue基础面试题(三)

本文整理了 Vue 的基础面试题,包括 keep-alive 抽象组件的介绍以及相关用法,vue-router 导航守卫种类介绍,以及 vue-router 整个路由钩子解析流程等等

keep-alive 是什么

keep-alive 声明一个抽象组件。keep-alive 组件不会渲染一个 DOM 元素,也不会出现在组件链中;使用 keep-alive 包裹动态组件,在不满足条件渲染的时候,会缓存在内存中,而不会销毁。可以更快得到复用。

keep-alive 用法

在动态组件中的应用

<keep-alive :include="whiteList" :exclude="blackList" :max="amount">
<component :is="currentComponent"></component>
</keep-alive>

在路由中使用

<keep-alive :include="whiteList" :exclude="blackList" :max="amount">
<router-view></router-view>
</keep-alive>

keep-alive 相关属性

include 定义缓存白名单,取值可以是字符串,正则,或者数组,例如 :include="a,b":include="/a|b/" 或者 :include="['a', 'b']"

exclude 定义缓存黑名单,被命中的组件将不会被缓存,取值同上

max 2.5 版本新增的,定义最大的缓存组件数量,超出的通过 LRU 算法 策略进行清理。

vue-router 导航守卫有多少种?

vue-router 导航守卫有三种,分别是:全局守卫,路由独享守卫,组件内守卫

全局守卫又分三种:分别是全局前置,全局解析,全局后置。

全局前置守卫

全局前置守卫是 router.beforeEach,一般可以用来做权限控制,不符合的话直接返回登录页面。

const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
else next()
})

全局解析守卫

全局解析守卫是 router.beforeResolve,在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。

全局后置守卫

全局后置守卫是 router.afterEach,这个钩子不会接受 next 函数也不会改变导航本身

组件内守卫

组件内守卫允许在组件内部做处理,有三个钩子,分别是 beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave

beforeRouteEnter 不能访问 this,此时组件还没有被挂载。如果需要访问组件实例,可以通过 next 回调,嗯,但是好像没什么鸟用。

beforeRouteEnter (to, from, next) {
next(vm => {
// 通过 `vm` 访问组件实例
})
}

beforeRouteLeave 可以在路由离开前做以下二次确认,例如

beforeRouteLeave (to, from, next) {
const answer = window.confirm('表单未提交,是否离开?')
if (answer) {
next()
} else {
next(false)
}
}

vue-router 路由钩子解析流程

  • 导航被触发。
  • 在失活的组件里调用 beforeRouteLeave 守卫。
  • 调用全局的 beforeEach 守卫。
  • 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
  • 在路由配置里调用 beforeEnter
  • 解析异步路由组件。
  • 在被激活的组件里调用 beforeRouteEnter
  • 调用全局的 beforeResolve 守卫 (2.5+)。
  • 导航被确认。
  • 调用全局的 afterEach 钩子。
  • 触发 DOM 更新。
  • 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

history 和 hash 模式的区别

history 模式:利用 HTML5 history api 实现的,url 看起来比较美观,不过在部署的时候需要服务器处理,例如 nginx 跳转处理,防止 404 问题。

hash 模式:在路径后面添加 # 号,不过有一些场景不建议使用,比如在公众号分享的时候,会把 # 后端的参数过滤掉。