




















作者梳理了前端面试高频考点,涵盖 JS 事件流、闭包、节流防抖,Vue 生命周期、权限、组件通信与双向绑定原理,以及 CSS 布局与性能优化等核心知识。
金三银四,又到了每年换工作的黄金时间,正好最近也准备找新工作,顺便将面试过程中的一些题目进行总结。
先进行事件捕获过程、然后调用目标元素事件,最后执行事件冒泡。
在操作一堆嵌套的元素时,如果目标元素嵌套在第四层,那么当点击目标元素时会从第一层捕获到第四层目标元素上,然后此时执行目标元素绑定的事件,结束后从目标元素开始又一层一层向上冒泡。
通过 obj.addEventListener(event,function(){},bool) 的 bool 属性来确定捕获阶段和冒泡阶段,bool 为 true 时,当前函数捕获阶段触发。反之为冒泡阶段触发。
阻止冒泡 w3c 的方法是 e.stopPropagation(),IE 则是使用 e.cancelBubble = true;
额外知识点: 如果在捕获阶段阻止了事件,那么此流程就会被阻止掉,不会触发后续的操作。
闭包就是能够读取其他函数内部变量的函数。由于在 Javascript 语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
使用闭包的注意点:
开发中使用的地方,比如我定义了一个函数,这个函数会帮我在页面生成一些 dom,如果不做限制的话,每次 new 函数就会生成一次,如果恶意操作会造成页面卡顿等。
let ProxySingletonDialog = (function () {
let instance, initFlag;
return function (option) {
if (!instance) {
initFlag = false;
instance = new Dialog({ ...option, initFlag });
}
return instance;
};
})();
window.Dialog = ProxySingletonDialog;
函数节流:是确保函数特定的时间内至多执行一次。 函数防抖:是函数在特定的时间内不被再调用后执行。
节流函数
let canRun = false;
function throttle() {
if (!canRun) {
canRun = true;
setTimeout(() => {
canRun = false;
console.log('节流函数');
}, 1000);
}
}
window.addEventListener('resize', throttle, false);防抖函数
function debounce(fn, delay) {
let timer = null;
return (...arg) => {
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, arg);
}, delay);
};
}
function click() {
console.log('防抖函数');
}
document.addEventListener('click', debounce(click, 200), false);beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
beforeDestroy
destroyedsetup --> 代替了 vue2 中的 create 阶段函数
onBeforeMount
onMounted
onBeforeUpdate
onUpdated
onBeforeUnmount
onUnmountedVue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新。
$nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 $nextTick,则可以在回调中获取更新后的 DOM
有过封装,比如在请求拦截器中,给header中添加 Token,或者通过参数修改请求头格式等。
加载全局请求 Loading 状态。在请求开始前打开,结束后关闭。
在返回拦截器中对返回 code 状态进行判断,无权则跳转无权界面,错误则跳转错误界面,随后将正确请求内容 return 出去。
可以在 vuex 中定义好用户的基本信息,然后在用户登录时将后端返回的信息更新到 vuex 中,并将返回的 Token 信息存放在 cookies 中。登录成功后使用 router 的 push 方法跳转路由到 home 页面。
因为 vuex 里的内容在刷新后就不存在了,所以我使用如下方法:
在路由守卫的钩子函数中查找 vuex 中的某一项用户信息是否存在,如果存在则进行其他的操作,例如权限判断。反之不存在的话,就需要通过另外一个获取用户信息的接口来拿到用户信息,并更新 vuex 中相对应的属性。
通过这一接口在每次刷新页面后就可快速拿到用户数据。
1.前端效验法
在定义路由初期时就定义好一个自定义属性,例如 access 属性,标志好权限内容,将权限内容发给后端,后端给对应的用户添加上当前权限内容。
在路由守卫的钩子函数中,每次路由的跳转都进行权限的效验,如果当前用户登录后的用户信息中并没有当前路由的权限,就跳转无权页面。反之则通过,使用next()方法进行路由处理。
至于侧边菜单栏的生成,需要在项目运行初期先进行权限比对,生成有权路由信息,交给封装好的侧边栏组件进行渲染。
2.后端返回法
在项目开始初期就先进行路由信息输入页面的处理,将新页面的信息录入到后端,并在权限分配页面进行用户权限的分配。
用户登录后,在路由守卫的钩子函数中,将后端返回的路由表信息进行逻辑处理,将杂乱的信息转化为 vue-router 可识别的对象数据。通过addRoute()方法将生成的路由表 push 进 router 对象中。
侧边栏就可以直接使用生成的内容进行渲染
使用过,混入方法主要用来提取一些页面公共方法,减少代码的冗余。常见业务就是比如在表格中会有排序方法,然后分页中也会有一些关于分页内容的方法,这些方法函数都是一致的,所以可以抽离出来,使得其他页面可以共用。
常见的三个方法在这里 《组件传值》
补充方法:vuex provide/inject
使用插槽。抽离共用的部分,然后将需要自定义的地方使用 slot 引入。
包括匿名插槽、具名插槽等slot插槽使用方法
使用 this.$options().data.xxxx xxxx 代指的就是需要重置的对象。
1.可以在调用初期使用 UI 组件提供的初始化方法将组件重构成自己需要的样式,比如修改整体颜色之类的。
2.在 vue 文件中,可以通过使用样式穿透方法进行样式调整。.父元素class /deep/ .需要调整元素class
在 new Vue() 后传入了基本数据,Vue 会先把 data 的内容通过Object.defineProperty()劫持。然后调用Observer类将劫持后数据内部的属性再劫持处理一次。
在这个过程中,会在数据处理的 get 方法中将观察者Dep类注入,并会在 set 方法中通知所有的订阅者更新视图。在Compiler类中将页面中的特殊指令和模板解析,然后调用 data 中的对应属性进行替换,并在相应的处理函数中将订阅者绑定。订阅者Watcher类会先把自身存放进观察者属性中,绑定后订阅者会先触发一次 get 方法,将自己添加进观察者的通知队列中。然后双向绑定的地方需要使用 dom 的属性方法比如 input 的 input 方法将数据改动后告诉 set 方法,那么观察者就会通知队列进行更新。
1.弹性盒子布局。 2.子绝父相。 3.网格布局。
问题分析。主要就是考一下基础的 css 属性组合,酌情回答两到三种就可以了。垂直居中布局详解
具体可查看之前分享的弹性盒子内容,不做赘述。
如左图所示
<div class="box"></div>
<style>
.box {
position: relative;
width: 20px;
height: 3px;
top: 6px;
background: #333;
}
.box::before,
.box::after {
position: absolute;
content: ' ';
width: 20px;
height: 3px;
background: #333;
}
.box::before {
top: -6px;
}
.box::after {
top: 6px;
}
</style>1.分步渲染,先对侧边栏的数据进行处理,比如先展示 20 条,通过数组的切割方法,将数据剥离渲染。
2.滚动监听,监听侧边栏滚动,如果滚动到底部,展示 loading 状态。并再次切割数据,更新渲染。关闭 loading 展示。
作者: 文章链接: https://reinness.com/posts/38 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自小陈同学 !
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。