关于 vue.js 的面试
Q:Vue3 今年发布了,请你说一下他们之间在相应式的实现上有什么区别?
A:Vue2 采用的是 defineProperty 去定义 get,set,而 Vue3 改用了 proxy。也代表着 vue 放弃了兼容 ie。
Q:像 Vue-Router,Vuex 他们都是作为 Vue 插件,请说一下他们分别都是如何在 vue 中生效的?
A:通过 vue 的插件系统,用 vue.mixin 混入到全局,在每个组件的生命周期的某个阶段注入组件实例。
Q:请你说一下 Vue 的设计架构。
A:Vue2 采用的是典型的混入式架构,类似于 express 和 jquery,各部分分模块开发,再通过一个 mixin 去混入到最终暴露到全局的类上。
Q:请说一下你这个项目中做的事情?
A:这个项目主体是一个 vue 项目,但是因为是 pc 端,为了 seo,我特意做了 ssr。然后这个项目有一套我和同事一起做的专门的组件库。在移动端,我们为了搭配 app,也做了移动混合方案。像在首页,因为数据巨大,我们采用了一些优化方案。利用本地缓存数据,对小图标进行了 base64 转码。
Q:什么是 MVVM 框架?它适用于哪些场景?
A:MVVM 框架是一个 Model-View-ViewModel 框架,其中 ViewModel 连接模型(Model) 和 视图 (View)。
在数据操作比较多的场景中,MVVM 框架更合适,有助于通过操作数据渲染页面。
Q:active-class 是哪个组件的属性?
A:它是 vue-router 模块的 router-link 组件的属性。
Q:如何定义 vue-router 的动态路由?
A:在静态路由名称前面添加冒号,例如设置 id 动态路由参数,为路由对象的 path 属性设置:/:id。
Q:如何获取传过来的动态参数?
A:在组件中,使用 $router 对象的 params.id 即 $route.params.id。
Q:vue-router 有哪几种导航钩子?
A:有 3 种。
第一种是全局导航钩子:router.beforeEach(to,from,next)。作用是跳转前进行判断拦截。
第二种是组件内的钩子。
第三种是单独路由独享组件。
Q:mint-ui 是什么?如何使用?
A:它是基于 vue.js 的前端组件库,用 npm 安装,然后通过 import 导入样式 和 JavaScript 代码。
vue.use(minUi)
用于实现全局引入,import { Toast } from 'mint-ui'
用于在单个组件局部引入。
Q:v-model 是 什么?有什么作用?
A:v-model 是 Vue.js 中的一条指令,可以实现数据的双向绑定。
Q:vue.js 中标签如何绑定事件?
A:绑定事件有两种方式。
第一种,通过 v-on 指令,<input v-on:click = "doLog()"/>
第二种,通过 @ 语法糖,<input @click = "doLog()">
Q:vuex 是 什么?如何使用?在哪种功能场景中使用它?
A:vuex 是针对 vue.js 框架实现的状态管理系统。
为了使用 vuex,要引入 store,并注入 vue.js 组建中,在组件内部即可通过 $store 访问 store 对象。
使用场景包括:在单页面应用中,用于组件之间的通信,例如音乐播放,登录状态管理,加入购物车等。
Q:如何实现自定义指令?它有哪些钩子函数?还有哪些钩子函数参数?
A:自定义指令包含以下两种。
全局自定义指令:vue.js 对象提供了 directive 方法,可以用来自定义指令,directive 方法接受两个参数,一个是指令名称,另一个是函数。
局部自定义指令:通过组件的 directive 属性定义。
它有如下钩子函数:
bind:在指令第一次绑定到元素时调用。
inserted:在被绑定元素插入父节点时调用(vue2.0新增的)
update:在所在组件的 VNode 更新时调用。
componentUpdated:在指令所在组件的 VNode 及其子 VNode 全部更新后调用(Vue2.0 新增的)。
unbind:只调用一次,在指令与元素解除绑定时调用。
钩子函数的参数如下。
el:指令所绑定的元素
binding:指令对象
vnode:虚拟节点
oldVnode:上一个虚拟节点
Q:至少说出 vue.js 中 4 种指令和它们的用法。
A:相关指令及其用法如下:
v-if:判断对象是否隐藏
v-for:循环渲染
v-bind:绑定一个属性
v-model:实现数据双向绑定
Q:vue-router 是什么?它有哪些组件?
A:它是 vue.js 的路由插件。组件包括 router-link 和 router-view
Q:导航钩子有哪些?它们有哪些参数?
A:导航钩子又称为导航守卫,又分为全局钩子,单个路由独享钩子和组件级钩子。
全局钩子有 beforeEach、beforeResolve(vue2.5.0新增)、afterEach。
单个路由独享钩子有 beforeEnter
组件级钩子有 beforeRouteEnter、beforeRouteUpdate(vue2.2 新增的)、beforeRouteLeave
它们有以下参数。
to:即将要进入的目标路由对象
from:当前导航正要离开的路由
next:一定要用这个函数才能到达下一个路由,如果不用就会遭到拦截
Q:Vue.js 的双向数据绑定原理是什么?
A:vue.js 采用 ES5 提供的属性特性功能,结合发布者-订阅者模式,通过 Object.defineProperty() 为各个属性定义 get、set 特性方法,
在数据发送改变时给订阅者发布消息,触发响应的监听回调。
具体步骤如下。
(1)对需要观察的数据对象进行递归遍历,包括子属性对象的属性,设置 set 和 get 特性方法。当给这个对象的某个值赋值时,
会触发绑定的 set 特性方法,于是就能监听到数据变化。
(2)用 compile 解析模板指令,将模板中的变量替换成数据。然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,
添加监听数据的订阅者,一旦数据有变动,就会收到通知,并更新视图。
(3)Watcher 订阅者是 Observer 和 Compile 之间通信的桥梁,主要功能如下。
在自身实例化时向属性订阅器(dep)里面添加自己
自身必须是一个 update() 方法
在 dep.notice() 发布通知时,能调用自身的 update() 方法,并触发 Compile 中绑定的回调函数
(4)MVVM 是数据绑定的入口,整合了 Observer、Compile 和 Watcher 三者,通过 Observer 来监听自己的 model 数据变化,
通过 Compile 来解析编译模板指令,最终利用 Watcher 搭建 Observer 和 Compile 之间的通信桥梁,达到数据变化通知视图更新的效果。利用视图交互,变化更新数据 model 变更的双向绑定效果。
Q:请详细说明你对 vue.js 生命周期的理解
A:总共分为 8 个阶段,分别是 beforeCreate、Created、beforeMount、mounted、beforeUpdate、updated、beforeDestroyed、destroyed。
beforeCreate:在实例初始化之后,数据观测者(data observer) 和 event/watcher 事件配置之前调用。
created:在实例创建完成后立即调用。在这一步,实例已完成以下配置:数据观测者、属性和方法的运算,watch/event 事件回调,然而,挂载阶段还没开始,$el 属性目前不可见。
beforeMount:在挂载开始之前调用,相关的 render 函数首次调用。
mounted:el 被新创建的 vm.$el 替代,并且在挂载到实例上之后再调用该钩子。如果 root 实例挂载了 一个文档内元素,当调用mounted 时 vm.$el 也在文档内。
beforeUpdate:在数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。
updated:由于数据更新导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
beforeDestroy:在实例销毁之前调用。在这一步,实例仍然完全可用。
destroyed:在 vue.js 实例销毁后调用。调用后,vue.js 实例指示的所有东西都会解除绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
当使用组件的 keep-alive 功能时,增加以下两个周期。
activated 在 keep-alive 组件激活时调用
deactivated 在 keep-alive 组件停用时调用
vue 2.5.0 版本新增了一个周期钩子:ErrorCaptured,当捕获一个来自子孙组件的错误时调用。
Q:请描述封装 Vue 组件的作用过程
A:组件可以提升整个项目的开发效率,能够把页面抽象成多个相对独立的模块,解决了传统项目开发中效率低、难维护、复用性等问题。
使用 vue.extend 方法创建一个组件,使用 Vue.component 方法注册组件,子组件需要数据,可以在 props 中接收数据,而子组件修改好数据后,若想把数据传递给父组件,可以采用 emit 方法。
Q:你是怎么认识 vuex 的?
A:vuex 可以理解为一种开发模式或框架。它是对 vue.js 框架数据层面的扩展,通过状态(数据源)集中管理驱动组件的变化,应用的状态集中放在 store 中。改变状态的方式是提交 mutations,这是个同步的事务,异步逻辑应该封装在 action 中。
Q:vue-loader 是什么?它的用途有哪些?
A: 它是解析 .vue 文件的一个加载器,可以将 template/js/style 转换成 JavaScript 模块。用途是通过 vue-loader,JavaScript 可以写 EMAScript 6 语法,style 样式可以应用 scss 和 less,template 可以添加 jade 语法等。
Q:请说出 vue.cli 项目的 src 目录中每个文件夹的用法。
A:assets 文件夹存放静态资源,components 存放组件,router 定义路由相关的配置;view 是视图;app.vue 是一个应用主组件;main.js 是入口文件。
Q:在 vue.cli 中怎样使用自定义组件?在使用过程中你遇到过哪些问题?
A:具体步骤如下。
(1)在 components 目录中新增组件文件,脚本一定要导出暴露的接口。
(2)导入需要用到的页面(组件)。
(3)将导入的组件注入 Vue.js 的子组件的 components 属性中。
(4)在 template 的视图中使用自定义组件。
Q:谈谈你对 Vue.js 的 template 编译的理解
A:简而言之,就是首先转换成 AST(Abstract Syntax Tree,抽象语法树),即将源代码语法结构抽象成树状表现形式,然后通过 render 函数进行渲染,并返回 VNode(vue.js 的虚拟 DOM节点)。
详细步骤如下。
(1)通过 compile 编译器把 template 编译成 AST,compile 是 createCompiler 的返回值,createCompiler 用来创建编译器。另外,compile 还负责合并 option。
(2)AST 会经过 generate(将 AST 转化成 render function 字符串的过程)得到 render 函数,render 的返回值是 VNode,VNode是 Vue.js的虚拟 DOM节点,里面有标签名、子节点、文本等。
Q:说一下 Vue.js 中的 MVVM模式
A:MVVM 模式即 Model-View-ViewModel 模式。
Vue.js 是通过数据驱动的,vue.js 实例化对象将 DOM 和数据进行绑定。一旦绑定,DOM 和数据将保持同步,每当数据发生变化,DOM 也会随着变化。
ViewModel 是 Vue.js 的核心,它是 Vue.js 的一个实例。Vue.js 会针对某个 HTML 元素进行实例化,这个 HTML 元素可以是 body,也可以是某个 CSS 选择器所指代的元素。DOM Listeners 和 Data Bindings 是实现双向绑定的关键。DOM Listeners 监听页面所有 View 层中的 DOM 元素,当发生变化时,Model 层的数据随之变化。Data bindings 会监听 Model 层的数据,当数据发生变化时,View 层的 DOM 元素也随之变化。
Q:v-show 指令 和 v-if 指令的区别是什么?
A:v-show 与 v-if 都是条件渲染指令。不同的是,无论 v-show 的值为 true 或 false,元素都会存在于 HTML 页面中;而只有当 v-if 的值为 true 时,元素才会存在于 HTML 页面中。v-show 指令是通过修改元素的 style 属性值实现的。
Q:如何让 CSS 只在当前组件中起作用?
A:在每个 vue.js 组建中都可以定义各自的 CSS、JavaScript 代码。如果希望组件内写的 CSS 只对当前组件起作用,只需要在 style 标签中 添加 scoped 属性,即<style scoped></style>
Q:如何创建 Vue.js 组件?
A:在 Vue.js 中,组件要先注册,然后才能使用。具体代码如下。
1 | <!-- 应用程序 --> |
Q:如何实现路由嵌套?如何进行页面跳转?
A:路由嵌套会将其他组件渲染到该组件内,而不是使整个页面跳转到 router-view 定义组件渲染的位置,要进行页面跳转。就要将页面渲染到根组件内,可做如下配置。
1 | new Vue({ |
首先,实例化根组件,在根组件中定义组件渲染容器,然后挂载路由,当切换路由时,将会切换整个页面。
Q:ref 属性有什么作用?
A:有时候,为了在组件内部可以直接访问组件内部的一些元素,可以定义该属性。此时可以在组件内部通过 this.$refs 属性,更快捷地访问设置 ref 属性的元素。这是一个原生的 DOM 元素,要使用原生 DOM API 操作它们,例如一下代码。
1 | <div id="ickt"> |
Q:Vue.js 是什么?
A:vue.js 是一套构建用户界面的渐进式框架。与其他重量级框架不同的是,Vue.js 采用自下而上增量开发的设计、vue.js 的核心库只关注视图层,并且容易学习,易于与其他库或已有项目整合。另外,Vue.js 完全有能力驱动采用单文件组件以及 Vue.js 生态系统支持的库开发的复杂单页应用。
Vue.js 的目标是通过尽可能简单的 API 实现响应式的数据绑定和组件开发。
Q:描述 Vue.js 的一些特性
A:Vue.js 有以下特性
(1)MVVM 模式
数据模型(Model)发生改变,视图(View)监听到变化,也同步改变;视图(View)发生改变,数据模型(Model)监听到改变,也同步改变。
使用 MVVM 模式有几大好处。
- 低耦合度,视图可以独立于模型变化和修改,一个 ViewModel 可以绑定到不同的视图上,当视图变化时模型可以不变,当模型变化时视图也可以不变。
- 可重用性,可以把一些视图的逻辑放在 ViewModel 里面,让很多视图复用这段视图逻辑。
- 独立开发,开发人员可以专注于业务逻辑和数据的开发,设计人员可以专注于视图的设计
- 可测试性,可以针对 ViewModel 来对视图进行测试。
(2)组件化开发。
(3)指令系统
(4)Vue2.0 开始支持虚拟 DOM
但在 Vue 1.0 中,操作的是真实的 DOM 元素而不是虚拟的 DOM,虚拟 DOM 可以提升页面的渲染性能。
Q:描述 Vue.js 的特点
A:Vue.js 有以下特点。
- 简洁:页面由 HTML 模板 + JSON数据 + vue.js实例化对象组成
- 数据驱动:自动计算属性和追踪依赖的模板表达式
- 组件化:用可复用、解耦的组件来构造页面
- 轻量:代码量小、不依赖其他库
- 快速:精确而有效地批量实现 DOM 更新
- 易获取:可以通过 npm 、bower等多种方式安装,很容易融入。
Q:说说你对 SPA 单页面的理解,它的优缺点分别是什么?
A:SPA(single-page application)仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转,取而代之的是利用路由机制实现 HTML 内容的变换,UI 与用户的交互,避免页面的重新加载。
优点:
用户体验好、快、内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染;
基于上面一点,SPA 相对对服务器压力小;
前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理
缺点:
初次加载耗时多:为实现单页 Web 应用功能及显示效果,需要在加载页面的时候将 JavaScript、CSS 统一加载,部分页面按需加载;
前进后退路由管理:由于单页应用在一个页面中显示所有内容,所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理
SEO难度较大:由于所有的内容都在一个页面中动态替换显示,所以在SEO 上其有着天然的弱势。
以上是我对下列视频及文章的归纳和总结。
《前端程序员面试宝典—张容铭》
关于 vue.js 的面试
install_url
to use ShareThis. Please set it in _config.yml
.