vue 前端面试题整理

前端优化可以做什么

  • 减少http请求:

合并js和css文件(使用webpack或其它打包工具打包)

小图片使用雪碧图(需要的图片和ui说下,交给ui做就可以)

使用base64表示简单的图片

  • 用内容分发网络cdn

cdn主要用于静态文件,如css,js和flash。

cdn,自动寻找最近的物理机服务器下载web组件

  • 简js和css

使用jsmint和gzip精简文件,css精简技术点:#660066 优化 #606 ,提取 css ,js 公共方法,使用0代替0px

  • 资源体积减少

gzip压缩

js混淆

css压缩

图片压缩

  • 图片加载处理

图片懒加载

首屏加载时进度条的显示

懒加载详细:最初给图片的src设置一个比较简单的图片,然后将图片的真实地址设置给自定义的属性,做一个占位,然后给图片设置监听事件,一旦图片到达视口范围,从图片的自定义属性中获取出真是地址,然后赋值给src,让其进行加载。

首屏加载时进度条的显示:往对于首屏优化后的数据量并不满意的话,同时也不能进一步缩短首屏包的长度了,就可以使用进度条的方式,来提醒用户进行等待。

  • 移动端优化

长列表滚动优化

函数防抖和函数节流

使用touchstart、touchend代替click

HTML的viewport设置

长列表滚动:ios尽量局部滚动,Android尽量全局滚动,同时需要给body添加上-webkit-overflow-scrolling: touch来优化移动段的滚动

防抖:止频繁滑动或者重复点击,当调用动作过了n毫秒后,才会执行该动作,若在这n毫秒内又调用此动作则将重新计算执行时间。

节流:预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新周期。

touchstart、touchend代替click:click在移动端会有300ms延时,事件执行顺序是touchstart->touchmove->touchend->click

HTML的viewport设置:可以防止页面的缩放,来优化性能

http和https的区别

  • https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。

  • http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。

  • http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。

  • http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全

ajax的理解和优缺点与实现过程?

ajax是无须进行刷新页面就可以请求后台的数据的一种方法,通过XmlHttpRequest对象来向服务器发送异步请求,从服务器中获取数据,然后通过js进行操作dom,以此来更新页面内容。

  • 实现过程:

1.创建一个XmlHttpRequest的对象

2.设置响应HTTP请求的回调函数

3.创建一个HTTP请求,指定响应的请求方法、url、参数等

4.发送HTTP请求

5.获取服务端返回的数据

6.使用js操作dom更新页面的内容

  • 缺点:

1.对搜索引擎不友好

2.要实现Ajax下的前后退功能成本较大

3.跨域问题限制

ajax 同步和异步区别?

  • 异步处理就是我们通过事件触发到 ajax,请求服务器,在这个期间无论服务器有没有响应,客户端的其他代码一样可以运行。

  • 同步处理:我们通过事件触发 ajax,请求服务器,在这个期间等待服务器处理请求, 在这个期间客户端不能做任何处理。当 ajax 执行完毕才会继续执行其他代码。

  • 同步:提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事异步: 请求通过事件触发->服务器处理(这是浏览器仍然可以作其他事情)->处理完毕同步需要等待返回结果才能继续,异步不必等待,一般需要监听异步的结果

同步是在一条直线上的队列,异步不在一个队列上 各走各的

jquery 的 async:false,这个属性

默认是true:异步,false:同步

watch和computed区别

Vue中computed和watch比较

computed:计算属性

计算属性是由data中的已知值,得到的一个新值
这个新值只会根据已知值的变化而变化,其他不相关的数据的变化不会影响该新值。
计算属性不在data中,计算属性新值的相关已知值在data中。
别人变化影响我自己。

watch:监听数据的变化

监听data中数据的变化
监听的数据就是data中的已知值
我的变化影响别人

watch 使用场景

1、自适应浏览器(监听浏览器宽高、如果有变化就存在localStorage里面去,或者有变化就通知其他组件改变化)

data() {
     
  return {
     
    height: ''
  }
},
mounted() {
     
  const _this = this
  this.height = document.documentElement.clientHeight
  localStorage.setItem('whVal', JSON.stringify({
     'height': this.height }))
  window.onresize = function temp() {
     
    _this.height = document.documentElement.clientHeight
  }
},
watch: {
     
  // 如果发生改变,这个函数就会运行
  height() {
     
    this.changeFixed(this.width, this.height)
    // eventBus.$emit('onresize', {'height': this.height }) 或者通知其他组件变化
  }
},
methods: {
     
  changeFixed(width, height) {
      // 动态修改样式
    localStorage.setItem('Layout', JSON.stringify({
     'height': height }))
  }
}

2、监控路由对象

new Vue({
     
        el: '#app',
        router: router, //开启路由对象
        watch: {
     
          '$route': function(newroute, oldroute) {
     
            console.log(newroute, oldroute);
            //可以在这个函数中获取到当前的路由规则字符串是什么
            //那么就可以针对一些特定的页面做一些特定的处理
       }
    }
 })

computed使用场景

1、作为过滤器:展开更多
2、作为过滤器: tab切换

// 展开更多
<li v-for="(item,index) in addressListFilter" :class="{'check':checkIndex == index}" @click="checkIndex=index;selectedAddrId=item._id"></li>
<a @click="expand" v-bind:class="{'open':limit>3}">展开更多</a>

data(){
     
  return {
     
    addressList:[],   // 地址列表
    limit:3,   // 限制默认显示3个地址
  checkIndex:0
  }
},
computed:{
     
  addressListFilter(){
     
    return this.addressList.slice(0,this.limit);
  }
},
methods:{
     
  expand(){
       //  点击more更多
    if(this.limit ==3){
     
      this.limit = this.addressList.length;
    }else{
     
      this.limit =3;
    }
  }
}
}

// tab 切换
<span v-for="(item,index) in navList" :key="index" @click="type = index" :class="{'active':type===index}">{
     {
     item}}</span>
<li v-for="(item,index) in taskListfilter" :key="index">
</li>
data() {
     
    return {
     
      navList: ['全部', '实时单', '竞价单'],
      type:0,
      taskList:[]
    }
},
computed: {
     
  taskListfilter() {
     
    switch (this.type) {
     
      case 0:return this.taskList
      case 1:return this.taskList.filter(item => item.type === '实时单')
      case 2:return this.taskList.filter(item => item.type === '竞价单')
      // default :return this.taskList
    }
  }
}

vue的注意规范之v-if 与 v-for 一起使用

https://blog.csdn.net/namechenfl/article/details/83987488
当和 v-if 一起使用时,v-for 的优先级比 v-if 更高。详见列表渲染教程

  • 当 v-if 与 v-for 一起使用时,v-for 具有比 v-if 更高的优先级,这意味着 v-if 将分别重复运行于每个 v-for 循环中,所以,不推荐v-if和v-for同时使用,使用推荐方式:
//不同时使用if与for 或 将if置于for的外层
<ul v-if="shouldShowUsers">
	<li v-for="user in users" :key="user.id" > {
     {
      user.name }} </li>
</ul>

//或 放在计算属性遍历
<ul>
	<li v-for="user in activeUsers" :key="user.id" >{
     {
      user.name }}</li>
</ul>
computed: {
     
	activeUsers: function () {
     
		return this.users.filter(function (user) {
     
		return user.isActive
	})
}
  • 当它们处于同一节点,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。当你想为仅有的一些项渲染节点时,这种优先级的机制会十分有用,如下:

<li v-for="todo in todos" v-if="!todo.isComplete">{
     {
      todo }}</li>

而如果你的目的是有条件地跳过循环的执行,那么可以将 v-if 置于外层元素 (或 )上。如:

<ul v-if="todos.length">
	<li v-for="todo in todos">{
     {
      todo }}</li>
</ul>
<p v-else>No todos left!</p>

浅谈MVC与MVVM

浅谈
MVC、MVP、MVVM模式的概念与区别

  • MVC:MVC是一个编程思想,是一种设计模式

    M: model 数据模型层 提供数据

    V: view 视图层 显示页面

    C: controller 控制层 调用数据渲染视图
    vue 前端面试题整理_第1张图片

button点击事件的触发:View→Controller
获取用户信息事件的触发:Controller→Model
绑定用户信息到View:Controller→View

  • MVVM设计思想

    M:model 数据模块层 提供数据

    V:view 视图层 渲染数据

    VM: ViewModel 视图模型层 调用数据,渲染视图

    由数据来驱动视图(不需要多考虑DOM操作,把重心放在VM上)vue 前端面试题整理_第2张图片
    MVVM模式和以前的MVC模式一样,主要目的是分离(View)和模型(Model),有几大优点:

低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计,使用Expression Blend可以很容易设计界面并生成xaml代码。
可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。

v-if和v-show的区别?

v-if 是“真正的”条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。

v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。

相比之下, v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 进行切换。

一般来说, v-if 有更高的切换开销,而 v-show 有更高的初始渲染开销。因此,如果需要非常频繁地切换,则使用 v-show 较好;如果在运行时条件不太可能改变,则使用 v-if 较好。

总结生命周期钩子函数

生命周期图示:
在这里插入图片描述

1.beforeCreate:在实例初始化之后,**数据观测(data observer) ** 和 event/watcher事件配置 之前被调用,注意是 之前,此时data、watcher、methods统统滴没有。

这个时候的vue实例还什么都没有,但是$route对象是存在的,可以根据路由信息进行重定向之类的操作。

2.created:在实例已经创建完成之后被调用。在这一步,实例已完成以下配置:数据观测(data observer) ,属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el属性目前不可见。

此时 this.$data 可以访问,watcher、events、methods也出现了,若根据后台接口动态改变data和methods的场景下,可以使用。

3.beforeMount:在挂载开始之前被调用,相关的 render 函数 首次被调用。但是render正在执行中,此时DOM还是无法操作的。我打印了此时的vue实例对象,相比于created生命周期,此时只是多了一个$el的属性,然而其值为undefined,

页面渲染时所需要的数据,应尽量在这之前完成赋值。

4.mounted:在挂载之后被调用。在这一步 创建vm.$el并替换el,并挂载到实例上。

此时元素已经渲染完成了,依赖于DOM的代码就放在这里吧~比如监听DOM事件。

5.beforeUpdate:$vm.data更新之后,虚拟DOM重新渲染 和打补丁之前被调用。

你可以在这个钩子中进一步地修改$vm.data,这不会触发附加的重渲染过程。

6.updated:虚拟DOM重新渲染 和打补丁之后被调用。

当这个钩子被调用时,组件DOM的data已经更新,所以你现在可以执行依赖于DOM的操作。但是不要在此时修改data,否则会继续触发beforeUpdate、updated这两个生命周期,进入死循环!

7.activated:被 keep-alive 缓存的组件激活时调用。

8.deactivated:被 keep-alive 缓存的组件停用时调用。

9.beforeDestroy:实例被销毁之前调用。在这一步,实例仍然完全可用。

实例要被销毁了,赶在被销毁之前搞点事情吧哈哈~

10.destroyed:Vue实例销毁后调用。此时,Vue实例指示的所有东西已经解绑定,所有的事件监听器都已经被移除,所有的子实例也已经被销毁

注:beforeMount、mounted、beforeUpdate、updated、beforeDestroy、destroyed、activated、deactivated这几个钩子函数,在服务器端渲染期间不被调用。

for循环结构遍历数组时key的作用

  • key来给每个节点做一个唯一标识
  • key的作用主要是为了高效的更新虚拟DOM,提高性能

javascript 中异步函数与promise then 执行顺序

异步函数
执行顺序

js浮点数计算精度缺失

解决方法: js计算精确度丢失问题解决,js小数失精度的解决方法

例如:

console.log(0.7+0.1) //输出:1 0.7999999999999999

console.log(1.897+2.091) //输出:3.9880000000000004

你可能感兴趣的:(vue.js,es6)