「时光不负,创作不停,本文正在参加2021年终总结征文大赛」
-
前言
作为程序员难免会跳槽,这个时候就需要去面试,面试经常被一些HR问前端的知识点,这个时候没有面试问题干货怎么行,下面是我面试几家公司最常见的一些问题,现在分享给大家希望对在座的各位都有用。
-
内容
1. Vue的生命周期方法有哪些?一般在哪一步发起请求及原因
核心答案: 总共分为8个阶段:创建前/后,载入前/后,更新前/后,销毁前/后。
创建前/后:
- beforeCreate阶段:vue实例的挂载元素el和数据对象data都为undefined,还未初始化。
- 说明:在当前阶段data、methods、computed以及watch上的数据和方法都不能被访问。
- created阶段:vue实例的数据对象data有了,el还没有。
- 说明:可以做一些初始数据的获取,在当前阶段无法与Dom进行交互,如果非要想,可以通过vm.$nextTick来访问Dom。 载入前/后:
- beforeMount阶段
- 说明:当前阶段虚拟Dom已经创建完成,即将开始渲染。在此时也可以对数据进行更改,不会触发updated。
- mounted阶段:vue实例挂载完成,data.message成功渲染。
- 说明:在当前阶段,真实的Dom挂载完毕,数据完成双向绑定,可以访问到Dom节点,使用$refs属性对Dom进行操作 更新前/后:
- beforeUpdate阶段,说明:可以在当前阶段进行更改数据,不会造成重渲染。
- updated阶段,说明:当前阶段组件Dom已完成更新。要注意的是避免在此期间更改数据,因为这可能会导致无限循环的更新。 销毁前/后:
- beforeDestroy阶段:
- 说明:在当前阶段实例完全可以被使用,我们可以在这时进行善后收尾工作,比如清除计时器。
- destroyed阶段:
- 说明:当前阶段组件已被拆解,数据绑定被卸除,监听被移出,子实例也统统被销毁。
- 补充回答:
- 第一次页面加载时会触发:beforeCreate, created, beforeMount, mounted。
2.Vue 组件间通信有哪几种方式?
Vue 组件间通信只要指以下 3 类通信:父子组件通信、隔代组件通信、兄弟组件通信。
1、props / $emit 适用 父子组件通信
2、ref 与 children 适用 父子组件通信
- ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例
- children:访问父 / 子实例
3、EventBus (on) 适用于 父子、隔代、兄弟组件通信
这种方法通过一个空的 Vue 实例作为中央事件总线(事件中心),用它来触发事件和监听事件,从而实现任何组件间的通信,包括父子、隔代、兄弟组件。
4、Vuex 适用于 父子、隔代、兄弟组件通信
3.vue-router 两种模式的区别?
核心答案:
vue-router 有 3 种路由模式:hash、history、abstract。
1. hash模式:
特点:hash虽然在URL中,但不被包括在HTTP请求中 用来指导浏览器动作,对服务端安全无用,hash不会重加载页面 通过监听 hash(#)的变化来执行js代码 从而实现 页面的改变
hash: 使用 URL hash 值来作路由。支持所有浏览器,包括不支持 HTML5 History Api 的浏览器;
2. history模式:historyApi + popState
HTML5推出的history API,由pushState()记录操作历史,监听popstate事件来监听到状态变更; 因为 只要刷新 这个url就会请求服务器,然而服务器上根本没有这个资源,所以就会报404,解决方案就 配置一下服务器端。
history : 依赖 HTML5 History API 和服务器配置。具体可以查看 HTML5 History 模式;
4.nextTick怎么使用?
nextTick的回调是在下次DOM更新循环结束之后执行的延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM。nextTick主要使用了宏任务和微任务。原理就是异步方法(promise, mutationObserver, setImmediate, setTimeout)经常与事件循环一起来问。
5.Vue中key的作用
key的作用主要是为了高效的更新虚拟DOM,其原理是vue在patch过程中通过key可以精准判断两个节点是否是同一个,从而避免频繁更新不同元素,使得整个patch过程更加高效,减少DOM操作量,提高性能。
6.computed 和 watch 的区别
- computed: 计算属性。依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值;
- watch: 监听数据的变化。更多的是「观察」的作用,类似于某些数据的监听回调 ,每当监听的数据变化时都会执行回调进行后续操作;
7.垂直水平居中的几种方法
1. flex布局(最常用的方法)
display: flex; justify-content: center; align-items: center;
2.水平居中
不过要记得设置块级元素的宽高。 margin: 0 auto;
3.元素水平垂直居中
定位+margin反向偏移
4.给子元素相对定位,在通过translaY()得到垂直居中给子元素相对定位,在通过translaY()得到垂直居中
(其实还有随便说点就够了,平常也用不到这么多)
8.浅拷贝、深拷贝
简单来说,就是一个变量赋值给另一个变量,其中一个变量的值改变,两个变量的值都变了,这就叫做浅拷贝。
ES6语法中也给我们提供了一个浅拷贝的方法Object.assign(target, sources)target:拷贝的目标 sources: 被拷贝的对象。那么浅拷贝, 是拷贝后,新拷贝的对象内部仍然有一部分数据会随着源对象的变化而变化, 那么深拷贝就是,拷贝后, 新拷贝的对象内部所有数据都是独立存在的,不会随着源对象的改变而改变 深拷贝的话一共有两种方式: 递归拷贝 和 利用JSON函数深拷贝JSON.parse(JSON.stringify(a))
9.v-if与v-show的区别
- v-if 是真正的条件渲染,直到条件第一次变为真时,才会开始渲染,不渲染不占用dom元素。
- v-show 不管初始条件是什么会渲染,并且只是简单地基于 CSS 的 “display” 属性进行切换,占用dom元素
- 注意:v-if 适用于不需要频繁切换条件的场景;v-show 则适用于需要非常频繁切换条件的场景。
10.V-model的原理
其实v-model是vue的一个语法糖。即利用v-model绑定数据后,既绑定了数据,又添加了一个input事件监听。
1.input 输入值后更新data
首先在页面初始化时候,vue的编译器会编译该html模板文件,将页面上的dom元素遍历生成一个虚拟的dom树。再递归遍历虚拟的dom的每一个节点。当匹配到其是一个元素而非纯文本,则继续遍历每一个属性。如果遍历到v-model这个属性,则会为这个节点添加一个input事件,当监听从页面输入值的时候,来更新vue实例中的data想对应的属性值。
2.data的属性赋值后更新input的值
同样初始化vue实例时候,会递归遍历data的每一个属性,并且通过defineProperty来监听每一个属性的get,set方法,从而一旦某个属性重新赋值,则能监听到变化来操作相应的页面控制。