v-show 与 v-if 区别前端
第一题应该是最简单的,提这个问题,也是想让候选人不那么紧张,由于但凡用过 Vue.js,多少知道 v-show 和 v-if 的区别,不然就没得聊了。不过这最简单的一道题,有三个层次,我会逐一追问。首先,基本全部人都会说到:
最后,若是你们若是在自学遇到困难,想找一个前端的学习环境,能够加入咱们的前端学习圈,点击我加入吧,会节约不少时间,减小不少在学习中遇到的难题。面试
v-show 只是 CSS 级别的 display: none; 和 display: block; 之间的切换,而 v-if 决定是否会选择代码块的内容(或组件)。编程
回答这些,已经能够获得 50 分了,紧接着我会追问,何时用 v-show,何时用 v-if ?到这里一部分人会比较吞吐,多是知道,但表达不出来。我比较倾向的回答是:数组
频繁操做时,使用 v-show,一次性渲染完的,使用 v-if,只要意思对就好。缓存
第二问能够获得 80 分了,最后一问不多有人能答上:那使用 v-if 在性能优化上有什么经验?这是一个加分项,要对 Vue.js 的组件编译有必定的理解。说一下指望的答案:性能优化
由于当 v-if="false" 时,内部组件是不会渲染的,因此在特定条件才渲染部分组件(或内容)时,能够先将条件设置为 false,须要时(或异步,好比 $nextTick)再设置为 true,这样能够优先渲染重要的其它内容,合理利用,能够进行性能优化。架构
绑定 class 的数组用法异步
动态绑定 class 应该不陌生吧,这也是最基本的,可是这个问题却有点绕,什么叫绑定 class 的数组用法?咱们看一下,最经常使用的绑定 class 怎么写:ide
前端面试:专一Vue.js常见的问题答疑,掌握了基本上Vue就过关了
绑定 class 的对象用法能知足大部分业务需求,不过,在复杂的场景下,会用到数组,来看示例:函数
<template>
<div :class="classes"></div>
</template>
<script>
export default {
computed: {
classes () {
return [${prefixCls}
,${prefixCls}-${this.type}
,
{
}
];
}
}
}
</script>
前端面试:专一Vue.js常见的问题答疑,掌握了基本上Vue就过关了
示例来自 iView 的 Button 组件,能够看到,数组里,能够是固定的值,还有动态值(对象)的混合。
计算属性和 watch 的区别
回答该题前,通常都会思考一下。不少人会偏题,直接去答计算属性和 watch 怎么用,这是不得分的,由于题目是问区别,并非用法。
计算属性是自动监听依赖值的变化,从而动态返回内容,监听是一个过程,在监听的值变化时,能够触发一个回调,并作一些事情。
因此区别来源于用法,只是须要动态值,那就用计算属性;须要知道值的改变后执行业务逻辑,才用 watch,用反或混用虽然可行,但都是不正确的用法。
这个问题会延伸出几个问题:
computed 是一个对象时,它有哪些选项?
computed 和 methods 有什么区别?
computed 是否能依赖其它组件的数据?
watch 是一个对象时,它有哪些选项?
问题 1,有 get 和 set 两个选项。
问题 2,methods 是一个方法,它能够接受参数,而 computed 不能;computed 是能够缓存的,methods 不会;通常在 v-for 里,须要根据当前项动态绑定值时,只能用 methods 而不能用 computed,由于 computed 不能传参。
问题 3,computed 能够依赖其它 computed,甚至是其它组件的 data。
问题 4,有如下经常使用的配置:
handler 执行的函数
deep 是否深度
immediate 是否当即执行
事件修饰符
这个问题我会先写一段代码:
<custom-component>内容</custom-component>
而后问:怎样给这个自定义组件 custom-component 绑定一个原生的 click 事件?
我一开始并不会问什么是事件修饰符,可是若是候选人说 <custom-component @click="xxx">,就已经错了,说明它对这个没有概念。这里的 @click 是自定义事件 click,并非原生事件 click。绑定原生的 click 是这样的:
<custom-component @click.native="xxx">内容</custom-component>
该问题会引伸不少,好比常见的事件修饰符有哪些?若是你能说上 .exact,说明你是个很爱探索的人,会大大加分哦。
.exact 是 Vue.js 2.5.0 新加的,它容许你控制由精确的系统修饰符组合触发的事件,好比:
<!-- 即便 Alt 或 Shift 被一同按下时也会触发 -->
<button @click.ctrl="onClick">A</button>
<!-- 有且只有 Ctrl 被按下的时候才触发 -->
<button @click.ctrl.exact="onCtrlClick">A</button>
<!-- 没有任何系统修饰符被按下的时候才触发 -->
<button @click.exact="onClick">A</button>
你可能还须要了解经常使用的几个事件修饰符:
.stop
.prevent
.capture
.self
并且,事件修饰符在连用时,是有前后顺序的。
组件中 data 为何是函数
为何组件中的 data 必须是一个函数,而后 return 一个对象,而 new Vue 实例里,data 能够直接是一个对象?
由于组件是用来复用的,JS 里对象是引用关系,这样做用域没有隔离,而 new Vue 的实例,是不会被复用的,所以不存在引用对象的问题。
keep-alive 的理解
这是个概念题,主要考察候选人是否知道这个用法。简单说,就是把一个组件的编译缓存起来。
递归组件的要求
回答这道题,首先你得知道什么是递归组件。而不到 10% 的人知道递归组件。其实在实际业务中用的确实很少,在独立组件中会常用,递归组件的要求是什么?主要有两个:
要给组件设置 name;
要有一个明确的结束条件。
自定义组件的语法糖 v-model 是怎样实现的
这里的 v-model,并非给普通输入框 <input /> 用的那种 v-model,而是在自定义组件上使用。既然是语法糖,就可以还原,咱们先还原一下:
前端面试:专一Vue.js常见的问题答疑,掌握了基本上Vue就过关了
前端面试:专一Vue.js常见的问题答疑,掌握了基本上Vue就过关了
这个组件中,只有一个 props,可是名字叫 value,内部还有一个 currentValue,当改变 currentValue 时,会触发一个自定义事件 @input,并把 currentValue 的值返回。这就是一个 v-model 的语法糖,它要求 props 有一个叫 value 的项,同时触发的自定义事件必须叫 input。这样就能够在自定义组件上用 v-model 了:
<custom-component v-model="value"></custom-component>
若是你能说到 model 选项,绝对是加分的。
Vuex 中 mutations 和 actions 的区别
主要的区别是,actions 能够执行异步。actions 是调用 mutations,而 mutations 来修改 store。
Render 函数
这是比较难的一题了,由于不多有人会去了解 Vue.js 的 Render 函数,由于基本用不到。遇到这个问题,通常能够从这几个方面来回答:
什么是 Render 函数,它的使用场景是什么。
createElement 是什么?
Render 函数有哪些经常使用的参数?
说到 Render 函数,就要说到虚拟 DOM(Virtual DOM),Virtual DOM 并非真正意义上的 DOM,而是一个轻量级的 JavaScript 对象,在状态发生变化时,Virtual DOM 会进行 Diff 运算,来更新只须要被替换的 DOM,而不是所有重绘。
它的使用场景,就是彻底发挥 JavaScript 的编程能力,有时须要结合 JSX 来使用。
createElement 是 Render 函数的核心,它构成了 Vue Virtual DOM 的模板,它有 3 个参数:
前端面试:专一Vue.js常见的问题答疑,掌握了基本上Vue就过关了
经常使用的参数,主要是指上面第二个参数里的值了,这个比较多,得去看 Vue.js 的文档。
怎样理解单向数据流
这个概念出如今组件通讯。父组件是经过 prop 把数据传递到子组件的,可是这个 prop 只能由父组件修改,子组件不能修改,不然会报错。子组件想修改时,只能经过 $emit 派发一个自定义事件,父组件接收到后,由父组件修改。
通常来讲,对于子组件想要更改父组件状态的场景,能够有两种方案:
在子组件的 data 中拷贝一份 prop,data 是能够修改的,但 prop 不能:
前端面试:专一Vue.js常见的问题答疑,掌握了基本上Vue就过关了
2.若是是对 prop 值的转换,可使用计算属性:
前端面试:专一Vue.js常见的问题答疑,掌握了基本上Vue就过关了
若是你能提到 v-model 实现数据的双向绑定、.sync 用法,会大大加分的。
生命周期
Vue.js 生命周期主要有 8 个阶段:
1.建立前 / 后(beforeCreate / created):在 beforeCreate 阶段,Vue 实例的挂载元素 el 和数据对象 data 都为 undefined,还未初始化。在 created 阶段,Vue 实例的数据对象 data 有了,el 尚未。
2.载入前 / 后(beforeMount / mounted):在 beforeMount 阶段,Vue 实例的 $el 和 data 都初始化了,但仍是挂载以前为虚拟的 DOM 节点,data 还没有替换。在 mounted 阶段,Vue 实例挂载完成,data 成功渲染。
3.更新前 / 后(beforeUpdate / updated):当 data 变化时,会触发 beforeUpdate 和 updated 方法。这两个不经常使用,且不推荐使用。
4.销毁前 / 后(beforeDestroy / destroyed):beforeDestroy 是在 Vue 实例销毁前触发,通常在这里要经过 removeEventListener 解除手动绑定的事件。实例销毁后,触发 destroyed。
组件间通讯
这个问题看似简单,却比较大,回答时,能够拆分为几种场景:
1、父子通讯:
父向子传递数据是经过 props,子向父是经过 events(emit);
经过父链子链也能够通讯(parent / $children);
ref也能够访问组件实例;provide / inject API。
2、兄弟通讯:
Bus
Vuex
3、跨级通讯:
Bus;
Vuex;
provide / inject API。
除了常规的通讯方法,最近几篇文章提到的 dispatch / broadcast 和 findComponents 系列方法也能够说的,若是能说到这些,说明你对 Vue.js 组件已经有较深刻的研究。
路由的跳转方式
通常有两种:
经过 <router-link to="home">,router-link 标签会渲染为 标签,在 template 中的跳转都是用这种;
另外一种是编程式导航,也就是经过 JS 跳转,好比 router.push('/home')。
Vue.js 2.x 双向绑定原理
这个问题几乎是面试必问的,回答也是有深有浅。基本上要知道核心的 API 是经过 Object.defineProperty() 来劫持各个属性的 setter / getter,在数据变更时发布消息给订阅者,触发相应的监听回调,这也是为何 Vue.js 2.x 不支持 IE8 的缘由(IE 8 不支持此 API,且没法经过 polyfill 实现)。
什么是 MVVM,与 MVC 有什么区别
MVVM 模式是由经典的软件架构 MVC 衍生来的。当 View(视图层)变化时,会自动更新到 ViewModel(视图模型),反之亦然。View 和 ViewModel 之间经过双向绑定(data-binding)创建联系。与 MVC 不一样的是,它没有 Controller 层,而是演变为 ViewModel。
ViewModel 经过双向数据绑定把 View 层和 Model 层链接了起来,而 View 和 Model 之间的同步工做是由 Vue.js 完成的,咱们不须要手动操做 DOM,只须要维护好数据状态。
感悟
事物由简单到复杂再到简单,技术无止尽,接触的越多,感受本身知道的越少。所谓的心存敬畏吧,共勉!