前端高频面试题大白话讲解,小白也能看懂,面试/查漏补缺必备

📅 2026/8/15 9:44:30
前端高频面试题大白话讲解,小白也能看懂,面试/查漏补缺必备
不管是准备跳槽还是日常巩固基础下面这些前端高频考点都能帮你快速理清思路所有知识点都用大白话讲没有晦涩的专业术语建议收藏慢慢看。一、Vue 核心知识点1. Vue3 为什么能兼容 Vue2 的写法Vue3 在设计的时候就保留了对 Vue2 Options API就是我们常用的 data、methods 这种写法的兼容90% 的 Vue2 代码都能直接搬到 Vue3 里跑。而且 Vue2.7 版本还回移了 Vue3 的 Composition API就算你用的是 Vue2也能用 setup、ref 这些新特性老项目迁移的时候不用一次性全改可以慢慢过渡。2. 切换路由能不能 keep-alive当然可以keep-alive 就是专门用来缓存组件的。比如你从列表页滚到中间跳转到详情页再返回列表页如果没开 keep-alive列表会回到顶部重新加载开了之后列表还停留在你之前看的位置不用重新请求数据。配置很简单要么在路由的 meta 里加keepAlive: true字段要么用keep-alive :include[列表页组件名]指定要缓存的组件被缓存的组件会多出两个生命周期activated切回来时触发和deactivated切走时触发。3. Vue 过滤器就是用来格式化数据的小工具比如把时间戳转成2024-01-01的格式或者给金额前面加符号。Vue2 里可以直接用{{ price | formatPrice }}调用不过 Vue3 已经把过滤器去掉了建议直接用 computed 或者方法代替逻辑更清晰。4. watchEffect 的使用场景和 watch 不一样的是watchEffect 不用你手动指定要监听哪个变量它会自动收集函数里用到的响应式数据只要这些数据变了函数就会重新执行。比如你想监听多个变量的变化然后统一发请求用 watchEffect 就比写一堆 watch 方便多了。5. Provide / Inject用来解决跨多层组件传参的问题比如你有祖孙组件爷爷要给孙子传数据用 props 一层层传太麻烦爷爷用 provide 提供数据孙子用 inject 直接拿就行不用管中间隔了多少层组件。6. Vue 插槽的使用场景简单说就是给组件挖个坑让父组件可以往里面填内容。比如你封装了一个弹窗组件弹窗的标题、内容、按钮都不一样就可以用插槽父组件想填什么就填什么组件复用性直接拉满。7. Vue 的双向绑定原理Vue2 是用Object.defineProperty实现的给每个数据属性加了 getter 和 setter你读数据的时候触发 getter修改数据的时候触发 settersetter 会通知页面更新页面输入框修改的时候会同步更新到数据里。Vue3 换成了 Proxy能监听到新增、删除的属性也不用递归遍历所有属性性能更好。8. v-if 和 v-show 的区别v-if 是真正的销毁/创建组件切走的时候组件直接没了切回来的时候重新创建适合不频繁切换的场景v-show 只是修改 CSS 的display属性组件一直都在内存里只是隐藏了适合频繁切换的场景比如 tab 切换。9. key 值的作用Vue 在更新列表的时候会根据 key 来判断哪些元素是新的、哪些是旧的从而复用已有的 DOM不用重新渲染。如果不用 key 或者用 index 当 key列表顺序变化的时候可能会出现渲染错误比如输入框的内容错位。10. 什么时候要用 Vuex如果只有父子组件传参用 props/$emit 就够了但如果是兄弟组件、跨多层组件传参或者多个组件要共享同一个数据比如用户的登录信息、购物车里的商品就用 Vuex 统一管理不用来回传参数。二、Vue Router 相关1. 静态路由和动态路由的区别静态路由就是路径写死的比如/user/list不管什么时候访问都是这个路径动态路由是路径里带变量的比如/user/:id你访问/user/123和/user/456都会匹配到这个路由通过$route.params.id就能拿到对应的 id。2. 路由传参query 和 paramsquery 传参会在 url 里显示比如/user?id123刷新页面参数不会丢params 传参默认不显示在 url 里除非你在路由配置里写了/:id刷新页面参数会丢适合传不重要的参数。3. 路由跳转为什么要用 decodeURIComponent replace有时候路由传参会带中文或者特殊字符比如、浏览器会自动把这些字符转码比如中文会变成%E4%BD%A0%E5%A5%BD拿到的参数就是乱码所以要先用decodeURIComponent解码才能正常使用。用replace是因为它会替换掉当前的历史记录用户点浏览器的返回键不会回到跳转前的页面适合登录成功跳转这种不需要回退的场景。4. 怎么判断路径上是否有某个参数直接用this.$route.query.参数名或者this.$route.params.参数名就行如果有值就说明有这个参数没有就是undefined。5. 路由统一处理逻辑比如所有页面跳转前都要校验登录状态就可以用路由全局前置守卫router.beforeEach在里面判断有没有 token没有就跳转到登录页不用每个页面都写一遍校验逻辑。三、JavaScript 基础1. 递归和闭包递归就是函数自己调用自己比如算阶乘、遍历树形结构的数据都会用到注意要写终止条件不然会无限循环卡死。闭包就是函数里面套函数里面的函数能访问外面函数的变量就算外面函数执行完了里面的函数还能用这个变量比如用来做私有变量防抖节流里面就用到了闭包。2. 强弱类型语言强类型语言变量类型是固定的比如 Java你定义一个整型变量就不能存字符串弱类型语言变量类型不固定比如 JS一个变量可以先存数字再存字符串灵活但是容易出错。3. 数组的排序方法用sort()方法就行不过要注意默认是按字符串排序的比如[10, 2, 1]排序后会变成[1, 10, 2]要排数字的话要传比较函数arr.sort((a,b) a-b)就是升序b-a就是降序。4. 对象操作删除对象的键值用delete obj.key或者Reflect.deleteProperty(obj, key)对象转数组用Object.entries(obj)会得到[[key1, value1], [key2, value2]]的数组想要只拿 key 就用Object.keys(obj)只拿 value 就用Object.values(obj)改变对象的 key 名先删掉旧的 key再添加新的 key比如obj.newKey obj.oldKey; delete obj.oldKey5. 箭头函数和普通函数的区别箭头函数没有自己的this它的this是继承外层作用域的普通函数的this看调用方式箭头函数不能当构造函数不能new箭头函数没有arguments对象要用可变参数用...rest代替6. 防抖的适用场景就是等用户操作停下来一段时间再执行函数比如搜索框输入的时候不用每次敲一个字都发请求等用户停下来 500ms 再发省服务器资源还有窗口 resize、按钮点击防止重复提交这些场景都用得上。7. 定时器什么时候开启和清除比如在组件的mounted里开启定时器在beforeDestroyVue2或者onUnmountedVue3里清除不然组件销毁了定时器还在跑会内存泄漏。8. window.open 和关闭当前页打开新窗口window.open(url, _blank)可以在新标签页打开链接要打开多个就调多次。不过现在浏览器会拦截非用户触发比如点击事件的window.open容易被当成弹窗广告。要关闭当前页同时打开新窗口的话先window.open(url)打开新窗口再window.close()关闭当前页不过当前页如果不是脚本打开的浏览器可能会拦截关闭操作。四、CSS 与样式1. rem 和 em 的计算方法rem 是相对根元素html的字体大小计算的比如html { font-size: 16px }那么2rem就是32px不管嵌套多少层rem 的基准都是根元素不会乱。em 是相对父元素的字体大小计算的如果父元素没设置字体大小就继承更上层的嵌套多了会越套越大比如父元素是2em子元素也是2em那子元素就是父元素字体大小的 2 倍容易失控所以一般做响应式适配都用 rem。2. pre 标签为什么能识别换行符因为 pre 标签的white-space属性默认是pre会保留文本里的空格和换行符不像普通 div 会把多个空格合并成一个换行符也会被忽略。3. 什么时候用行内样式一般不建议用除非是动态样式比如进度条的宽度是根据数据来的或者用 JS 动态修改样式的时候才会用行内样式不然都写在 css 文件里方便维护。4. flexible.js是淘宝出的一套移动端适配方案原理是根据屏幕宽度动态修改根元素html的字体大小然后用 rem 做单位这样不同屏幕尺寸下元素的大小就能按比例缩放不用写一堆媒体查询。五、前端工程化与工具1. 前端脚手架是什么就是帮你快速搭建项目框架的工具比如 Vue 的vue/cli、Vite你不用自己配置 webpack、babel 这些复杂的东西一条命令就能生成一个带完整配置的项目直接开发就行。2. 前端模块化规范CommonJS用require引入module.exports导出同步加载Node.js 用的就是这个适合服务端AMD用define定义模块require引入异步加载RequireJS 是这个规范的实现适合浏览器端CMD和 AMD 类似不过是按需加载SeaJS 是这个规范的实现ESModule现在主流的规范用import引入export导出支持 tree-shaking打包体积更小3. CDN 方式引入就是把第三方的库比如 Vue、jQuery放在 CDN 服务器上你直接用script srccdn链接/script引入不用下载到本地加载速度快还能利用浏览器的缓存。4. 配置 alias 路径别名就是为了不用写一长串相对路径比如在vue.config.js里配置: path.resolve(__dirname, src)之后引入文件就可以用/components/xxx.vue代替../../../components/xxx.vue方便多了。5. Nuxt 为什么要用~引入文件Nuxt 是服务端的框架~代表的是项目的根目录代表的是src目录用~引入可以保证不管文件在哪个层级路径都不会错和服务端渲染的路径解析逻辑匹配。六、实战踩坑与问题解决1. uniapp 开发常见的 bug不同平台的样式兼容问题比如微信小程序和 H5 的 flex 布局有点差异条件编译没写好导致某个平台的代码在另一个平台报错原生 API 调用失败比如定位、扫码没加权限配置2. 公众号开发定位失败跳转先判断是不是用户没给定位权限如果是的话跳转到系统的定位设置页面引导用户打开权限代码大概是先调用wx.getLocation失败的话判断错误码如果是权限问题就跳转到weixin://settings/general/location微信的定位设置页。3. 微信开发者工具正常手机上不行大概率是域名配置的问题公众号的 JS 安全域名、小程序的 request 合法域名都要配置成你线上的域名本地测试的域名手机上不认。还有可能是缓存问题清一下微信的缓存再试。4. mpeg4 格式在安卓浏览器打不开安卓浏览器对视频格式的支持不一样有的不支持 mpeg4建议转成 H.264 编码的 mp4兼容性最好基本所有浏览器都能播。5. Vue 项目里 PDF 转图片用pdfjs-dist这个库先把 PDF 加载进来然后遍历每一页用 canvas 把每一页渲染出来再用canvas.toDataURL()转成图片就能下载或者展示了。6. Vue 下载后端返回的 PDF 链接如果后端返回的是文件流就用axios请求的时候设置responseType: blob然后创建一个a标签把 blob 转成 url设置download属性模拟点击下载就行。7. 微信支付方法封装把微信支付的流程封装成一个公共方法先调用后端接口拿支付参数然后调用微信的 JSAPI 支付接口处理成功和失败的回调返回 Promise这样每个页面调用的时候就不用重复写逻辑了。七、其他高频问题1. 浏览器加载页面的顺序DNS 解析域名拿到 IP→建立 TCP 连接→发送 HTTP 请求→服务器返回 HTML→浏览器解析 HTML 生成 DOM 树同时解析 CSS 生成 CSSOM 树→合并 DOM 和 CSSOM 生成渲染树→布局计算元素的位置大小→绘制到屏幕上。2. MVVM 的理解MVVM 就是 Model数据、View页面、ViewModel中间层ViewModel 负责把 Model 的数据同步到 View也把 View 的操作同步到 ModelVue 就是典型的 MVVM 框架我们不用手动操作 DOM改数据页面就会自动更新。3. axios 的作用就是对原生 XMLHttpRequest 的封装支持 Promise用起来更方便还能配置拦截器统一处理请求头、错误响应比如所有请求都加上 token所有错误都弹出提示不用每个请求都写一遍。4. 常见的 HTTP 请求方式GET获取数据参数在 url 里POST提交数据参数在请求体里PUT修改数据一般是全量修改DELETE删除数据PATCH修改数据一般是局部修改5. 父子组件传参父传子用 props子传父用$emit触发自定义事件父组件在子组件标签上监听这个事件就行。6. 父组件调用子组件的方法给子组件加个 ref比如Child refchild /然后父组件里用this.$refs.child.方法名()就能调用子组件的方法了。