荐 2020年前端面试题(二)之VUE篇
1.常用的vue指令有哪些:
v-if
v-else
v-on
v-bind
v-show
v-model
2.浏览器页面之前如何传参
- query
- url?a=xxx&b=yyy
- query+path
- query+name
- params
- 注册:url/:id
- 请求:url/123
- params+name
- props
- 布尔值
- 对象
- 函数
- meta
- 路由元信息
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.组件保持状态怎么做
-
组件没有没销毁
- keep-alive
-
组件被销毁的情况
- 在页面刷新的时候,将数据存至sessionStorage
- 页面刷新的时候,可以将组件的状态发送给服务器保存,组件再次 加载的时候发请求获取之前的状态数据
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 :
- 支持缓存,只有依赖数据发生改变,才会重新进行计算
- 不支持异步,当computed内有异步操作时无效,无法监听数据的变化
- computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值
- 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed
- 如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。
侦听属性watch:
- 不支持缓存,数据变,直接会触发相应的操作;
- watch支持异步;
- 监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
- 当一个属性发生变化时,需要执行对应的操作;一对多;
- 监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数,
- immediate:组件加载立即触发回调函数执行,
- deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变动不需要这么做。注意:deep无法监听到数组的变动和对象的新增,参考vue数组变异,只有以响应式的方式触发才会被监听到。
data 和 computed 最核心的区别在于 data 中的属性并不会随赋值变量的改动而改动,而computed 会。
10.vue中路由传参的方式
和2一样
11.vue的生命周期,哪个生命周期可以看到this,第一个发送请求的是哪一个
- beforeCreate
- 实例组件刚创建,元素DOM和数据都还没有初始化,暂时不知道能在这个周期里面进行生命操作。
- created
- 数据data已经初始化完成,方法也已经可以调用,但是DOM未渲染。有人问了,请求都是异步的,并不会阻碍实例加载。这是我个人水平的问题,这边改正,在这个周期里面,请求因为是异步的,不会阻碍实例加载,除非是那些同步操走才会导致页面空白。这样说来,在这个周期里面进行请求,渲染速度反而会更快。
- 第一个发送ajax请求的地方,注意不要将运算量特别大的代码或者多个请求操作放置在此,因为会影响页面的渲染时间,可能导致界面长时间白屏
- beforeMount
- DOM未完成挂载,数据也初始化完成,但是数据的双向绑定还是显示{{}},这是因为Vue采用了Virtual DOM(虚拟Dom)技术。先占住了一个坑。
- 可以发送ajax请求,注意不要将运算量特别大的代码或者多个请求操作放置在此,因为会影响页面的渲染时间,可能导致界面长时间白屏
- mounted
- 数据和DOM都完成挂载,在上一个周期占位的数据把值给渲染进去。可以在这边请求,不过created请求会更好一些。这个周期适合执行初始化需要操作DOM的方法。
- beforeUpdate
- 只要是页面数据改变了都会触发,数据更新之前,页面数据还是原来的数据,当你请求赋值一个数据的时候会执行这个周期,如果没有数据改变不执行。
- updated
- 只要是页面数据改变了都会触发,数据更新完毕,页面的数据是更新完成的。beforeUpdate和updated要谨慎使用,因为页面更新数据的时候都会触发,在这里操作数据很影响性能和容易死循环。
- beforeDestroy
- 这个周期是在组件销毁之前执行,在我项目开发中,觉得这个其实有点类似路由钩子beforeRouterLeave,都是在路由离开的时候执行,只不过beforeDestroy无法阻止路由跳转,但是可以做一些路由离开的时候操作,因为这个周期里面还可以使用data和method。比如一个倒计时组件,如果在路由跳转的时候没有清除,这个定时器还是在的,这时候就可以在这个里面清除计时器。
- Destroyed
- 说实在的,我还真的不知道这个周期跟beforeDestroy有什么区别,我在这个周期里面调用data的数据和methods的方法都能调用,所以我会觉得跟beforeDestroy是一样的。
- activated
- 被 keep-alive 缓存的组件激活时调用。
- 该钩子在服务器端渲染期间不被调用。
- deactivated
- 被 keep-alive 缓存的组件停用时调用。
- 该钩子在服务器端渲染期间不被调用。
- errorCapturde
- 当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回
false
以阻止该错误继续向上传播。 - 你可以在此钩子中修改组件的状态。因此在捕获错误时,在模板或渲染函数中有一个条件判断来绕过其它内容就很重要;不然该组件可能会进入一个无限的渲染循环。
- 当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回
在哪个生命周期中都可以看到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的区别
-
router是VueRouter的一个对象,通过Vue.use(VueRouter)和VueRouter构造函数得到一个router的实例对象,这个对象中是一个全局的对象,他包含了所有的路由包含了许多关键的对象和属性。
-
route是一个跳转的路由对象,每一个路由都会有一个route对象,是一个局部的对象,可以获取对应的name,path,params,query等
18.路由守卫都有什么,哪个守卫可以在在next中传函数(beforeRouteEnter)
19.mvc和mvvm的区别,数据劫持的优点
MVC是三个单词的首字母缩写,它们是Model(模型)、View(视图)和Controller(控制)。
这个模式认为,程序不论简单或复杂,从结构上看,都可以分成三层。
- 最上面的一层,是直接面向最终用户的"视图层"(View)。它是提供给用户的操作界面,是程序的外壳。
- 最底下的一层,是核心的"数据层"(Model),也就是程序需要操作的数据或信息。
- 中间的一层,就是"控制层"(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.常用的事件修饰符有哪些
- stop:阻止冒泡(通俗讲就是阻止事件向上级DOM元素传递)
- prevent:阻止默认事件的发生
- capture:捕获冒泡,即有冒泡发生时,有该修饰符的dom元素会先执行,如果有多个,从外到内依次执行,然后再按自然顺序执行触发的事件。
- self:将事件绑定到自身,只有自身才能触发,通常用于避免冒泡事件的影响
- once:设置事件只能触发一次,比如按钮的点击等。
- passive:该修饰符大概意思用于对DOM的默认事件进行性能优化,根据官网的例子比如超出最大范围的滚动条滚动的。
- 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的优点
- 虚拟DOM具有批处理和高效的Diff算法,最终表现在DOM上的修改只是变更的部分,可以保证非常高效的渲染,优化性能.
虚拟dom的缺点
- 首次渲染大量DOM时,由于多了一层虚拟DOM的计算,会比innerHTML插入慢。
25.观察者和发布者订阅有什么区别
-
观察者模式
-
比较概念的解释是,目标和观察者是基类,目标提供维护观察者的一系列方法,观察者提供更新接口。具体观察者和具体目标继承各自的基类,然后具体观察者把自己注册到具体目标里,在具体目标发生变化时候,调度观察者的更新方法。
比如有个“天气中心”的具体目标A,专门监听天气变化,而有个显示天气的界面的观察者B,B就把自己注册到A里,当A触发天气变化,就调度B的更新方法,并带上自己的上下文。
1.发布/订阅模式
- 比较概念的解释是,订阅者把自己想订阅的事件注册到调度中心,当该事件触发时候,发布者发布该事件到调度中心(顺带上下文),由调度中心统一调度订阅者注册到调度中心的处理代码。
- 比如有个界面是实时显示天气,它就订阅天气事件(注册到调度中心,包括处理程序),当天气变化时(定时获取数据),就作为发布者发布天气信息到调度中心,调度中心就调度订阅者的天气处理程序。
-
26.跨域问题是如何解决的,对跨域的理解,服务器之间存在跨域么
-
解决跨域问题
-
设置document.domain解决无法读取非同源网页的 Cookie问题
因为浏览器是通过document.domain属性来检查两个页面是否同源,因此只要通过设置相同的document.domain,两个页面就可以共享Cookie(此方案仅限主域相同,子域不同的跨域应用场景。) -
跨文档通信 API:window.postMessage()
调用postMessage方法实现父窗口向子窗口发消息(子窗口同样可以通过该方法发送消息给父窗口)
它可用于解决以下方面的问题:
页面和其打开的新窗口的数据传递
多窗口之间消息传递
页面与嵌套的iframe消息传递
上面三个场景的跨域数据传递 -
JSONP
JSONP是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,兼容性好(兼容低版本IE),缺点是只支持get请求,不支持post请求。
核心思想:网页通过添加一个
-
27.在开发中使用axios用于干什么,axios的封装
Axios是基于ajax+promise开发一个交互插件。目前基本用于vue项目中进行前后数据请求。项目中一般基于axios做二次封装使用。
只做过简单的axios封装
28.restful接口规范
RestFul风格(接口)
- 专人专职
- 一个方法只对应一种功能
Ps:如需获取更多的资料或者刷面试题,请关注公众号“玖柒知识屋”!
本文地址:https://blog.csdn.net/weixin_45257157/article/details/106215158
上一篇: JS实现二级、三级、四级联动效果。详细
下一篇: jquery时间下拉框小例子