vue面试(三)

  1. 1. 单页应用首屏加载速度慢怎么解决
  2. 2. vue项目中你是如何解决跨域的
  3. 3. vue要做权限管理应该怎么做?如果控制到按钮级别的权限怎么做?
    1. 3.1. 常见权限控制
  4. 4. vue-router有几种钩子函数,具体是什么及执行流程是怎么样的?
  5. 5. vue-router几种模式的区别
  6. 6. vue项目本地开发完成后部署到服务器报404是什么原因
  7. 7. 谈一下你对vuex的个人理解
    1. 7.1. 状态修改
    2. 7.2. 缺点
    3. 7.3. 原理
  8. 8. 如何监听vuex中的数据变化
  9. 9. 页面刷新后vuex的数据丢失怎么解决
  10. 10. mutation和action的区别
  11. 11. 使用过vuex的module吗?在什么情况下使用
  12. 12. vue3中compositionAPI的优势是?
  13. 13. vue3跟vue2的区别
  14. 14. vue项目中的错误如何处理
    1. 14.1. errorCaptured钩子
    2. 14.2. 全局设置错误处理
    3. 14.3. 接口异常处理
  15. 15. vue3中模板编译与优化
    1. 15.1. PatchFlags优化
  16. 16. 你知道哪些vue3新特性

单页应用首屏加载速度慢怎么解决

  • 使用路由懒加载、异步组件,实现组件拆分,减少入口文件体积大小(优化体验骨架屏)
  • 抽离公共代码,采用splitChunks进行代码分割
  • 组件加载采用按需加载
  • 静态资源缓存,采用HTTP缓存(强制缓存、对比缓存)、使用localStorage实现缓存资源
  • 图片资源的压缩,雪碧图,对小图片进行base64减少http请求
  • 打包时开启gzip压缩处理、compress-webpack-plugin插件
  • 静态资源采用CDN提速,终极的手段
  • 使用SSR对首屏做服务端渲染

vue项目中你是如何解决跨域的

跨域是浏览器同源策略导致的,这个是浏览器的行为(协议、主机名、端口的不同都会导致跨域问题)。服务端和服务端之间进行通信是没有跨域问题的。跨域的实现方案有很多种。不过一般常用的就那么几种。

  • CORS (Cross-Origin Resource sharing,跨域资源共享)由服务端设置,允许指定的客户端访问服务器
  • 构建工具中设置反向代理、使用 Nginx 做反向代理。
  • 使用 Websocket 进行通信。
  • 搭建 BFF(Backend For Frontend)层解决跨域问题

vue项目中封装过axios吗?主要是封装哪方面的?

  • 设置请求超时时间
  • 根据项目环境设置请求路径
  • 设置请求拦截,自动添加token
  • 设置响应拦截,对响应的状态码或者数据进行格式化
  • 增添请求队列,实现loading效果
  • 维护取消请求token,在页面切换时通过导航守卫可以取消上个页面中正在发送的请求

vue要做权限管理应该怎么做?如果控制到按钮级别的权限怎么做?

常见权限控制

  • 登录鉴权:用户登录后返回Token,前端将 foken 保存到本地,作为用户登录的凭证,每次发送请求时会携带 Token,后端会对 Token 进行验证。当页面刷新时我们可以使用 Token 来获得用户权限。
  • 访问权限:根据用户是否登录判断能否访问某个页面,通过路由守卫实现判断用户是否有此权限。
  • 页面权限:前端配置的路由分为两部分“通用路由配置”和“需要权限的路由配置”。在权限路由中增加访问权限 meta(备注)。用户登录后可得到对应的权限列表,通过权限列表筛查出对应符合的路由信息,最后通过 addRoutes 方法,动态添加路由。
  • 按钮权限:按钮权限一般采用自定义指令实现,当用户登录时后端会返回对应的按钮权限,在按钮上使用此指令,指令内部会判断用户是否有此按钮权限,如果没有则会移除按钮。

vue-router有几种钩子函数,具体是什么及执行流程是怎么样的?

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

vue-router几种模式的区别

  • vue-router 有三种模式 hash、history、abstract
  • abstract 模式是在不支持浏览器 API环境使用,不依赖于浏览器历史
  • hash 模式:hash+ popState/hashChange 兼容性好但是不够美观,hash 服务端无法获取。不利于 seo优化
  • history 模式: historyApi+ popstate 美观,刷新会出现 404->CLl webpack history-fallback

vue项目本地开发完成后部署到服务器报404是什么原因

history模式刷新时会像服务端发起请求,服务端无法响应到对应的资源,所以会出现404问题

谈一下你对vuex的个人理解

  • Vuex 是一个专为 Vue.js 应用程序开发的 状态管理模式采用集中式存储管理应用的所有组件的状态。核心就是解决数据的共享。
  • 以相应的规则保证状态以一种可预测的方式发生变化。

状态修改

  • 组件中 commit()-> mutation ->修改状态
  • 组件中 dispatch()-> action(为了解决接口的复用问题,封装公共的逻辑)->commit()->mutation ->修改状态

缺点

vuex中store只有一份,复杂的数据需要依赖于模块。vuex状态是一个树状结构,最终会将模块的状态挂载到根模块上。

  • 模块和状态的名字冲突。
  • 数据不够扁平化、调用的时候过长
  • 更改状态mutation和action的选取
  • 模块需要增加namespacede
  • 对TS支持并不友好
  • ……

原理

  • 对于Vuex3 核心就是通过new Vue()创建了一个Vue实例,进行数据共享。
  • 对于Vuex4 核心就是通过创建一个响应式对象进行数据共享 reactive()

如何监听vuex中的数据变化

  • 通过watch监控vuex中状态变化
  • 通过store.subscribe监控状态变化

页面刷新后vuex的数据丢失怎么解决

  • 每次获取数据前检测vuex数据是否存在,不存在则发请求重新拉取数据,存储到vuex中
  • 采用vuex持久化插件,将数据存储到localStorage或者sessionStorage中

mutation和action的区别

  • 在action中可以处理异步逻辑,可以获取数据后将结果提交给mutation,mutation则是修改state
  • 在action中可以多次进行commit操作,包括action中可以调用action
  • 在非mutation中修改数据,在严格模式下会发生异常
  • dispatch时会将aciton包装成promis,而mutation则没进行包装

使用过vuex的module吗?在什么情况下使用

使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。

vuex允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const moduleA={
state:()=>({}),
mutations:{},
actions:{},
getters:{}
}
const moduleB={
state:()=>({}),
mutations:{},
actions:{}
}
const store =createstore({
modules:{
a: moduleA,
b: moduleB
}
})
store.state.a //-> moduleA 的状态
store.state.b //-> modueB 的状态

vue3中compositionAPI的优势是?

  • 存 Vue2 中采用的是 OptionsAP,用户提供的 data,props,methods,computed,watch 等属性(用户编写复杂业务逻辑会出现反复横跳问题)
  • Vue2 中所有的属性都是通过 this 访问,this 存在指向明确问题.
  • Vue2 中很多未使用方法或属性依旧会被打包,并且所有全局API都在 Vue 对象上公开。CompositionAPI对 tree-shaking 更加友好,代码也更容易压缩。
  • 组件逻辑共享问题, Vue2 采用 mixins 实现组件之间的逻辑共享: 但是会有数据来源不明确,命名冲突4等问题。Vue3 采用 CompositionAPI提取公共逻辑非常方便
  • 简单的组件仍然可以采用 OptionsAP!进行编写,compositionAPI在复杂的逻辑中有着明显的优势~。

vue3跟vue2的区别

  • Vue3.0 更注重模块上的拆分,在 2.0 中无法单独使用部分模块。需要引入完整的 Vuejs(例如只想使用使用响应式部分,但是需要引入完整的 Vueis), Vue3 中的模块之间耦合度低,模块可以独立使用。 拆分模块
  • Vue2 中很多方法挂载到了实例中导致没有使用也会被打包(还有很多组件也是一样)。通过构建工具Tree-shaking机制实现按需引入,减少用户打包后体积。重写 API
  • vue3 允许自定义渲染器,扩展能力强。不会发生以前的事情,改写 Vue 源码改造渲染方式。 扩展更方便
  • 在 Vue2 的时候使用 defineProperty 来进行数据的劫持,需要对属性进行重写添加 getter 及 setter 性能差
  • 当新增属性和删除属性时无法监控变化。需要通过$set、$delete 实现
  • 数组不采用 defineProperty 来进行劫持(浪费性能,对所有索引进行劫持会造成性能浪费)需要对数组单独进行处理
  • Diff 算法也进行了重写。
  • Vue3 模板编译优化,采用 PatchFlags 优化动态节点,采用 BlockTree 进行靶向更新等
  • 相比Vue2来说Vue3新增了很多新的特性。

vue项目中的错误如何处理

errorCaptured钩子

可以捕获来自后代组件的错误,如果全局的config.errorHandler被定义,所有的错误仍会发送它,因此这些错误仍然会像单一的分析服务的地方进行汇报。

父组件errorCaptured->子组件errorCaptured->孙组件出错时,错误会一直向上抛。如果errorCaptured中返回false则会阻断传播

全局设置错误处理

如果在组件渲染时出现运行错误,错误将会被传递至全局vue.config.errorHandler配置函数

1
2
3
Vue.config.errorHandler = (err,vm,info)=>{
console.log(err,vm,info);
}

接口异常处理

1
2
3
4
5
6
7
8
9
10
11
12
instance.interceptors.response.use(
(res)=>{
return res.data
},
(err)=>{
let res = err.response
if(res.status >=400){
handleError(response) // 统一处理接口异常
}
return Promise.reject(error)
}
)

vue3中模板编译与优化

PatchFlags优化

diff算法无法避免新旧虚拟DOM中无用的比较操作,通过patchFlags来标记动态内容,可以实现快速diff算法

你知道哪些vue3新特性

  • composition API
  • SFC Composition API Syntax Sugar(