大家知道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 重新计算,从而致使它关联的组件得以更新。
检测变化的注意事项
受现代 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 更新完成后就会调用。例如:
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只在当前组件中起作用?
将当前组件的
閱讀更多 互聯網技能圖譜 的文章