一点点vue面试整理,方便自己查看

随便看看

vue全家桶

1、vue

SPA 单页面:仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机制实现 HTML 内容的变换,UI 与用户的交互,避免页面的重新加载。优点:用户体验好、快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染;基于上面一点,SPA相对对服务器压力小;前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理;缺点:初次加载耗时多:为实现单页 Web 应用功能及显示效果,需要在加载页面的时候将JavaScript、CSS统一加载,部分页面按需加载;前进后退路由管理:由于单页应用在一个页面中显示所有的内容,所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理;SEO 难度较大:由于所有的内容都在一个页面中动态替换显示,所以在 SEO 上其有着天然的弱势。

Vue的单向数据流:所有的prop都使得其父子prop之间形成了一个单向下行绑定:父级prop的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。

MVVM:MVVM是Model-View-ViewModel缩写,也就是把MVC中的Controller演变成ViewModel。Model层代表数据模型,View代表UI组件,ViewModel是View和Model层的桥梁,数据会绑定到viewModel层并自动将数据渲染到页面中,视图变化的时候会通知viewModel层更新数据。

双向数据绑定原理:vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

发布-订阅模式:其定义对象间一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知。

Vue3.x响应式原理:Vue3.x改用Proxy替代Object.defineProperty。因为Proxy可以直接监听对象和数组的变化,并且有多达13种拦截方法。

vue2.x中监测数组变化:使用了函数劫持的方式,重写了数组的方法,Vue将data中的数组进行了原型链重写,指向了自己定义的数组原型方法。这样当调用数组api时,可以通知依赖更新。如果数组中包含着引用类型,会对数组中的引用类型再次递归遍历进行监控。这样就实现了监测数组变化。

nextTick:在下次 DOM 更新循环结束之后执行延迟回调。

this.$forceUpdate():强制刷新

Vue的生命周期:

beforeCreate是new Vue()之后触发的第一个钩子,在当前阶段data、methods、computed以及watch上的数据和方法都不能被访问。

created在实例创建完成后发生,当前阶段已经完成了数据观测,也就是可以使用数据,更改数据,在这里更改数据不会触发updated函数。可以做一些初始数据的获取,Dom还未生成,在当前阶段无法与Dom进行交互,如果非要想,可以通过vm.$nextTick来访问Dom。组件实例已经完全创建,属性也绑定,但真实dom还没有生成,$el属性还没有显示出来

beforeMount发生在挂载之前,在这之前template模板已导入渲染函数编译。而当前阶段虚拟Dom已经创建完成,即将开始渲染。在此时也可以对数据进行更改,不会触发updated。虚拟Dom!!!

mounted在挂载完成后发生,el 被新创建的 vm.$el替换,并挂载到实例上去之后调用该钩子。在当前阶段,真实的Dom挂载完毕,数据完成双向绑定,可以访问到Dom节点,使用$refs属性对Dom进行操作。注意:当组件是在v-if当下的,mounted是访问不到$refs属性获取Dom的

beforeUpdate发生在更新之前,也就是响应式数据发生更新,虚拟dom重新渲染之前被触发,你可以在当前阶段进行更改数据,不会造成重渲染。

updated发生在更新完成之后,当前阶段组件Dom已完成更新。要注意的是避免在此期间更改数据,因为这可能会导致无限循环的更新。

activited:keep-alive专属,组件被激活时调用

deadctivated:keep-alive专属,组件被销毁时调用

beforeDestroy发生在实例销毁之前,在当前阶段实例完全可以被使用,我们可以在这时进行善后收尾工作,比如清除计时器。

destroyed发生在实例销毁之后,这个时候只剩下了dom空壳。组件已被拆解,数据绑定被卸除,监听被移出,子实例也统统被销毁。

服务端渲染(SSR):简单理解是将组件或页面通过服务器生成html字符串,再发送到浏览器,最后将静态标记"混合"为客户端上完全交互的应用程序

SSR的优势:更利于SEO;更利于首屏渲染 缺点:服务端压力较大;开发条件受限;学习成本相对较高

Computed:本质是一个具备缓存的watcher,依赖的属性发生变化就会更新视图。适用于计算比较消耗性能的计算场景。当表达式过于复杂时,在模板中放入过多逻辑会让模板难以维护,可以将复杂的逻辑放入计算属性中处理。

Watch:没有缓存性,更多的是观察的作用,可以监听某些数据执行回调。当我们需要深度监听对象中的属性时,可以打开deep:true,这样便会对对象中的每一项进行监听。这样会带来性能问题,优化的话可以使用字符串形式监听,如果没有写到组件中,不要忘记使用unWatch手动注销哦。

data为什么是一个函数:一个组件被复用多次的话,也就会创建多个实例。本质上,这些实例用的都是同一个构造函数。如果data是对象的话,对象属于引用类型,会影响到所有的实例。所以为了保证组件不同的实例之间data不冲突,data必须是一个函数。

v-model:本质就是一个语法糖,可以看成是value + input方法的语法糖。 可以通过model属性的prop和event属性来进行自定义。原生的v-model,会根据标签的不同生成不同的事件和属性。

Vue事件绑定原理:原生事件绑定是通过addEventListener绑定给真实元素的,组件事件绑定是通过Vue自定义的$on实现的。

Vue模版编译原理:Vue的编译过程就是将template转化为render函数的过程--生成AST树(一种用JavaScript对象的形式来描述整个模板);优化;codegen

diff算法:

同级比较,再比较子节点

先判断一方有子节点一方没有子节点的情况(如果新的children没有子节点,将旧的子节点移除)

比较都有子节点的情况(核心diff)

递归比较子节点

虚拟Dom:由于在浏览器中操作DOM是很昂贵的。频繁的操作DOM,会产生一定的性能问题。这就是虚拟Dom的产生原因。Virtual DOM本质就是用一个原生的JS对象去描述一个DOM节点。是对真实DOM的一层抽象。

key属性:key的作用是尽可能的复用 DOM 元素。新旧 children 中的节点只有顺序是不同的时候,最佳的操作应该是通过移动元素的位置来达到更新的目的。需要在新旧 children 的节点中保存映射关系,以便能够在旧 children 的节点中找到可复用的节点。key也就是children中节点的唯一标识。

keep-alive:keep-alive可以实现组件缓存,当组件切换时不会对当前组件进行卸载。常用的两个属性include和exclude,允许组件有条件的进行缓存(使用的是组件的name)。两个生命周期activated和deactivated,用来得知当前组件是否处于活跃状态。

生命周期调用顺序:组件的调用顺序都是先父后子,渲染完成的顺序是先子后父。组件的销毁操作是先父后子,销毁完成的顺序是先子后父。

加载渲染过程:父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount- >子mounted->父mounted

子组件更新过程:父beforeUpdate->子beforeUpdate->子updated->父updated

父组件更新过程:父 beforeUpdate -> 父 updated

销毁过程:父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

组件通信:

父子组件通信:父->子props,子->父 $on、$emit;获取父子组件实例 $parent、$children;Ref 获取实例的方式调用组件的属性或者方法

兄弟组件通信:Event Bus 实现跨组件通信 Vue.prototype.$bus = new Vue;Vuex

跨级组件通信:Vuex;$attrs、$listeners(中间child组件上加上v-bind="$attrs" v-on="$listeners",$attrs包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外),$listeners包含parent组件绑定的事件,可以用$emit访问,可以用这个对element-ui等组件进行二次封装)

Vue的性能优化:

编码阶段:尽量减少data中的数据,data中的数据都会增加getter和setter,会收集对应的watcher;v-if和v-for不能连用;使用v-for给每项元素绑定事件时使用事件代理;SPA页面采用keep-alive缓存组件;更多的情况下,使用v-if替代v-show;key保证唯一使用;路由懒加载、异步组件;防抖、节流;第三方模块按需导入;长列表滚动到可视区域动态加载;图片懒加载

SEO优化:预渲染;服务端渲染SSR

打包优化:压缩代码;Tree Shaking/Scope Hoisting;使用cdn加载第三方模块;多线程打包happypack;splitChunks抽离公共文件;sourceMap优化

用户体验:骨架屏;PWA

还可以使用缓存(客户端缓存、服务端缓存)优化、服务端开启gzip压缩等。

指令directives:

钩子函数:

bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。

update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。

componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。

unbind:只调用一次,指令与元素解绑时调用。

参数:

el:指令所绑定的元素,可以用来直接操作 DOM。

binding:一个对象,包含以下 property:

name:指令名,不包括 v- 前缀。

value:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。

oldValue:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。

expression:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。

arg:传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"。

modifiers:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }。

vnode:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。

oldVnode:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用。

动态指令参数:v-mydirective:[argument]="value",通过binding.arg获取参数

过滤器filter:过滤器可以用在两个地方:双花括号插值({{ message | capitalize }})和 v-bind 表达式 (

vue常用的修饰符:.prevent: 提交事件不再重载页面;.stop: 阻止单击事件冒泡;.self: 当事件发生在该元素本身而不是子元素的时候会触发;.capture: 事件侦听,事件发生的时候会调用

2、vuex:只用来读取的状态集中放在store中; 改变状态的方式是提交mutations,这是个同步的事物; 异步逻辑应该封装在action中。

state:Vuex 使用单一状态树,即每个应用将仅仅包含一个store 实例,但单一状态树和模块化并不冲突。存放的数据状态,不可以直接修改里面的数据。

mutations:mutations定义的方法动态修改Vuex 的 store 中的状态或数据。

getters:类似vue的计算属性,主要用来过滤一些数据。

action:actions可以理解为通过将mutations里面处里数据的方法变成可异步的处理数据的方法,简单的说就是异步操作数据。view 层通过 store.dispath 来分发 action。

modules:项目特别复杂的时候,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。

3、vue-router

hash路由和history路由实现原理:location.hash的值实际就是URL中#后面的东西。history实际采用了HTML5中提供的API来实现,主要有history.pushState()和history.replaceState()。

全局守卫(beforeEach,afterEach)  组件内的守卫(beforeRouteEnter,beforeRouteLeave)  路由独享的守卫(beforeEnter)

beforeEach主要有3个参数to,from,next:

to:route即将进入的目标路由对象,

from:route当前导航正要离开的路由

next:function一定要调用该方法resolve这个钩子。执行效果依赖next方法的调用参数。可以控制网页的跳转。

4、axios

js数据类型 String、Number、Boolean、Symbol、Null、undefined、Object

判断数据类型:Object.prototype.toString.call()(对于出Object外的其他对象,需要通过 call / apply 来调用才能返回正确的类型信息)、instanceof( [] instanceof Array 返回true, [] instanceof Object 也返回true)、typeOf(typeOf null返回object)、constructor(null 和 undefined 无constructor)

闭包就是能够读取其他函数内部变量的函数。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

五大主流浏览器及四大内核:IE(Trident内核,也是俗称的IE内核)、Firefox(Gecko内核,俗称Firefox内核)、GoogleChrome(统称为Chromium内核或Chrome内核,以前是Webkit内核,现在是Blink内核)、Safari(Webkit内核)、Opera(最初是自己的Presto内核,后来是Webkit,现在是Blink内核);Trident、Gecko、Blink、Webkit

数组去重:Array.from(set(array));arr.filter(function(elem, index, self) { return index == self.indexOf(elem); });for循环

JS中的MUL函数:function mul (x) { return function (y) { return function (z) {  return x * y * z;  } } }

mul(1)(2)(3)

匿名函数:(function(x, y){    alert(x + y);  })(2, 3);这里创建了一个匿名函数(在第一个括号内),第二个括号用于调用该匿名函数,并传入参数。

克隆对象:var y = Object.assign({}, x);

编码和解码:encodeURI() 函数用于在JS中对URL进行编码。decodeURI() 函数用于解码js中的URL。

BOM对象(浏览器对象模型,主要处理浏览器窗口和框架):window对象,是JS的最顶层对象,其他的BOM对象都是window对象的属性;document对象,文档对象;location对象,浏览器当前URL信息;navigator对象,浏览器本身信息;screen对象,客户端屏幕信息;history对象,浏览器访问历史信息;

DOM对象(文档对象模型):DOM就是一个接口,我们可以通过DOM来操作页面中各种元素,例如添加元素、删除元素、替换元素等。

创建BFC:float的值不是none。position的值不是static或者relative。display的值是inline-block、table-cell、flex、table-caption或者inline-flex;overflow的值不是visible

你可能感兴趣的:(一点点vue面试整理,方便自己查看)