2019年度web前端面试题总结(主要为Vue面试题)


Posted in Javascript onJanuary 12, 2020

毕业之后就在一直合肥小公司工作,没有老司机、没有技术氛围,在技术的道路上我只能独自摸索。老板也只会画饼充饥,前途一片迷茫看不到任何希望。于是乎,我果断辞职,在新年开工之际来到杭州,这里的互联网公司应该是合肥的几十倍吧。。。。

刚来3天,面试了几家公司,有些规模比较小,有些是创业公司,也有些已经发展的不错了;今天把最近的面试题目做个汇总,也给自己复个盘,由于我的技术栈主要为Vue,所以大部分题目都是Vue开发相关的。

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

MVVM分为Model、View、ViewModel三者。

Model 代表数据模型,数据和业务逻辑都在Model层中定义;

View 代表UI视图,负责数据的展示;

ViewModel 负责监听 Model 中数据的改变并且控制视图的更新,处理用户交互操作;

Model 和 View 并无直接关联,而是通过 ViewModel 来进行联系的,Model 和 ViewModel 之间有着双向数据绑定的联系。因此当 Model 中的数据改变时会触发 View 层的刷新,View 中由于用户交互操作而改变的数据也会在 Model 中同步。

这种模式实现了 Model 和 View 的数据自动同步,因此开发者只需要专注对数据的维护操作即可,而不需要自己操作 dom。

2. Vue 有哪些指令?

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

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

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

4. 简述Vue的响应式原理

当一个Vue实例创建时,vue会遍历data选项的属性,用 Object.defineProperty 将它们转为 getter/setter并且在内部追踪相关依赖,在属性被访问和修改时通知变化。

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

2019年度web前端面试题总结(主要为Vue面试题)

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

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

具体思路:父组件通过 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'
  }
 }
})

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

2019年度web前端面试题总结(主要为Vue面试题)

2019年度web前端面试题总结(主要为Vue面试题)

我们在父组件中做了两件事,一是给子组件传入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 已经成功添加,但是视图并未刷新:

2019年度web前端面试题总结(主要为Vue面试题)

2019年度web前端面试题总结(主要为Vue面试题)

原因在于在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处理成一个响应式的属性,此时视图也会跟着改变了:

2019年度web前端面试题总结(主要为Vue面试题)

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)

2019年度web前端面试题总结(主要为Vue面试题)

2019年度web前端面试题总结(主要为Vue面试题)

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

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

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

加一个首屏 loading 图,提升用户体验;

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

减少 HTTP 请求数量

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

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

合并 CSS 和 JS 文件:现在前端有很多工程化打包工具,如:grunt、gulp、webpack等。为了减少 HTTP 请求数量,可以通过这些工具再发布前将多个 CSS 或者 多个 JS 合并成一个文件。

采用 lazyLoad:俗称懒加载,可以控制网页上的内容在一开始无需加载,不需要发请求,等到用户操作真正需要的时候立即加载出内容。这样就控制了网页资源一次性请求数量。

控制资源文件加载优先级

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

一般情况下都是 CSS 在头部,JS 在底部。

利用浏览器缓存

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

减少重排(Reflow)

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

减少 Reflow,如果需要在 DOM 操作时添加样式,尽量使用 增加 class 属性,而不是通过 style 操作样式。

减少 DOM 操作

图标使用 IconFont 替换

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

大致可以分为如下7步:

输入网址;

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

与web服务器建立TCP连接;

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

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

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

生成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();

目前来看公司面试的问题还是比较基础的,但是对于某些只追求会用并不研究其原理的同学来说可能就没那么容易了。所以大家不仅要追求学习的广度,更要追求深度。

现在的前端有学不完的JS库,倒弄不完的兼容问题,面对层出不穷的新知识真是学不动了

Javascript 相关文章推荐
Confirmer JQuery确认对话框组件
Jun 09 Javascript
基于jquery的3d效果实现代码
Mar 23 Javascript
10个基于浏览器的JavaScript调试工具分享
Feb 07 Javascript
利用javascript实现web页面中指定区域打印
Oct 30 Javascript
jQuery 文本框得失焦点的简单实例
Feb 19 Javascript
jQuery 生成svg矢量二维码
Aug 09 Javascript
jQuery源码解读之extend()与工具方法、实例方法详解
Mar 30 jQuery
JS字符串按逗号和回车分隔的方法
Apr 25 Javascript
JS中mouseup事件丢失的原因与解决办法
Jun 14 Javascript
用vue封装插件并发布到npm的方法步骤
Oct 18 Javascript
layui异步加载table表中某一列数据的例子
Sep 16 Javascript
vue中get请求如何传递数组参数的方法示例
Nov 08 Javascript
html2canvas属性和使用方法以及如何使用html2canvas将HTML内容写入Canvas生成图片
Jan 12 #Javascript
ES2020 新特性(种草)
Jan 12 #Javascript
在微信小程序中渲染HTML内容3种解决方案及分析与问题解决
Jan 12 #Javascript
es6 for循环中let和var区别详解
Jan 12 #Javascript
js 计数排序的实现示例(升级版)
Jan 12 #Javascript
JS实现动态无缝轮播
Jan 11 #Javascript
原生js实现无缝轮播图
Jan 11 #Javascript
You might like
PHP日期处理函数 整型日期格式
2011/01/12 PHP
PHP 在5.1.* 和5.2.*之间 PDO数据库操作中的不同之处小结
2012/03/07 PHP
php cookie 详解使用实例
2016/11/03 PHP
实现PHP中session存储及删除变量
2018/10/15 PHP
奇妙的js
2007/09/24 Javascript
有道JavaScript监听浏览器的问题
2010/06/23 Javascript
原生javascript实现图片轮播效果代码
2010/09/03 Javascript
JavaScript 代码压缩工具小结
2012/02/27 Javascript
jQuery实现仿百度帖吧头部固定导航效果
2015/08/07 Javascript
灵活的理解JavaScript中的this指向
2016/02/25 Javascript
VUEJS实战之修复错误并且美化时间(2)
2016/06/13 Javascript
angularJS 如何读写缓冲的方法(推荐)
2016/08/06 Javascript
JS正则匹配中文的方法示例
2017/01/06 Javascript
Vue的Class与Style绑定的方法
2017/09/01 Javascript
js Date()日期函数浏览器兼容问题解决方法
2017/09/12 Javascript
使用imba.io框架得到比 vue 快50倍的性能基准
2019/06/17 Javascript
jQuery实现动态向上滚动
2020/12/21 jQuery
windows下wxPython开发环境安装与配置方法
2014/06/28 Python
星球大战与Python之间的那些事
2016/01/07 Python
谈谈Python进行验证码识别的一些想法
2016/01/25 Python
python 爬虫出现403禁止访问错误详解
2017/03/11 Python
Python内置random模块生成随机数的方法
2019/05/31 Python
python写入文件自动换行问题的方法
2019/07/05 Python
Python Django框架防御CSRF攻击的方法分析
2019/10/18 Python
基于python+selenium的二次封装的实现
2020/01/06 Python
python实现梯度法 python最速下降法
2020/03/24 Python
英国办公家具网站:Furniture At Work
2019/10/07 全球购物
安全责任书范本
2014/04/15 职场文书
乡镇创先争优活动总结
2014/08/28 职场文书
2014年学生党支部工作总结
2014/12/20 职场文书
春季运动会开幕词
2015/01/28 职场文书
2015年驾驶员工作总结
2015/04/29 职场文书
上甘岭观后感
2015/06/10 职场文书
七年级之开学家长寄语35句
2019/09/05 职场文书
Python实现科学占卜 让视频自动打码
2022/04/09 Python
Java设计模式之代理模式
2022/04/22 Java/Android