【前端面试系列】:
- 2024前端面试 --
HTML5
+CSS3
篇 - 2024前端面试 --
ES6
篇 - 2024前端面试 --
JavaScript
篇 - 2024前端面试 --
Vue2
篇 - 2024前端面试 --
Vue3
篇 - 2024前端面试 --
Angular
篇 - 2024前端面试 --
Node.js
篇 - 2024前端面试 --
Webpack
篇
1. 生命周期:
1.1 vue2
生命周期有哪些?
生命周期 | 描述 | 备注 |
---|---|---|
组件实例创建之初,组件的属性生效之前 | 这个阶段属性和方法都不能使用 | |
组件实例已经完全创建,属性也绑定,但真实的dom 还没有生成,$el 还不可用 | 在这里完成了数据监测;可以使用数据,修改数据 | |
在挂载开始之前被调用,相关的render 函数首次被调用 | 完成了模板的编译,虚拟DOM 也完成创建,即将渲染,修改数据,不会触发updated | |
el 被新创建的vm.$el 替换,并挂载到实例上去之后调用该钩子(把编译好的模板挂载到页面) | 这里可以发送异步请求,也可以访问DOM 节点 | |
组件数据更新之前调用,发生在虚拟dom 打补丁之前 | 数据是新的,页面上的数据是旧的,组件即将更新,准备渲染 | |
组件数据更新之后 | render 重新做了渲染,这时的数据和页面都是新的,避免再次更新数据 | |
keep-alive 专属,组件被激活后调用 | ||
keep-alive 专属,组件被销毁后调用 | ||
组件销毁前调用 | 在这里实例还可以用,尅清除定时器等 | |
组件销毁后调用 | 全部都销毁 |
1.2. 生命周期执行顺序:
- 无子元素:
beforeCreate
、created
、beforeMount
、mounted
- 有子元素:
- 父:
beforeCreate
、created
、beforeMount
- 子:
beforeCreate
、created
、beforeMount
、mounted
- 父:
mounted
- 父:
1.3. 在created
和mounted
去请求数据,有什么区别?
created
:在渲染前使用,通常先初始化属性,然后做渲染;mounted
:在模板渲染完成后,一般都是初始化页面后,在对元素节点进行操作;- 在这里请求数据,可能会出现闪屏问题,
created
里不会。
- 在这里请求数据,可能会出现闪屏问题,
一般用
created
比较多
- 请求的数据对
DOM
有影响,那么使用created
;- 如果请求的数据对
DOM
无关,可以放在mounted
。
2. keep-alive
是什么?怎么使用?
vue
的一个内置组件,包裹组件的时候,会缓存不活跃的组件实例,并不是销毁他们;- 作用:把组件切换的状态保存在内存里,防止重复渲染
DOM
节点,减少加载时间和性能消耗,提高用户体验。
3. vue
中的修饰符有哪些?
- 事件修饰符
.stop
组织冒泡.prevent
组织默认行为.capture
内部元素触发的事件先在次处理.self
只有在event.target是当前元素时触发.once
事件只会触发一次.passive
立即触发默认行为.native
把当前元素作为原生标签看待
- 按键修饰符
.keyup
键盘抬起.keydown
键盘按下
- 系统修饰符
.ctrl
.alt
.meta
- 鼠标修饰符
.left
鼠标左键.right
鼠标右键.middle
鼠标中键
- 表单修饰符
.lazy
等输入完之后再显示.trim
删除内容前后的空格.number
输入是数字或转为数字
4. vue
如何进行组件通信?
- 父传子
props
:父组件使用自定义属性,然后子组件使用props
$ref
:引用信息会注册在父组件的$refs
对象上- 子传父
$emit
:子组件绑定自定义事件,触发执行后,传给父组件,父组件需要用事件监听来接收参数- 兄弟传
new
一个新的vue
实例,用on
和emit
来对数据进行传输vuex
传值
5. vue
的双向绑定原理是什么?
通过数据劫持和发布订阅者模式来实现,同时利用Object.defineProperty()
劫持各个属性的 setter
和 getter
,在数据发生改变的时候发布消息给订阅者,触发对应的监听回调渲染视图,也就是说数据和视图时同步的,数据发生改变,视图跟着发生改变,视图改变,数据也会发生改变。
- 第一步:需要
observer
的数据对象进行递归遍历,包括子属性对象的属性,都加上setter
和getter
; - 第二步:
compile
模板解析指令,把模板中的变量替换成数据,然后初始化渲染视图,同时把每个指令对应的节点绑定上更新函数,添加订阅者,如果数据变化,收到通知,更新视图; - 第三步:
Watcher
订阅者是Observer
和Compile
之间的通信桥梁,作用:- 在自身实例化的时候忘订阅器内添加自己;
- 自身要有一个update()方法;
- 等待属性变动时,调用自身的update方法,触发compile这种的回调。
- 第四步:
MVVM
作为数据绑定的入口,整合了observer
、compile
和watcher
三者,通过observer
来监听自己的数据变化,通过compile
解析模板指令; - 最后,利用
watcher
把observer
和compile
联系起来,最终达到数据更新视图更新,视图更新数据更新的效果。
6. vue router
路由
6.1. 路由是怎么传参的?
// params传参:
this.$router.push({name:"index",params:{id:item.id}});
this.$router.params.id
// 路由属性传参:this.$router.push({name:"/index/${item.id}"})
路由配置:{ path: "/index:id" }
// query传参(可以解决页面刷新参数丢失的问题)
this.$router.push({
name:'index',
query:{id:item.id}
})
6.2. hash
模式和history
模式有什么区别?
hash
的路由地址上有#
号,history
模式没有;- 在做回车刷新的时候,
hash
模式会加载对应页面,history
会报错404
; hash
模式支持低版本浏览器,history
不支持,因为是H5
新增的API
;hash
不会重新加载页面,单页面应用必备;history
有历史记录,H5
新增了pushState
和replaceState()
去修改历史记录,并不会立刻发送请求;history
需要后台配置。
6.3. 路由拦截是怎么实现的?
// 路由拦截 axios拦截
// 需要在路由配置中添加一个字段,它是用于判断路由是否需要拦截
{
name: 'index',
path: '/index',
component: Index,
meta:{
requirtAuth: true
}
}
router.beforeEach((to,from,next) => {
if(to.meta.requirtAuth) {
if( store.satte.token ) {
next()
}else{
}
}
})
6.4. 动态路由?
- 要在路由配置里设置
meta
属性,扩展权限相关的字段,在路由导航守卫里通过判断这个权限标识,实现路由的动态增加和跳转 - 根据用户登录的账号,返回用户角色
- 前端再根据角色,跟路由表的
meta.role
进行匹配 - 把匹配搭配的路由形成可访问的路由
6.5. 如何解决刷新后二次加载路由?
// 1. 路由重加载
window.location.reload();
// 2. matcher
const router = createRouter();
export function resetRouter(){
const newRouter = creatRouter();
router.matcher = newRouter.matcher;
};
7. vuex
7.1. vuex在什么场景会去使用?属性有哪些?
- state 存储变量
- getters state的计算属性
- mutations 提交更新数据的方法
- actions 和mutations差不多,他是提交mutations来修改数据,可以包括异步操作
- modules 模块化vuex 使用场景:用户的个人信息、购物车模块、订单模块
7.2. vuex
的响应式处理:
vuex
是vue
的状态管理工具vue
中可以直接触发methods
中的方法,vuex
是不可以的。未来处理异步,当触发事件的时候,会通过dispatch
来访问actions
中的方法,actions
中的commit
会触发mutations
中的方法从而修改state
里的值,通过getter
把数据更新到视图Vue.use(vuex)
,调用install
方法,通过applyMixin(vue)
在任意组件内执行this.$store
就可以访问到store
对象。vuex
的state
是响应式的,借助的就是vue
的data
,把state
存到vue
实例组件的data
中
7.3. vuex刷新数据会丢失吗?怎么解决?
vuex肯定会重新获取数据,页面也会丢失数据
- 把数据直接保存在浏览器缓存里(cookie localstorage sessionstorage)
- 页面刷新的时候,再次请求数据,达到可以动态更新的方法
- 监听浏览器的刷新书简,在刷新前把数据保存到sessionstorage里,刷新后请求数据,请求到了用vuex,如果没有那就用sessionstorage里的数据
8. vue中遍历全局的方法有哪些?
// 1.普通遍历,对象.forEach()
arr.forEach(function(item,index,arr){
console.log(item,index)
})
// 2.对元素统一操作 对象.map()
var newarr = arr.map(function(item){
return item+1
})
// 3.查找符合条件的元素 对象.filter()
arr.filter(function(item){
if(item > 2){
return false
}else{
return true
}
})
// 4.查询符合条件的元素,返回索引 对象.findindex()
arr.finindex(function(item){
if(item>1){
return true
}else{
return false
}
})
// 对象.evening() 遇到不符合的对象会停止
// 对象.some() 找到符合条件的元素就停止
9. 基础内容:
9.1. 如何理解MVVM
?
9.2. v-if
和v-show
的区别
都可以控制元素的显示和隐藏
v-show
时控制元素的display
值来让元素显示和隐藏;v-if
显示隐藏时把DOM
元素整个添加和删除;v-if
有一个局部编译/卸载的过程,切换这个过程中会适当的销毁和重建内部的事件监听和子组件;v-show
只是简单的css
切换;v-if
才是真正的条件渲染;v-show
从false
变成true
的时候不会触发组件的生命周期,v-if
会触发生命周期;v-if
的切换效率比较低,v-show
的效率比较高。
Q2:class
和style
的动态绑定
class
的动态绑定的几种方法
// 对象语法
<div v-bind:class="{'activeClass':isActive, 'animationClass':isAnimation}"></div>
data() {
return {
isActive:true,
isAnimation:true
}
},
// 数组语法:
<div v-bind:class="[isActive?'activeClass':'',isAnimation?'animationClass':'']"></div>
data() {
return {
isActive:true,
isAnimation:true
}
},
style
的动态绑定的几种方法:
// 数组方法
<div :style="{color:fontColor,fontSize:fontSize+'px'}"></div>
data() {
return {
fontColor:'red',
fontSize:14
}
},
// 对象方法
<div :style="[colorStyle,fontStyle]"></div>
data() {
return {
colorStyle:{ color:'red' },
fontStyle: { fontSize: '14px' }
}
},
Q3:computed
和watch
的区别
computed
:计算属性,依赖其他属性值,并且compouted
的值有缓存,只有它依赖的属性值发生变化,下一次获取computed
的值时才会重新计算computed
的值。watch
:侦查属性,执行数据的监听回调,每次监听的数据发生变化时,watch
就会触发。
应用场景:
computed
:当我们需要进行数值计算,并且依赖其他数据时,用computed
的缓存特性,避免每次获取数据后,重新计算。watch
:当需要监听数据变化后,需要进行异步操作或者开销比较大的操作时,使用watch
选项允许我们执行异步操作 ( 访问一个API
),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。