05.19 Vue2.0复仇者联盟之无限面试题

Vue2.0复仇者联盟之无限面试题

大家知道Vue全家桶里面强力成员很多,比如vue的同门师兄弟:vuex负责状态管理,vue-router负责前端路由,devtools extension帮助开发者调试,vue-cli配置webpack模板,axios负责网络请求,它跟vue的强力对手Angular有很大渊源,来自饿了么的element-ui使得开发者使用Vue做项目更容易了。

而面试官一般会围绕这些方面的问题考察面试者的vue实战经验。为了让大家更有底气地跟面试官说做过vue项目,本文跟大家一起分多篇文章将这些关于vue实战的相关知识点一网打尽,并长期更新。

Vue相关概念

background

Vue 是 2016 年发展最为迅速的 JS 框架之一。

Vue 将自己描述为一款“用于构建直观,快速和组件化交互式界面的 MVVM 框架”。

它于 2014 年 2 月首次由 Google 前员工 Evan You 发布。

尤其是考虑到 Vue 在没有大公司的支持的情况下,作为一个人开发的框架还能获得这么多的吸引力,这无疑是非常成功的。

尤雨溪目前有一个包含数十名核心开发者的团队。2016 年,版本 2 发布。Vue 被阿里巴巴,百度,Expedia,任天堂,GitLab 使用 — 可以在 madewithvuejs.com 找到一些小型项目的列表。

feature

Vue 擅长处理组件:小型的无状态的函数接收输入和返回元素作为输出。

Vue 使用 Javascript ES5 或 ES6。

模板-HTML

Vue 具有“单个文件组件”。这似乎是对于关注分离的权衡 - 模板,脚本和样式在一个文件中,但在三个不同的有序部分中。这意味着你可以获得语法高亮,CSS 支持以及更容易使用预处理器(如 Jade 或 SCSS)

Vue 相比于Angular和React是最轻量的。

Vue.js 完美的兼顾了它将为你做什么和你需要做什么。(...)Vue.js 始终是可及的,一个坚固,但灵活的安全网,保证编程效率和把操作 DOM 造成的痛苦降到最低。

Vue 使用了MVVM模式,支持单向绑定和双向绑定

Vue 的体积为23K

Vue 使用了虚拟 DOM(Virtual DOM)

Vue 学习起来很容易。公司转向 Vue 是因为它对初级开发者来说似乎更容易一些。有了 Vue,初级和高级开发人员之间的差距缩小了,他们可以更轻松地协作,代码会更简洁,减少 bug,减少解决问题的时间。

vue的双向数据绑定原理

vue是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调,达到监听数据变动的目的。

Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是为什么 Vue 不支持 IE8 以及更低版本浏览器的原因。

这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。这里需要注意的问题是浏览器控制台在打印数据对象时 getter/setter 的格式化并不同,所以你可能需要安装 vue-devtools 来获取更加友好的检查接口。

每个组件实例都有相应的 watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。

Vue2.0复仇者联盟之无限面试题

检测变化的注意事项

受现代 JavaScript 的限制 (以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。例如:

var vm = new Vue({

data:{

a:1

}

})

// `vm.a` 是响应的

vm.b = 2

// `vm.b` 是非响应的

Vue 不允许在已经创建的实例上动态添加新的根级响应式属性 (root-level reactive property)。然而它可以使用 Vue.set(object, key, value) 方法将响应属性添加到嵌套的对象上:

Vue.set(vm.someObject, 'b', 2)

您还可以使用 vm.$set 实例方法,这也是全局 Vue.set 方法的别名:

this.$set(this.someObject,'b',2)

有时你想向已有对象上添加一些属性,例如使用 Object.assign() 或 _.extend() 方法来添加属性。但是,添加到对象上的新属性不会触发更新。在这种情况下可以创建一个新的对象,让它包含原对象的属性和新的属性:

// 代替 `Object.assign(this.someObject, { a: 1, b: 2 })`

this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })

由于 JavaScript 的限制,Vue 不能检测以下变动的数组:

当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue

当你修改数组的长度时,例如:vm.items.length = newLength

举个例子:

var vm = new Vue({

data: {

items: ['a', 'b', 'c']

}

})

vm.items[1] = 'x' // 不是响应性的

vm.items.length = 2 // 不是响应性的

为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue 相同的效果,同时也将触发状态更新:

// Vue.set

Vue.set(vm.items, indexOfItem, newValue)

// Array.prototype.splice

vm.items.splice(indexOfItem, 1, newValue)

你也可以使用 vm.$set 实例方法,该方法是全局方法 Vue.set 的一个别名:

vm.$set(vm.items, indexOfItem, newValue)

为了解决第二类问题,你可以使用 splice:

vm.items.splice(newLength)

由于 Vue 不允许动态添加根级响应式属性,所以你必须在初始化实例前声明根级响应式属性,哪怕只是一个空值。

异步更新队列

可能你还没有注意到,Vue 异步执行 DOM 更新。只要观察到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作上非常重要。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。Vue 在内部尝试对异步队列使用原生的 Promise.then 和 MessageChannel,如果执行环境不支持,会采用 setTimeout(fn, 0) 代替。

例如,当你设置 vm.someData = 'new value' ,该组件不会立即重新渲染。当刷新队列时,组件会在事件循环队列清空时的下一个“tick”更新。多数情况我们不需要关心这个过程,但是如果你想在 DOM 状态更新后做点什么,这就可能会有些棘手。虽然 Vue.js 通常鼓励开发人员沿着“数据驱动”的方式思考,避免直接接触 DOM,但是有时我们确实要这么做。为了在数据变化之后等待 Vue 完成更新 DOM ,可以在数据变化之后立即使用 Vue.nextTick(callback) 。这样回调函数在 DOM 更新完成后就会调用。例如:

{{message}}

var vm = new Vue({

el: '#example',

data: {

message: '123'

}

})

vm.message = 'new message' // 更改数据

vm.$el.textContent === 'new message' // false

Vue.nextTick(function () {

vm.$el.textContent === 'new message' // true

})

在组件内使用 vm.$nextTick() 实例方法特别方便,因为它不需要全局 Vue ,并且回调函数中的 this 将自动绑定到当前的 Vue 实例上:

Vue.component('example', {

template: '{{ message }}',

data: function () {

return {

message: '没有更新'

}

},

methods: {

updateMessage: function () {

this.message = '更新完成'

console.log(this.$el.textContent) // => '没有更新'

this.$nextTick(function () {

console.log(this.$el.textContent) // => '更新完成'

})

}

}

})

面试题大战:

1、vuejs与angularjs以及react的区别?

1)与AngularJS的区别

相同点:

  • 都支持指令:内置指令和自定义指令。
  • 都支持过滤器:内置过滤器和自定义过滤器。
  • 都支持双向数据绑定。
  • 都不支持低端浏览器。

不同点:

  • AngularJS的学习成本高,比如增加了Dependency Injection特性,而Vue.js本身提供的API都比较简单、直观。
  • 在性能上,AngularJS依赖对数据做脏检查,所以Watcher越多越慢。
  • Vue.js使用基于依赖追踪的观察并且使用异步队列更新。所有的数据都是独立触发的。
  • 对于庞大的应用来说,这个优化差异还是比较明显的。

2)与React的区别

相同点:

  • React采用特殊的JSX语法,Vue.js在组件开发中也推崇编写.vue特殊文件格式,对文件内容都有一些约定,两者都需要编译后使用。
  • 中心思想相同:一切都是组件,组件实例之间可以嵌套。
  • 都提供合理的钩子函数,可以让开发者定制化地去处理需求。
  • 都不内置列数AJAX,Route等功能到核心包,而是以插件的方式加载。
  • 在组件开发中都支持mixins的特性。

不同点:

  • React依赖Virtual DOM,而Vue.js使用的是DOM模板。React采用的Virtual DOM会对渲染出来的结果做脏检查。
  • Vue.js在模板中提供了指令,过滤器等,可以非常方便,快捷地操作Virtual DOM。

2、请谈谈Vue中的MVVM模式

MVVM全称是Model-View-ViewModel

Vue是以数据为驱动的,Vue自身将DOM和数据进行绑定,一旦创建绑定,DOM和数据将保持同步,每当数据发生变化,DOM会跟着变化。 ViewModel是Vue的核心,它是Vue的一个实例。Vue实例时作用域某个HTML元素上的这个HTML元素可以是body,也可以是某个id所指代的元素。

DOMListeners和DataBindings是实现双向绑定的关键。DOMListeners监听页面所有View层DOM元素的变化,当发生变化,Model层的数据随之变化;DataBindings监听Model层的数据,当数据发生变化,View层的DOM元素随之变化。

3、数组和对象的什么操作vue不会响应?

由于 JavaScript 的限制, Vue 不能检测以下变动的数组:

1 当你利用索引直接设置一个项时,例如: vm.items[indexOfItem] = newValue

2 当你修改数组的长度时,例如: vm.items.length = newLength

受现代 JavaScript 的限制 (以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除。

Vue基础知识

1、双花括号

语法:

{{表达式}}

作用:

将表达式执行的结果 输出当调用元素的innerHTML中;还可以将数据绑定到视图

2、指令-循环指令

基本语法1:

基本语法2:

作用:

在遍历array这个集合时,将临时变量保存在tmp中,创建多个any标签

3、指令-选择指令

语法:

作用:

根据表达式执行结果的真假,来决定是否要将当前的这个元素 挂载到DOM树

4、指令-事件绑定

语法:

作用:

给指定的元素 将handleEvent的方法绑定给指定eventName事件

5、指令-属性绑定

基本语法:

补充,支持简写:

作用:

将表达式执行的结果 绑定 到当前元素的myProp属性

动态样式绑定

动态样式绑定

动态样式类绑定

动态样式类的绑定

6、指令-双向数据绑定

方向1:数据绑定到视图

方向2:将视图中(表单元素)用户操作的结果绑定到数据

基本语法:

表单元素>

生命周期

四个阶段:

create 准备工作 (数据的初始化。。。)

mount 挂载前后针对元素进行操作

update 数据发生变化,

destroy 清理工作 (关闭定时器、集合清空..)

beforeCreate/created

beforeMount/mounted

beforeUpdate/updated

beforeDestroy/destroyed

组件间通信

1、父与子通信 (props down)

1.发送

2.接受

到son组件:

Vue.component('son',{

props:['myName'],

template:`

{{myName}}

`

})

2、子与父通信 (events up)

1.绑定

methods:{

handleEvent:function(msg){}

}

2.触发

子组件内部:

this.$emit(‘customEvent’,100);

3、ref(reference 引用/参考 外号)

帮助在父组件中 得到子组件中的数据、方法。

1.指定ref属性

2.根据ref得到子组件实例

this.$refs.mySon

4、$parent

this.$parent得到父组件的实例

5、兄弟组件通信

1.var bus = new Vue();

2.接收方

bus.$on('eventName',function(msg){})

3.发送方

bus.$emit('eventName',123);

组件创建的方式

1、直接在template属性中指定模板内容

1.全局组件

Vue.component

2.局部组件

{

components:{

'my-footer':{template:``}

}

}

2、.vue结尾的文件

<template>

<script>

<style>

3、单独指定一个模板内容

Vue.component('',{

template:'#myContent'

})

面试题大战:

1、v-model是什么?怎么使用? vue中标签怎么绑定事件?

可以实现双向绑定,指令(v-class、v-for、v-if、v-show、v-on)。vue的model层的data属性。绑定事件:

2、mvvm框架是什么?它和其它框架(jquery)的区别是什么?哪些场景适合?

一个model+view+viewModel框架,数据模型model,viewModel连接两个

区别:vue数据驱动,通过数据来显示视图层而不是节点操作。

场景:数据操作比较多的场景,更加便捷

3、说出至少4种vue当中的指令和它的用法?

v-if:判断是否隐藏;v-for:数据循环出来;v-bind:class:绑定一个属性;v-model:实现双向绑定

4、v-show和v-if指令的共同点和不同点?

v-show指令是通过修改元素的displayCSS属性让其显示或者隐藏

v-if指令是直接销毁和重建DOM达到让元素显示和隐藏的效果

5、如何让CSS只在当前组件中起作用?

将当前组件的


分享到:


相關文章: