Vue面试手册

Vue 是什么

Vue是一个构建用户界面的渐进式 MVVM 框架。它的核心在于数据驱动和组件化的思想。

Vue的优点主要有:

  • 轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十 kb ;
  • 简单易学:中文文档丰富,易于理解和学习;
  • 双向数据绑定:保留了 Angular 的特点,在数据操作方面更为方便;
  • 组件化:保留了 React 的优点,通过单页面组件实现了 html 的封装和重用,在构建单页面应用方面有着独特的优势;
  • 视图,数据,结构分离:使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作;
  • 虚拟DOM:dom 操作是非常耗费性能的,不再使用原生的 dom 操作节点,极大解放 dom 操作;
  • 运行速度更快:相比较于 react 而言,同样是操作虚拟 dom,就性能而言, vue 存在很大的优势。

为什么说Vue是一个渐进式框架

Vue 实现了构建 web 应用最核心的 mvvm 绑定部分,用户可以选择使用其他库(例如vuex、axios、vue-router)来搭配使用构建最适合自己的应用。

v-model 双向绑定的原理是什么

v-model 实际上是语法糖,以 input 元素为例:

1
2
3
<input v-model="inputV" />
// 等同于
<input :value="inputV" @input="inputV = $event.target.value"/>
  • input 组件的 value 属性绑定于 inputV 变量上,也就是当 inputV 变化时,input 组件的 value 也会跟着变化;
  • 监听 input 事件,该事件在 input 的值改变时触发,事件触发时给 inputV 重新赋值,所赋的值是 $event.target.value,也就是当前触发 input 事件时的 value 值,也就是该 input 组件的值。

Vue 2.0 响应式数据的原理

Vue.js 是采用 数据劫持 结合 发布者-订阅者模式 的方式,通过 Object.defineProperty() 来劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。主要分为以下几个步骤:

  • 对需要 observe 的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter 和 getter,这样的话,给这个对象的某个值赋值,就会触发 setter,那么就能监听到了数据变化;
  • Compile 负责解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图;
  • Watcher 订阅者是 Observer 和 Compile 之间通信的桥梁,主要做的事情是:
    • 在自身实例化时往属性订阅器(dep)里面添加自己
    • 自身必须有一个 update() 方法
    • 待属性变动 dep.notice() 通知时,能调用自身的 update() 方法,并触发 Compile 中绑定的回调
  • MVVM 作为数据绑定的入口,整合 Observer、Compile 和 Watcher 三者,通过 Observer 来监听自己的 model 数据变化,通过 Compile 来解析编译模板指令,最终利用 Watcher 搭起 Observer 和 Compile 之间的通信桥梁,达到 数据变化 -> 视图更新;视图交互变化(input) -> 数据(model)变更的双向绑定效果。

vue2_inner

Vue3 中为什么使用 Proxy 来替代 Object.defineProperty() 实现数据劫持?

Object.defineProperty 无法监听 下标方式修改数组数据 或者 给对象新增属性 的操作,Proxy 可以监听。

Vue data 中某一个属性的值发生改变后,视图会立即同步执行重新渲染吗

不会立即同步执行重新渲染。Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化, Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。如果同一个 watcher 被多次触发,只会被推入到队列中。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的。然后,在下一个的事件循环 tick 中,Vue 刷新队列并执行实际(已去重的)工作。

Vue2 监控不了数组类型 data 的变化,有什么解决办法

  • 使用 this.$set(obj,key,value) 更新数组
  • 调用以下几个数组的方法 splice()、 push()、pop()、shift()、unshift()、sort()、reverse()

Vue2 中何时使用 Vue.$nextTick()?

  • 在数据变化后执行的某个操作,而这个操作需要使用随数据变化而变化的 DOM 结构的时候,这个操作就需要方法在 nextTick() 的回调函数中。
  • 在 vue 生命周期中,如果在 created() 钩子进行DOM操作,也一定要放在 nextTick() 的回调函数中。因为在 created() 钩子函数中,页面的DOM还未渲染,这时候没办法操作DOM。

什么是 Vue.mixin

混入(mixin)是指当多个组件共享同样的功能(生命周期hook、方法等)时,将同样的功能剥离开来并在多个组件中引入该部分实现从而代码重用的目的。

vue-router有多少种模式?

  • hash模式:兼容所有浏览器,包括不支持 HTML5 History Api 的浏览器。例如 https://example.com/#index hash 的值为 #index, hash 的改变会触发 hashchange 事件,我们可以通过监听 hashchange 事件来完成操作实现前端路由。

  • history模式:能支持 HTML5 History Api 的浏览器,依赖 HTML5 History API 来实现前端路由。例如 https://example.com/index 。为防止服务器请求不到资源时返回 404,需要在服务器端设置,匹配不到资源时返回 index.html ,同时由前端来控制 404 页面的显示。例如,nginx 需配置

1
2
3
4
5
6
location / {
try_files $uri $uri/ @router index index.html;
}
location @router {
rewrite ^.*$ /index.html last;
}
  • abstract模式:支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式。

hash和history模式实现vue-router跳转api的区别

api hash history
push window.location.assign window.history.pushState
replace window.location.replace window.history.replaceState`
go window.history.go window.history.go
back window.history.go(-1) window.history.go(-1)
forward window.history.go(1) window.history.go(1)

vue 指令有哪些?

v-show、v-if、v-else-if、v-else、v-for、v-on、v-bind、v-model、v-once、v-slot、v-html、v-text

对比Vue和React

Vue3 和 React16.8 引入了较大的变更,所以 Vue 和 React 的对比一般指 Vue2 和 React16.7 的对比。

相同点

  • 使用 Virtual DOM
  • 提供了响应式(Reactive)和组件化(Composable)的视图组件
  • 核心库与路由(react-router、vue-router)和状态管理(redux、vuex)分离
  • 支持 JSX,移动端都支持原生渲染
  • 提供了命令行工具(create-react-app、vue-cli)
  • 提供了跨端解决方案(React Native、weex)

不同点

  • 预编译
    • React 可以通过 Prepack 优化 JavaScript 源代码,在编译时执行原本在运行时的计算过程,通过简单的赋值序列提高 JavaScript 代码的执行效率,消除中间计算过程及分配对象操作。缓存 JavaScript 解析结果,优化效果最佳
    • Vue 可以静态分析 template,构造 AST 树,通过 PatchFlags 标记节点变化类型
  • 渲染
    • React
      • 通过 shouldComponentUpdate / setState,使用 PureCompoent 等对比前后状态和属性,手动决定是否渲染来优化
      • 推荐 jsx 语法,可扩展性好,可以渐进式应用
      • CSS in JS
    • Vue
      • 推荐 template 语法,自动追踪组件依赖,精确渲染状态改变的组件
      • 支持并且默认单文件组件,样式仍旧是 CSS 语法,迁移方便
  • 事件处理
    • React
      • 事件委托到 document,之后委托到 根节点
      • 所有事件被合并为合成事件并兼容不同浏览器
      • 事件处理函数中的 this 需要手动绑定或使用箭头函数声明
    • Vue
      • 支持原生事件
      • this 自动绑定执行上下文

前端技术选型

本文主要面向前端基础框架和库的选型,不包括构建工具、 UI 库和框架配套解决方案的选择。由于前端发展速度很快,框架层出不穷,特标明本文发布时间为 2021年6月6日,更新时间 2022年2月21日,更新时间 2022年3月14日,只适用于2021年前端基础框架技术选型。只选择了 web 应用开发时使用的框架,桌面端框架如 Electron、Tauri、Flutter,或者跨平台框架例如 React Native、Weex 或者众多的小程序框架本质上和如下列出的框架不是解决同一类问题所以不在对比之列。

阅读更多

Vue最佳实践

使用 vue 周边

vue-devtools

浏览器插件,让你能够实时编辑数据 property 并立即看到其反映出来的变化。另一个主要的好处是能够为 Vuex 提供时间旅行式的调试体验。

vue-performance-devtool

一个用于检查vue组件性能的浏览器插件。

vue-cli

vue-cli 是 vue 开发的标准工具,提供了交互式的项目脚手架,集成了 webpack 和丰富的官方插件集合。

vue-router

vue 官方路由管理器,支持嵌套的路由/视图表以及模块化的、基于组件的路由配置。

vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

axios

Axios是一款 promise 化的HTTP客户端,支持在浏览器和 Nodejs 环境中使用。

element-ui

elementUI 是一款基于 Vue 2.0 桌面端中后台组件库。

iview

iview 是一套基于 Vue 的高质量 UI 组件库,主要服务于 PC 界面的中后台产品。

Ant Design Vue

Ant Design Vue 是 Ant Design 的 Vue 实现,开发和服务于企业级后台产品。

阅读更多

Vue-keep-alive实现原理

一、前言

本文介绍的内容包括:

  • keep-alive用法:动态组件&vue-router
  • keep-alive源码解析
  • keep-alive组件及其包裹组件的钩子
  • keep-alive组件及其包裹组件的渲染

阅读更多

Vue3新功能和作用

2020 年 9 月 18 日 Vue3.0 正式发布。

Composition API

新增 setup 组件选项,是一个接受 props 和 context 的函数,使用 toRefs 对 props 进行响应式解构,可以通过 context 获取组件的 attrs slots emit 属性。返回一个可以在组件模板中使用其属性的对象,或者返回一个渲染函数,该函数可以直接使用在同一作用域中声明的响应式状态。

通过一个新的 ref/reactive 函数使任何响应式变量在任何地方起作用。

在 setup 中注册生命周期钩子,因为 setup 是围绕 beforeCreate 和 created 生命周期钩子运行的,所以不需要显式地定义它们,在vue3中只有如下钩子:onBeforeMountonMountedonBeforeUpdateonUpdatedonBeforeUnmountonUnmountedonErrorCapturedonRenderTrackedonRenderTriggered

从 Vue 导入的 watch 函数执行相同的操作

从 Vue 导入的 computed 函数在 Vue 组件外部创建计算属性

从 Vue 导入的 provide/inject 函数进行深度传值

阅读更多

读Vue源码所能想到的面试问题

指令v-if v-show有什么不同?

v-if 和 v-show都是Vue中的指令而且都可以用来控制模板的渲染。

v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。

v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。

相比之下,v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS( display:none) 进行切换。

一般来说,v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件很少改变,则使用 v-if 较好。

阅读更多

ionic4+vue搭建跨平台移动应用框架

ionic是一款混合移动应用开发框架,可以用来构建跨平台(Android & iOS)的移动应用程序,而且还可以基于Sass和AngularJS进行构建,是目前跨平台移动应用开发的一个翘楚。这个框架的目的是从web的角度开发手机应用,基于PhoneGap的编译平台,可以实现编译成各个平台的应用程序。
Vue.js是一个MVVM驱动的 web 界面的渐进式框架,学习简单并且十分灵活。ionic3之前一般默认和Angular“绑定”在了一起,从ionic4开始,Ionic Team宣布将会逐渐采用Stencil来实现标准Web Components,使用ionic将不再必须使用Angular,可以使用React,Vue,Jquery或者什么框架都不使用。

阅读更多