2020年前端面试题(二)之VUE篇

1.常用的vue指令有哪些:

​ v-if

​ v-else

​ v-on

​ v-bind

​ v-show

​ v-model

2.浏览器页面之前如何传参

  1. query
    1. url?a=xxx&b=yyy
    2. query+path
    3. query+name
  2. params
    1. 注册:url/:id
    2. 请求:url/123
    3. params+name
  3. props
    1. 布尔值
    2. 对象
    3. 函数
  4. meta
    1. 路由元信息

3.父子组件互相调用方法

父组件主动获取子组件的数据和方法:

1.调用子组件的时候定义一个ref,其中children为子组件别名

2.在父组件脚本里面通过

​ this.$refs.header.属性

​ this.$refs.header.方法

子组件主动获取父组件的数据和方法,在子组件脚本中通过如下方式获取:

​ this.$parent.数据

​ this.$parent.方法

在脚本中获取另一个组件的值时展示在页面,需要在mounted属性中加一个方法,初始化要展示的值,

4.vue设计模式请简述

MVVM的模式

由 Model、View、ViewModel 三部分构成,Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展现出来,ViewModel 是一个同步View 和 Model的对象。

在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上

ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

5.组件保持状态怎么做

  1. 组件没有没销毁

    1. keep-alive
  2. 组件被销毁的情况

    1. 在页面刷新的时候,将数据存至sessionStorage
    2. 页面刷新的时候,可以将组件的状态发送给服务器保存,组件再次 加载的时候发请求获取之前的状态数据

6.图片懒加载原理,如何实现

原理:

图片懒加载的原理很简单,就是我们先设置图片的data-set属性(当然也可以是其他任意的,只要不会发送http请求就行了,作用就是为了存取值)值为其图片路径,由于不是src,所以不会发送http请求。 然后我们计算出页面scrollTop的高度和浏览器的高度之和, 如果图片举例页面顶端的坐标Y(相对于整个页面,而不是浏览器窗口)小于前两者之和,就说明图片就要显示出来了(合适的时机,当然也可以是其他情况),这时候我们再将 data-set 属性替换为 src 属性即可。

实现:

我一般使用第三方库lazysizes

这个开源的库也有6406个star,好处在于他是原生js实现,不依赖于jquery/zepto, 自动监测可能发生变化的 lazyload 节点,不需要额外初始化, 并且支持响应式图片 srcset, 性能高,改善seo。强烈推荐!!!

7.vue路由模式的区别

在vue-router路由对象中,路由有两种模式: hash 和 history,而默认的是hash模式,hash模式背后的原理是:

hash路由

  • 监听路由的变化:onhashchange事件,只有#后面的地址发生变化,可以在window对象上监听这个事件:
window.onhashchange = function(event) {
    console.log(event.oldURL, event.newURL);
    let hash = loaction.hash  //通过location对象来获取hash地址
    console.log(hash)    // "#/notebooks/260827/list"  从#号开始
}

因为hash发生变化的url都会被浏览器记录下来,从而你会发现浏览器的前进后退都可以用

  • 随着history api的到来,前端路由开始进化了,前面的hashchange,你只能改变#后面的url片段,而history api则给了前端完全的自由
    history api可以分为两大部分,切换和修改,参考MDN

切换历史状态

包括back,forward,go三个方法,对应浏览器的前进,后退,跳转操作,有同学说了,(谷歌)浏览器只有前进和后退,没有跳转,嗯,在前进后退上长按鼠标,会出来所有当前窗口的历史记录,从而可以跳转(也许叫跳更合适):

history.go(-2);//后退两次
history.go(2);//前进两次
history.back(); //后退
hsitory.forward(); //前进

修改历史状态
包括了history.pushState(),history.replaceState()两个方法,这两个方法接收三个参数:stateObj,title,url

history.pushState({color:'red'}, 'red', 'red'})
history.back();

history.forward();
通过pushstate把页面的状态保存在state对象中,当页面的url再变回这个url时,可以通过event.state取到这个state对象.

8.vue之间组件通信方式

https://segmentfault.com/a/1190000019208626#item-6

9.watch和computed的区别,data和computed的区别

计算属性computed :

  1. 支持缓存,只有依赖数据发生改变,才会重新进行计算
  2. 不支持异步,当computed内有异步操作时无效,无法监听数据的变化
  3. computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值
  4. 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed
  5. 如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。

侦听属性watch:

  1. 不支持缓存,数据变,直接会触发相应的操作;
  2. watch支持异步;
  3. 监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
  4. 当一个属性发生变化时,需要执行对应的操作;一对多;
  5. 监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数,
    1. immediate:组件加载立即触发回调函数执行,
    2. deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变动不需要这么做。注意:deep无法监听到数组的变动和对象的新增,参考vue数组变异,只有以响应式的方式触发才会被监听到。
data 和 computed 最核心的区别在于 data 中的属性并不会随赋值变量的改动而改动,而computed 会。

10.vue中路由传参的方式

和2一样

11.vue的生命周期,哪个生命周期可以看到this,第一个发送请求的是哪一个

  1. beforeCreate
    1. 实例组件刚创建,元素DOM和数据都还没有初始化,暂时不知道能在这个周期里面进行生命操作。
  2. created
    1. 数据data已经初始化完成,方法也已经可以调用,但是DOM未渲染。有人问了,请求都是异步的,并不会阻碍实例加载。这是我个人水平的问题,这边改正,在这个周期里面,请求因为是异步的,不会阻碍实例加载,除非是那些同步操走才会导致页面空白。这样说来,在这个周期里面进行请求,渲染速度反而会更快。
    2. 第一个发送ajax请求的地方,注意不要将运算量特别大的代码或者多个请求操作放置在此,因为会影响页面的渲染时间,可能导致界面长时间白屏
  3. beforeMount
    1. DOM未完成挂载,数据也初始化完成,但是数据的双向绑定还是显示{{}},这是因为Vue采用了Virtual DOM(虚拟Dom)技术。先占住了一个坑。
    2. 可以发送ajax请求,注意不要将运算量特别大的代码或者多个请求操作放置在此,因为会影响页面的渲染时间,可能导致界面长时间白屏
  4. mounted
    1. 数据和DOM都完成挂载,在上一个周期占位的数据把值给渲染进去。可以在这边请求,不过created请求会更好一些。这个周期适合执行初始化需要操作DOM的方法。
  5. beforeUpdate
    1. 只要是页面数据改变了都会触发,数据更新之前,页面数据还是原来的数据,当你请求赋值一个数据的时候会执行这个周期,如果没有数据改变不执行。
  6. updated
    1. 只要是页面数据改变了都会触发,数据更新完毕,页面的数据是更新完成的。beforeUpdate和updated要谨慎使用,因为页面更新数据的时候都会触发,在这里操作数据很影响性能和容易死循环。
  7. beforeDestroy
    1. 这个周期是在组件销毁之前执行,在我项目开发中,觉得这个其实有点类似路由钩子beforeRouterLeave,都是在路由离开的时候执行,只不过beforeDestroy无法阻止路由跳转,但是可以做一些路由离开的时候操作,因为这个周期里面还可以使用data和method。比如一个倒计时组件,如果在路由跳转的时候没有清除,这个定时器还是在的,这时候就可以在这个里面清除计时器。
  8. Destroyed
    1. 说实在的,我还真的不知道这个周期跟beforeDestroy有什么区别,我在这个周期里面调用data的数据和methods的方法都能调用,所以我会觉得跟beforeDestroy是一样的。
  9. activated
    1. 被 keep-alive 缓存的组件激活时调用。
    2. 该钩子在服务器端渲染期间不被调用。
  10. deactivated
    1. 被 keep-alive 缓存的组件停用时调用。
    2. 该钩子在服务器端渲染期间不被调用。
  11. errorCapturde
    1. 当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。
    2. 你可以在此钩子中修改组件的状态。因此在捕获错误时,在模板或渲染函数中有一个条件判断来绕过其它内容就很重要;不然该组件可能会进入一个无限的渲染循环。
在哪个生命周期中都可以看到this

12.对于vuex的理解一些使用场景

对于vuex的理解

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

一些使用场景

vuex 一般用于中大型 web 单页应用中对应用的状态进行管理,对于一些组件间关系较为简单的小型应用,使用 vuex 的必要性不是很大,因为完全可以用组件 prop 属性或者事件来完成父子组件之间的通信,vuex 更多地用于解决跨组件通信以及作为数据中心集中式存储数据。

13.对于vue中v-model的原理的理解,v-on可以监听多个方法么

一,v-model是什么

v-model就是vue的双向绑定的指令,能将页面上控件输入的值同步更新到相关绑定的data属性,也会在更新data绑定属性时候,更新页面上输入控件的值。

二,为什么使用v-model

v-model作为双向绑定指令也是vue两大核心功能之一,使用非常方便,提高前端开发效率。在view层,model层相互需要数据交互,即可使用v-model。

三,v-model的原理简单描述

v-model主要提供了两个功能,view层输入值影响data的属性值,data属性值发生改变会更新view层的数值变化。

v-on可以监听多个方法

14.vue初始化页面闪动问题

在根dom上加上 style=“display: none;” :style="{display: ‘block’}"

<div class="app" style="display: none;" :style="{display: 'block'}">	{{message}}</div>

ok,完美解决vue初始加载前的花屏现象

15.谈谈对vue双向数据绑定原理的理解

实现mvvm的双向绑定,是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。就必须要实现以下几点:
1、实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
2、实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数
3、实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图

4、mvvm入口函数,整合以上三者

16.钩子的actived和mounted的区别

mounted钩子在主页挂载时执行一次,如果没有缓存的话,再次回到主页时,mounted还会执行,从而导致ajax反复获取数据。

activated钩子则不受缓存的影响,每次重新回到主页都会执行。

17.router和route的区别

  1. router是VueRouter的一个对象,通过Vue.use(VueRouter)和VueRouter构造函数得到一个router的实例对象,这个对象中是一个全局的对象,他包含了所有的路由包含了许多关键的对象和属性。
  2. route是一个跳转的路由对象,每一个路由都会有一个route对象,是一个局部的对象,可以获取对应的name,path,params,query等

18.路由守卫都有什么,哪个守卫可以在在next中传函数(beforeRouteEnter)

19.mvc和mvvm的区别,数据劫持的优点

MVC是三个单词的首字母缩写,它们是Model(模型)、View(视图)和Controller(控制)。

这个模式认为,程序不论简单或复杂,从结构上看,都可以分成三层。

  1. 最上面的一层,是直接面向最终用户的"视图层"(View)。它是提供给用户的操作界面,是程序的外壳。
  2. 最底下的一层,是核心的"数据层"(Model),也就是程序需要操作的数据或信息。
  3. 中间的一层,就是"控制层"(Controller),它负责根据用户从"视图层"输入的指令,选取"数据层"中的数据,然后对其进行相应的操作,产生最终结果。

这三层是紧密联系在一起的,但又是互相独立的,每一层内部的变化不影响其他层。每一层都对外提供接口(Interface),供上面一层调用。这样一来,软件就可以实现模块化,修改外观或者变更数据都不用修改其他层,大大方便了维护和升级。

MVVM的模式

由 Model、View、ViewModel 三部分构成,Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展现出来,ViewModel 是一个同步View 和 Model的对象。

在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上

ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

20.页面加载会调用几个钩子

会触发 下面这几个beforeCreate, created, beforeMount, mounted 。

21.常用的事件修饰符有哪些

  1. stop:阻止冒泡(通俗讲就是阻止事件向上级DOM元素传递)
  2. prevent:阻止默认事件的发生
  3. capture:捕获冒泡,即有冒泡发生时,有该修饰符的dom元素会先执行,如果有多个,从外到内依次执行,然后再按自然顺序执行触发的事件。
  4. self:将事件绑定到自身,只有自身才能触发,通常用于避免冒泡事件的影响
  5. once:设置事件只能触发一次,比如按钮的点击等。
  6. passive:该修饰符大概意思用于对DOM的默认事件进行性能优化,根据官网的例子比如超出最大范围的滚动条滚动的。
  7. native:在父组件中给子组件绑定一个原生的事件,就将子组件变成了普通的HTML标签,不加’. native’事件是无法触 发的。

22.vif,vshow的区别

​  1.手段:v-if是动态的向DOM树内添加或者删除DOM元素;v-show是通过设置DOM元素的display样式属性控制显隐;

2.编译过程:v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换;

**4.性能消耗:**v-if有更高的切换消耗;v-show有更高的初始渲染消耗;

**5.使用场景:**v-if适合运营条件不大可能改变;v-show适合频繁切换。

23.同时写vif和vfor执行结果是怎么样的

v-for和v-if不应该一起使用,必要情况下应该替换成computed属性。

v-for比v-if优先级高,所以嵌套使用的的话,每次v-for都会执行v-if,造成不必要的计算,影响性能,尤其是当之需要渲染很小一部分的时候。

24.虚拟DOM和真实DOM的区别,虚拟DOM的优缺点

虚拟DOM不会进行排版与重绘操作

虚拟DOM进行频繁修改,然后一次性比较并修改真实DOM中需要改的部分(注意!),最后并在真实DOM中进行排版与重绘,减少过多DOM节点排版与重绘损耗

虚拟DOM有效降低大面积(真实DOM节点)的重绘与排版,因为最终与真实DOM比较差异,可以只渲染局部(同2)

真实DOM频繁排版与重绘的效率是相当低的

虚拟dom的优点

  1. 虚拟DOM具有批处理和高效的Diff算法,最终表现在DOM上的修改只是变更的部分,可以保证非常高效的渲染,优化性能.

虚拟dom的缺点

  1. 首次渲染大量DOM时,由于多了一层虚拟DOM的计算,会比innerHTML插入慢。

25.观察者和发布者订阅有什么区别

  1. 观察者模式

    1. 比较概念的解释是,目标和观察者是基类,目标提供维护观察者的一系列方法,观察者提供更新接口。具体观察者和具体目标继承各自的基类,然后具体观察者把自己注册到具体目标里,在具体目标发生变化时候,调度观察者的更新方法。

    比如有个“天气中心”的具体目标A,专门监听天气变化,而有个显示天气的界面的观察者B,B就把自己注册到A里,当A触发天气变化,就调度B的更新方法,并带上自己的上下文。

    1.发布/订阅模式

    1. 比较概念的解释是,订阅者把自己想订阅的事件注册到调度中心,当该事件触发时候,发布者发布该事件到调度中心(顺带上下文),由调度中心统一调度订阅者注册到调度中心的处理代码。
    2. 比如有个界面是实时显示天气,它就订阅天气事件(注册到调度中心,包括处理程序),当天气变化时(定时获取数据),就作为发布者发布天气信息到调度中心,调度中心就调度订阅者的天气处理程序。

26.跨域问题是如何解决的,对跨域的理解,服务器之间存在跨域么

  1. 解决跨域问题

    1. 设置document.domain解决无法读取非同源网页的 Cookie问题
      因为浏览器是通过document.domain属性来检查两个页面是否同源,因此只要通过设置相同的document.domain,两个页面就可以共享Cookie(此方案仅限主域相同,子域不同的跨域应用场景。)

    2. 跨文档通信 API:window.postMessage()

      调用postMessage方法实现父窗口向子窗口发消息(子窗口同样可以通过该方法发送消息给父窗口)

      它可用于解决以下方面的问题:

      页面和其打开的新窗口的数据传递
      多窗口之间消息传递
      页面与嵌套的iframe消息传递
      上面三个场景的跨域数据传递

    3. JSONP

      JSONP是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,兼容性好(兼容低版本IE),缺点是只支持get请求,不支持post请求。

      核心思想:网页通过添加一个

27.在开发中使用axios用于干什么,axios的封装

Axios是基于ajax+promise开发一个交互插件。目前基本用于vue项目中进行前后数据请求。项目中一般基于axios做二次封装使用。

只做过简单的axios封装

28.restful接口规范

RestFul风格(接口)
  1. 专人专职
  2. 一个方法只对应一种功能

猜你喜欢

转载自blog.csdn.net/weixin_45257157/article/details/106215158
今日推荐