前端面试题汇总(主要为 Vue)

前端面试题汇总

1. 谈谈你对MVVM开发模式的理解

MVVM分为Model、View、ViewModel三者。javascript

1)Model:表明数据模型,数据和业务逻辑都在Model层中定义;css

2)View:表明UI视图,负责数据的展现;html

3)ViewModel:负责监听Model中数据的改变而且控制视图的更新,处理用户交互操做;前端

Model和View并没有直接关联,而是经过ViewModel来进行联系的,Model和ViewModel之间有着双向数据绑定的联系。所以当Model中的数据改变时会触发View层的刷新,View中因为用户交互操做而改变的数据也会在Model中同步。vue

这种模式实现了Model和View的数据自动同步,所以开发者只须要专一对数据的维护操做便可,而不须要本身操做dom。java

2. Vue 有哪些指令?

v-html、v-show、v-if、v-for等等。webpack

3. v-if 和 v-show 有什么区别?

v-show 仅仅控制元素的显示方式,将 display 属性在 block 和 none 来回切换;而v-if会控制这个 DOM 节点的存在与否。当咱们须要常常切换某个元素的显示/隐藏时,使用v-show会更加节省性能上的开销;当只须要一次显示或隐藏时,使用v-if更加合理。web

4. 简述Vue的响应式原理

当一个Vue实例建立时,vue会遍历data选项的属性,用 Object.defineProperty 将它们转为getter/setter而且在内部追踪相关依赖,在属性被访问和修改时通知变化。 每一个组件实例都有相应的watcher程序实例,它会在组件渲染的过程当中把属性记录为依赖,以后当依赖项的setter被调用时,会通知watcher从新计算,从而导致它关联的组件得以更新。面试

 

5. Vue中如何在组件内部实现一个双向数据绑定?

假设有一个输入框组件,用户输入时,同步父组件页面中的数据。gulp

具体思路:父组件经过props传值给子组件,子组件经过 $emit 来通知父组件修改相应的props值,具体实现以下:

import Vue from 'vue'

const component = {
 props: ['value'],
 template: `
   <div>
     <input type="text" @input="handleInput" :value="value">
   </div>
 `,
 data () {
   return {
   }
 },
 methods: {
   handleInput (e) {
     this.$emit('input', e.target.value)
   }
 }
}
new Vue({
 components: {
   CompOne: component
 },
 el: '#root',
 template: `
   <div>
     <comp-one :value1="value" @input="value = arguments[0]"></comp-one>
   </div>
 `,
 data () {
   return {
     value: '123'
   }
 }
})

  

能够看到,当输入数据时,父子组件中的数据是同步改变的:

 

咱们在父组件中作了两件事,一是给子组件传入props,二是监听input事件并同步本身的value属性。那么这两步操做可否再精简一下呢?答案是能够的,你只须要修改父组件:

template: `
   <div>
     <!--<comp-one :value1="value" @input="value = arguments[0]"></comp-one>-->
     <comp-one v-model="value"></comp-one>
   </div>
 `

v-model 实际上会帮咱们完成上面的两步操做。

6. Vue中如何监控某个属性值的变化?

好比如今须要监控data中, obj.a 的变化。Vue中监控对象属性的变化你能够这样:

watch: {
     obj: {
     handler (newValue, oldValue) {
       console.log('obj changed')
     },
     deep: true
   }
 }

deep属性表示深层遍历,可是这么写会监控obj的全部属性变化,并非咱们想要的效果,因此作点修改:

watch: {
  'obj.a': {
     handler (newName, oldName) {
       console.log('obj.a changed')
     }
  }
 }

还有一种方法,能够经过computed 来实现,只须要:

computed: {
   a1 () {
     return this.obj.a
   }
}

利用计算属性的特性来实现,当依赖改变时,便会从新计算一个新值。

7. Vue中给data中的对象属性添加一个新的属性时会发生什么,如何解决?

示例:

<template>
 <div>
   <ul>
     <li v-for="value in obj" :key="value">
       {{value}}
     </li>
   </ul>
   <button @click="addObjB">添加obj.b</button>
 </div>
</template>
<script>
export default {
 data () {
   return {
     obj: {
       a: 'obj.a'
     }
   }
 },
 methods: {
   addObjB () {
     this.obj.b = 'obj.b'
     console.log(this.obj)
   }
 }
}
</script>
<style></style>

点击button会发现, obj.b 已经成功添加,可是视图并未刷新:

缘由在于在Vue实例建立时, obj.b 并未声明,所以就没有被Vue转换为响应式的属性,天然就不会触发视图的更新,这时就须要使用Vue的全局api—— $set()

addObjB () {
     // this.obj.b = 'obj.b'
     this.$set(this.obj, 'b', 'obj.b')
     console.log(this.obj)
}

$set() 方法至关于手动的去把 obj.b 处理成一个响应式的属性,此时视图也会跟着改变了:

8. delete和Vue.delete删除数组的区别

delete只是被删除的元素变成了 empty/undefined 其余的元素的键值仍是不变。

Vue.delete 直接删除了数组 改变了数组的键值。

var a=[1,2,3,4]
var b=[1,2,3,4]
delete a[1]
console.log(a)
this.$delete(b,1)
console.log(b)

  

9.如何优化SPA应用的首屏加载速度慢的问题?

1)将公用的JS库经过script标签外部引入,减少 app.bundel 的大小,让浏览器并行下载资源文件,提升下载速度;

2)在配置 路由时,页面和组件使用懒加载的方式引入,进一步缩小 app.bundel 的体积,在调用某个组件时再加载对应的js文件;

3)加一个首屏loading图,提高用户体验;

10. 前端如何优化网站性能?

1)减小 HTTP 请求数量

在浏览器与服务器进行通讯时,主要是经过 HTTP 进行通讯。浏览器与服务器须要通过三次握手,每次握手须要花费大量时间。并且不一样浏览器对资源文件并发请求数量有限(不一样浏览器容许并发数),一旦 HTTP 请求数量达到必定数量,资源请求就存在等待状态,这是很致命的,所以减小 HTTP 的请求数量能够很大程度上对网站性能进行优化。

CSS Sprites

国内俗称CSS精灵,这是将多张图片合并成一张图片达到减小HTTP请求的一种解决方案,能够经过CSS的background属性来访问图片内容。这种方案同时还能够减小图片总字节数。

合并 CSS 和 JS 文件

如今前端有不少工程化打包工具,如:grunt、gulp、webpack等。为了减小 HTTP 请求数量,能够经过这些工具再发布前将多个CSS或者多个JS合并成一个文件。

采用 lazyLoad

俗称懒加载,能够控制网页上的内容在一开始无需加载,不须要发请求,等到用户操做真正须要的时候当即加载出内容。这样就控制了网页资源一次性请求数量。

2)控制资源文件加载优先级

浏览器在加载HTML内容时,是将HTML内容从上至下依次解析,解析到link或者script标签就会加载href或者src对应连接内容,为了第一时间展现页面给用户,就须要将CSS提早加载,不要受 JS 加载影响。

通常状况下都是CSS在头部,JS在底部。

3)利用浏览器缓存

浏览器缓存是将网络资源存储在本地,等待下次请求该资源时,若是资源已经存在就不须要到服务器从新请求该资源,直接在本地读取该资源。

4)减小重排(Reflow)

基本原理:重排是DOM的变化影响到了元素的几何属性(宽和高),浏览器会从新计算元素的几何属性,会使渲染树中受到影响的部分失效,浏览器会验证 DOM 树上的全部其它结点的visibility属性,这也是Reflow低效的缘由。若是Reflow的过于频繁,CPU使用率就会急剧上升。

减小Reflow,若是须要在DOM操做时添加样式,尽可能使用 增长class属性,而不是经过style操做样式。

5)减小 DOM 操做
6)图标使用 IconFont 替换

11. 网页从输入网址到渲染完成经历了哪些过程?

大体能够分为以下7步:

1)输入网址;

2)发送到DNS服务器,并获取域名对应的web服务器对应的ip地址;

3)与web服务器创建TCP链接;

4)浏览器向web服务器发送http请求;

5)web服务器响应请求,并返回指定url的数据(或错误信息,或重定向的新的url地址);

6)浏览器下载web服务器返回的数据及解析html源文件;

7)生成DOM树,解析css和js,渲染页面,直至显示完成;

12. jQuery获取的dom对象和原生的dom对象有何区别?

js原生获取的dom是一个对象,jQuery对象就是一个数组对象,其实就是选择出来的元素的数组集合,因此说他们二者是不一样的对象类型不等价。

原生DOM对象转jQuery对象:

var box = document.getElementById('box');
var $box = $(box);
jQuery对象转原生DOM对象:
var $box = $('#box');
var box = $box[0];

13. jQuery如何扩展自定义方法

(jQuery.fn.myMethod=function () {
      alert('myMethod');
})
// 或者:
(function ($) {
       $.fn.extend({
            myMethod : function () {
                 alert('myMethod');
            }
       })
})(jQuery)

使用:

$("#div").myMethod();

相关文章
相关标签/搜索