📌Vue 核心考点(面试官必问!)
1. Vue 的生命周期有哪些?一般在哪一步发起请求及原因?
Vue2 共 8 个核心钩子,Vue3 命名优化,记牢这张表就够!
| Vue2 | Vue3 对应 | 核心作用 |
|---|---|---|
| beforeCreate | setup(合并) | 实例初始化前,el/data 全没有❌ |
| created | setup(合并) | data 就绪、el 未挂载,可初始请求(需 $nextTick 操作 DOM) |
| beforeMount | onBeforeMount | 虚拟 DOM 创建完,即将渲染 |
| mounted | onMounted | 🚩推荐请求时机!真实 DOM 挂载完成,可操作 DOM + 访问实例资源 |
| beforeUpdate | onBeforeUpdate | 响应式数据变了,DOM 还没更 |
| updated | onUpdated | DOM 已更新,别改数据(防死循环)♻️ |
| beforeDestroy | onBeforeUnmount | 实例销毁前,清定时器 / 解绑事件🗑️ |
| destroyed | onUnmounted | 实例彻底销毁,子组件 + 事件全没了 |
| activated | onActivated | keep-alive 组件激活时 |
| deactivated | onDeactivated | keep-alive 组件停用时 |
2. keep-alive 的使用场景与核心特性
- 作用:缓存不活动组件,避免重复创建销毁,提升性能⚡️
- 场景:列表页→详情页、tab 切换(保留表单输入 / 滚动位置)
- 关键属性:include(指定缓存组件)、exclude(排除缓存组件)
- 示例:
<keep-alive include="Home,User">
<router-view /> <!-- 只缓存Home和User组件 -->
</keep-alive>
3. 父子组件生命周期执行顺序
- 挂载:父 beforeCreate→父 created→父 beforeMount→子 beforeCreate→子 created→子 beforeMount→子 mounted→父 mounted 📥
- 更新:父 beforeUpdate→子 beforeUpdate→子 updated→父 updated 🔄
- 销毁:父 beforeDestroy→子 beforeDestroy→子 destroyed→父 destroyed 📤
4. Vue 组件间通信方式(7 种全收录)
| 通信场景 | 推荐方案 | 核心说明 |
|---|---|---|
| 父子组件 | props/$emit | 父传子用 props(单向数据流),子传父用 $emit 触发父事件🎯 |
| 兄弟组件 | EventBus/Pinia | 小项目用 EventBus,中大型用 Pinia(更稳) |
| 隔代组件 | provide/inject/$attrs | 深层传递不用层层 props,provide 传、inject 接(非响应式加 ref/reactive) |
| 全局状态 | Pinia(替代 Vuex) | 轻量、TS 友好,支持模块化,不用嵌套命名空间👍 |
| 跨页面通信 | localStorage/sessionStorage | 存非敏感数据,需手动序列化(JSON.stringify/parse) |
| 父子直接访问 | parent/children | 耦合度高,偶尔用(比如临时拿父组件方法) |
| 复杂场景 | $refs | 父组件直接访问子组件 DOM / 方法(ref 绑定子组件) |
5. Pinia 与 Vuex 的核心区别
| 特性 | Pinia | Vuex |
|---|---|---|
| API 复杂度 | 简单!Composition API 风格 | 复杂!需 state/mutations/actions/getters |
| 状态管理 | 多 store 分散管理 | 单一状态树,靠 modules 拆分 |
| TS 支持 | 原生支持,类型超准 | 需手动配置,支持弱 |
| 体积 | <1KB,超轻量 | 较冗余,大型项目有性能开销 |
| 调试 | 支持 Vue DevTools,直观 | 支持但配置麻烦 |
6. v-if 与 v-show 的区别及使用场景
- v-if:条件为真才渲染 DOM,假则销毁→ 切换开销大、初始渲染开销小👉 用在权限控制、条件少变(如登录 / 未登录展示)🔒
- v-show:始终渲染 DOM,用 display: none 控制→ 切换开销小、初始渲染开销大👉 用在 tab 切换、条件频繁变(如开关展示)🔄
7. computed、watch、methods 的区别
| 特性 | computed(计算属性) | watch(监听器) | methods(方法) |
|---|---|---|---|
| 缓存 | 有!依赖不变则复用结果 | 无缓存,数据变就触发 | 无缓存,调用就执行 |
| 触发方式 | 依赖数据变自动触发 | 监听数据变触发 | 手动调用(事件 / 其他地方调) |
| 异步支持 | 不支持(需返回同步结果) | 支持(比如监听数据发接口) | 支持(任意逻辑) |
| 用途 | 数据派生(拼接、计算总和) | 数据变化副作用(请求、改状态) | 事件处理、通用逻辑复用 |
8. Vue 的响应式原理
-
Vue2:Object.defineProperty 劫持对象属性的 get/set,监听数据读写📝
- 缺点:无法监听数组索引 / 长度变化、新增属性需用 Vue.set
-
Vue3:Proxy 代理整个对象,拦截所有操作(读写、删除、新增)🚀
- 优点:天然支持数组变化、新增属性,劫持更全面
-
核心:数据变→ 触发依赖收集→ 通知组件重新渲染
9. v-for 与 v-if 为什么不建议一起用?
-
问题:v-for 优先级比 v-if 高,会先循环再判断,遍历所有元素后才过滤,浪费性能⚠️
-
解决:
- 用 computed 过滤数据(先筛再循环)
- 在外层用 template 包 v-if(控制整个循环是否执行)
10. Vue 中的 key 有什么作用?
-
核心:给虚拟 DOM 节点打唯一标识,帮助 Vuediff 算法高效对比🆔
-
作用:
- 避免重复渲染,提升性能
- 确保组件状态正确(如 v-for 中用 index 当 key 可能导致状态错乱)
-
推荐:用唯一 ID 当 key(如后端返回的 id),别用 index!
🚀JavaScript 核心考点(重中之重!)
1. 数据类型与判断方式
- 基本类型(6 种):String、Number、Boolean、Undefined、Null、Symbol(ES6 新增)
- 引用类型:Object(包含 Array、Function、Date、RegExp 等)
- 准确判断方法:
运行
// 原始类型(除null)
typeof 'abc' // 'string'
typeof 123 // 'number'
// 引用类型
[] instanceof Array // true
{} instanceof Object // true
// 通用判断(含null)
Object.prototype.toString.call(null) // '[object Null]'
Object.prototype.toString.call([]) // '[object Array]'
2. 闭包的概念、用途与风险
-
概念:函数 + 声明时的词法环境,函数在外部执行仍能访问内部变量🤫
-
用途:
- 数据缓存(如缓存计算结果,避免重复计算)
- 封装私有变量(避免全局污染)
- 延迟执行(定时器 / 回调中访问外部变量)
-
风险:过度使用导致内存占用增加,可能引发内存泄漏→ 解决方案:及时释放引用(置为 null)
3. 原型与原型链
-
核心概念:
- 每个引用类型有
__proto__(隐式原型),指向构造函数的prototype(显式原型) - 访问属性时,自身没有就通过
__proto__向上找,直到 Object.prototype(顶端,__proto__为 null)
- 每个引用类型有
-
关键结论:原型链实现继承(如数组能调用 push,是因为继承了 Array.prototype 的方法)
4. 事件循环(Event Loop)机制
- JS 是单线程,靠事件循环实现异步→ 执行顺序:同步任务→ 所有微任务→ 下一个宏任务🔄
- 宏任务:script、setTimeout、setInterval、I/O、UI 交互
- 微任务:Promise.then/catch/finally、MutationObserver、process.nextTick(Node)
- 示例执行结果:
console.log('1') // 同步
setTimeout(() => console.log('2'), 0) // 宏任务
Promise.resolve().then(() => console.log('3')) // 微任务
console.log('4') // 同步
// 结果:1→4→3→2
5. 深拷贝与浅拷贝的实现
- 浅拷贝(仅复制表层,引用类型共享地址):
const obj = { a: 1, b: { c: 2 } }
const shallow1 = Object.assign({}, obj)
const shallow2 = { ...obj }
- 深拷贝(完全复制,引用类型独立):
// 递归实现(通用)
function deepClone(source) {
if (!source || typeof source !== 'object') return source
const target = Array.isArray(source) ? [] : {}
for (const key in source) {
if (source.hasOwnProperty(key)) {
target[key] = deepClone(source[key])
}
}
return target
}
// JSON.parse(有局限)
const deep = JSON.parse(JSON.stringify(obj))
// 局限:不能拷函数/undefined/Symbol/循环引用,日期转字符串
6. 防抖与节流(实战必备)
- 防抖(debounce):触发后延迟 n 秒执行,重复触发重新计时→ 输入框搜索、窗口 resize⏳
function debounce(fn, wait) {
let timer = null
return (...args) => {
clearTimeout(timer)
timer = setTimeout(() => fn.apply(this, args), wait)
}
}
- 节流(throttle):单位时间内仅执行一次,重复触发不生效→ 滚动加载、按钮防重复点击🚫
function throttle(fn, wait) {
let lastTime = 0
return (...args) => {
const now = Date.now()
if (now - lastTime >= wait) {
fn.apply(this, args)
lastTime = now
}
}
}
7. 原型继承的几种方式
-
- 原型链继承:Child.prototype = new Parent ()
-
- 构造函数继承:Parent.call (this, args)(解决原型链继承的属性共享问题)
-
- 组合继承:原型链 + 构造函数(常用!)
-
- ES6 类继承:class Child extends Parent {constructor () { super () } }(语法糖,本质是组合继承)
8. this 指向问题(高频!)
- 普通函数:谁调用指向谁(全局调用指向 window/global,严格模式 undefined)
- 箭头函数:没有自己的 this,指向定义时外层作用域的 this(不绑定 this)
- 绑定 this 的方法:call(参数列表)、apply(参数数组)、bind(返回新函数)
const obj = { name: '张三' }
function sayName() { console.log(this.name) }
sayName.call(obj) // 张三
sayName.apply(obj) // 张三
const fn = sayName.bind(obj)
fn() // 张三
9. Promise 的状态与使用
-
状态:pending(等待)→ fulfilled(成功)/rejected(失败)(状态不可逆)
-
常用方法:
- Promise.resolve ()/reject ():快速创建 Promise
- then ():成功回调
- catch ():失败回调
- finally ():无论成功失败都执行
-
异步并发:
- Promise.all ():所有成功才成功,一个失败就失败
- Promise.race ():第一个完成的状态决定结果
10. 箭头函数与普通函数的区别
- 箭头函数没有 this、arguments、prototype
- 不能当构造函数(不能 new)
- 语法更简洁(单参数可省括号,单语句可省大括号 + return)
- this 指向外层作用域,不会被 call/apply/bind 改变
11. 变量提升与函数提升
- 变量提升:var 声明的变量会提升到作用域顶部,初始值为 undefined(let/const 不会变量提升,有暂时性死区)
- 函数提升:函数声明会整体提升(函数表达式不会)
console.log(a) // undefined(var提升)
var a = 10
fn() // 能执行(函数提升)
function fn() { console.log('hello') }
fn2() // 报错(函数表达式不提升)
const fn2 = function() {}
12. 模块化(ES6 Module vs CommonJS)
| 特性 | ES6 Module(import/export) | CommonJS(require/module.exports) |
|---|---|---|
| 加载方式 | 静态加载(编译时加载) | 动态加载(运行时加载) |
| 输出 | 值引用 | 浅拷贝引用 |
| 适用环境 | 浏览器 + Node(需配置) | Node 环境 |
| 语法 | export 导出,import 导入 | module.exports 导出,require 导入 |
🎨CSS 核心考点
1. Flex 布局(必会!)
-
父容器核心属性:
- display: flex(开启 Flex)
- justify-content:主轴对齐(center/space-between/space-around)
- align-items:副轴对齐(center/stretch/flex-start)
- flex-wrap:是否换行(wrap/nowrap)
-
子元素核心属性:
- flex: 1(占满剩余空间)
- align-self:单独设置自身对齐方式
-
用途:快速实现居中、自适应布局(项目中最常用!)🎉
2. 盒子模型
- 标准盒模型(content-box):width = 内容宽度(默认)
- 怪异盒模型(border-box):width = 内容 + 内边距 + 边框
- 切换:box-sizing: border-box(项目中推荐用,避免计算麻烦)
3. 垂直居中 3 种实用方法
-
- Flex 布局(最简单):
.parent {
display: flex;
align-items: center;
justify-content: center;
}
-
- 绝对定位 + transform:
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
-
- 表格布局:
.parent {
display: table-cell;
vertical-align: middle;
text-align: center;
}
.child {
display: inline-block;
}
4. CSS 优先级
- 优先级顺序:!important > 内联样式(style)> id 选择器(#id)> class 选择器(.class)> 标签选择器(div)
- 权重计算:内联 1000,id100,class10,标签 1→ 同权重后定义的生效
- 注意:!important 慎用,会覆盖所有规则(除非其他规则也加!important 且权重更高)
5. 选择器有哪些?
- 基础选择器:id、class、标签、通配符(*)
- 组合选择器:后代(空格)、子代(>)、相邻兄弟(+)、通用兄弟(~)
- 伪类选择器::hover、:active、:focus、:nth-child ()
- 伪元素选择器:::before、::after(需配合 content 属性)
6. 浮动(float)的影响与清除
-
影响:浮动元素脱离文档流,导致父元素高度塌陷
-
清除浮动方法:
- 父元素加 overflow: hidden
- 父元素末尾加空 div,设置 clear: both
- 用伪元素清除(推荐):
.parent::after {
content: '';
display: block;
clear: both;
}
7. CSS3 新特性
- 边框:border-radius(圆角)、border-image(边框图片)
- 背景:background-gradient(渐变)、background-size(背景大小)
- 动画:transition(过渡)、animation(动画)
- 其他:flex、grid(网格布局)、rgba(透明色)、box-shadow(阴影)
8. 响应式布局实现方式
-
- 媒体查询(@media):根据屏幕宽度写不同样式📱
@media (max-width: 768px) { /* 移动端样式 */
.container { width: 100%; padding: 0 10px; }
}
@media (min-width: 769px) and (max-width: 1200px) { /* 平板样式 */
.container { width: 90%; margin: 0 auto; }
}
@media (min-width: 1201px) { /* 桌面端样式 */
.container { width: 1200px; margin: 0 auto; }
}
-
- 弹性布局(Flex)/ 网格布局(Grid):天然自适应,不用写多套样式
-
- 相对单位:用 rem(相对于根元素字体大小)、vw/vh(相对于视口尺寸)代替 px
-
- 图片响应式:
max-width: 100%; height: auto;避免图片溢出
- 图片响应式:
9. BFC 是什么?有什么用?
-
概念:块级格式化上下文(Block Formatting Context),独立渲染区域,内部元素布局不影响外部🌍
-
触发条件(满足一个即可):
- 浮动元素(float≠none)
- 定位元素(position=absolute/fixed)
- display=inline-block/table-cell/table-caption
- overflow≠visible(hidden/auto/scroll)
-
核心作用:
- 清除浮动(解决父元素高度塌陷)
- 避免 margin 重叠(兄弟元素 / 父子元素 margin 合并问题)
- 阻止元素被浮动元素覆盖
10. 回流(Reflow)与重绘(Repaint)
-
回流:DOM 结构 / 几何属性变了(如宽高、位置、增删节点),浏览器重新计算布局→ 性能开销大⚠️
-
重绘:样式变了但不影响布局(如颜色、背景色),浏览器重新绘制→ 性能开销小
-
优化技巧:
- 批量修改样式(用 class 代替 inline 样式)
- 避免频繁操作 DOM(用文档片段 DocumentFragment)
- 复杂动画用 absolute/fixed 脱离文档流
- 避免 table 布局(table 修改会触发全表回流)
11. 定位(position)的 5 种属性
| 定位属性 | 核心特点 | 适用场景 |
|---|---|---|
| static | 默认值,正常文档流,不受 top/left 影响 | 普通元素布局 |
| relative | 相对自身原位置偏移,不脱离文档流 | 微调元素位置、作为绝对定位父容器 |
| absolute | 绝对定位,脱离文档流,相对于最近定位父元素 | 弹窗、悬浮组件 |
| fixed | 固定定位,脱离文档流,相对于浏览器窗口 | 导航栏、回到顶部按钮 |
| sticky | 粘性定位,滚动到阈值后固定(需配合 top/left) | 列表标题、滚动跟随组件 |
12. CSS 渐变与阴影
- 线性渐变:
background: linear-gradient(方向, 颜色1, 颜色2)
/* 从左到右,红→蓝渐变 */
.bg-gradient {
background: linear-gradient(to right, red, blue);
}
- 盒阴影:
box-shadow: 水平偏移 垂直偏移 模糊度 扩散度 颜色 内阴影(inset)
/* 灰色外阴影,带模糊 */
.box {
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
- 文字阴影:
text-shadow: 水平偏移 垂直偏移 模糊度 颜色
.text-shadow {
text-shadow: 1px 1px 3px #666;
}
🌐浏览器核心考点
1. 从输入 URL 到显示页面的完整流程
-
DNS 解析:把域名(如www.baidu.com)转 IP 地址📡
-
建立 TCP 连接:三次握手(客户端→服务器→客户端,确认双方通信能力)🤝
-
发送 HTTP 请求:客户端向服务器发送请求(请求行、请求头、请求体)
-
服务器处理请求:解析请求,查询数据库 / 处理业务逻辑,返回响应
-
接收响应:服务器返回 HTTP 响应(状态码、响应头、响应体)
-
关闭 TCP 连接:四次挥手(双方确认数据传输完成)👋
-
浏览器解析渲染:
- 解析 HTML 生成 DOM 树
- 解析 CSS 生成 CSSOM 树
- 合并为渲染树(Render Tree)
- 布局(回流)→ 绘制(重绘)→ 显示页面
-
执行 JavaScript:JS 会阻塞 DOM/CSSOM 构建(可加 defer/async 优化)
2. HTTP 与 HTTPS 的区别
| 特性 | HTTP | HTTPS |
|---|---|---|
| 安全性 | 明文传输,无加密,不安全⚠️ | SSL/TLS 加密,安全✅ |
| 端口 | 80 | 443 |
| 证书 | 不需要 | 需要 CA 证书(需付费 / 免费申请) |
| 性能 | 传输快(无加密开销) | 略慢(需加密解密) |
| 适用场景 | 非敏感数据(如静态页面) | 敏感数据(支付、登录、个人信息) |
3. HTTP 状态码分类与常用码
- 1XX:信息状态码(如 100 Continue,临时响应)
- 2XX:成功(200 OK - 请求成功,201 Created - 资源创建成功)✅
- 3XX:重定向(301 永久重定向,302 临时重定向,304 Not Modified - 缓存命中)🔄
- 4XX:客户端错误(400 Bad Request - 请求参数错误,401 未授权,403 禁止访问,404 资源未找到)❌
- 5XX:服务器错误(500 服务器内部错误,503 服务不可用 - 服务器过载 / 维护)💥
4. GET 与 POST 的区别
| 特性 | GET | POST |
|---|---|---|
| 参数位置 | URL 拼接(可见) | 请求体(不可见,相对安全) |
| 数据大小限制 | 有限制(约 2KB,因浏览器而异) | 无限制(由服务器配置决定) |
| 缓存 | 可缓存(浏览器记录 URL) | 不可缓存 |
| 幂等性 | 幂等(多次请求结果一致) | 非幂等(多次请求可能重复提交) |
| 适用场景 | 查询数据(如搜索、列表) | 提交数据(如登录、注册、上传) |
5. 跨域问题(原因 + 解决方案)
-
原因:浏览器同源策略(域名、协议、端口必须完全相同),防止恶意网站窃取数据🚫
-
常用解决方案:
-
CORS(推荐):后端设置响应头
Access-Control-Allow-Origin: *(允许所有域名)或指定域名 -
JSONP:利用 script 标签跨域特性,仅支持 GET 请求(需后端配合返回回调函数)
-
代理转发:
- 开发环境:webpack-dev-server 配置 proxy
- 生产环境:Nginx 反向代理(把跨域请求转发为同源请求)
-
localStorage+iframe:适合简单数据传递(需双方页面配合)
-
6. 浏览器缓存机制(强缓存 + 协商缓存)
-
强缓存:浏览器直接用本地缓存,不发请求→ 控制头:Cache-Control(优先级高)、Expires
- Cache-Control: max-age=3600(缓存 1 小时)
- 优点:速度快,无网络请求开销
-
协商缓存:浏览器发请求问服务器 “缓存是否过期”,服务器判断是否用缓存→ 控制头:Last-Modified/If-Modified-Since、ETag/If-None-Match
- 服务器返回 304 Not Modified→ 用缓存;返回 200→ 更新缓存
-
缓存优先级:强缓存 > 协商缓存 > 重新请求
7. Cookie、localStorage、sessionStorage 的区别
| 特性 | Cookie | localStorage | sessionStorage |
|---|---|---|---|
| 存储大小 | 约 4KB | 约 5MB | 约 5MB |
| 有效期 | 可设置(默认会话级,关闭浏览器失效) | 永久有效(需手动删除) | 会话级(关闭标签页 / 浏览器失效) |
| 通信 | 随 HTTP 请求发送到服务器 | 仅本地存储,不发服务器 | 仅本地存储,不发服务器 |
| 作用域 | 同域名(子域名可配置) | 同域名、同协议、同端口 | 仅当前标签页(同源不同标签页不共享) |
| 用途 | 存储身份标识(如 token)、记住密码 | 长期存储非敏感数据(如用户偏好) | 临时存储(如表单临时数据) |
8. XSS 攻击与 CSRF 攻击(安全考点)
XSS 攻击(跨站脚本攻击)
-
原理:注入恶意 JavaScript 代码到页面,窃取用户 Cookie、劫持会话😈
-
攻击类型:
- 反射型:恶意代码在 URL 中,诱导用户点击(如搜索框注入)
- 存储型:恶意代码存入服务器(如评论区、论坛)
-
防御方案:
- 输入过滤:过滤
<script>等危险标签 - 输出转义:把特殊字符(如 <→<)转义后渲染
- 用 CSP(内容安全策略)限制脚本加载源
- 输入过滤:过滤
CSRF 攻击(跨站请求伪造)
-
原理:盗用用户身份,以用户名义发送恶意请求(如转账、改密码)
-
防御方案:
- 验证 Referer(请求来源域名)
- 加 CSRF Token(服务器生成随机 token,请求时携带验证)
- 敏感操作需二次验证(如输入密码、短信验证)
9. 浏览器内核(渲染引擎 + JS 引擎)
-
渲染引擎:负责解析 HTML/CSS,渲染页面
- Chrome/Safari:WebKit(Safari)→ Blink(Chrome 后续自研)
- Firefox:Gecko
- IE:Trident(已淘汰)
-
JS 引擎:负责解析执行 JavaScript
- Chrome:V8(性能最强,Node.js 也用)
- Safari:JavaScriptCore
- Firefox:SpiderMonkey
10. 宏任务与微任务(事件循环补充)
-
宏任务队列:script(整体代码)、setTimeout、setInterval、I/O、UI 交互事件、setImmediate(Node)
-
微任务队列:Promise.then/catch/finally、MutationObserver、process.nextTick(Node,优先级最高)
-
执行规则:
- 先执行同步代码
- 清空当前所有微任务(按顺序执行)
- 执行一个宏任务
- 重复 2-3 步骤,直到所有任务完成
🛠️工程化与框架补充考点
1. 前端工程化的核心(模块化、组件化、规范化、自动化)
- 模块化:把代码拆分为独立模块(如 ES6 Module、CommonJS),避免全局污染
- 组件化:UI 拆分为可复用组件(如 Vue 组件、React 组件),提高开发效率
- 规范化:制定目录结构、编码规范、接口规范、Git 分支规范、Commit 规范
- 自动化:自动化构建(Webpack/Vite)、自动化测试(Jest)、自动化部署(CI/CD)、自动化 lint(ESLint)
2. Webpack 与 Vite 的区别
| 特性 | Webpack | Vite |
|---|---|---|
| 开发模式 | 打包后启动服务(冷启动慢) | 原生 ES Module,按需编译(冷启动快)⚡️ |
| 热更新 | 需配置 HotModuleReplacement,大型项目慢 | 原生热更新,速度快(毫秒级) |
| 配置复杂度 | 高(需配置 loader、plugin) | 低(零配置启动,按需配置) |
| 适用场景 | 大型复杂项目(支持各种场景) | 中小型项目、Vue/React 项目(开发体验好) |
| 生产构建 | 成熟,优化插件多(如 Tree-shaking、代码分割) | 用 Rollup 打包,优化到位 |
3. 小程序核心考点
小程序文件类型
-
WXML:页面结构(类似 HTML,用小程序内置组件)
-
WXSS:样式(类似 CSS,支持 rpx 单位,自动适配屏幕)
-
JS:逻辑处理(生命周期、事件、网络请求)
-
JSON:配置文件(页面注册、窗口样式、tabBar 配置)
- app.json:全局配置(必须有,项目入口)
- page.json:页面单独配置(覆盖全局配置)
小程序双向绑定与 Vue 的区别
- Vue:
v-model直接绑定,数据变 DOM 自动更 - 小程序:不能直接
this.data.key = value,需用this.setData({ key: value })触发 DOM 更新
// 小程序正确写法
this.setData({
username: '张三'
})
小程序页面间通信方式
- 全局变量:app.js 中定义
globalData,用getApp().globalData访问 - URL 传参:
wx.navigateTo({ url: '/pages/detail/detail?id=1' }),目标页面 onLoad 接收options.id - 本地缓存:
wx.setStorageSync('key', value)存储,wx.getStorageSync('key')读取 - 事件总线:用
wx.$emit/wx.$on(需自己实现或用第三方库) - 父子组件通信:父传子用 props,子传父用 triggerEvent
小程序路由跳转方式(5 种)
- wx.navigateTo:保留当前页面,跳转到非 tab 页(最多 10 层页面)
- wx.redirectTo:关闭当前页面,跳转到非 tab 页
- wx.switchTab:跳转到 tab 页,关闭其他非 tab 页
- wx.navigateBack:关闭当前页面,返回上一页面(可指定返回层数)
- wx.reLaunch:关闭所有页面,跳转到任意页面
小程序与 H5 的区别
- 运行环境:小程序在微信内置浏览器(X5 内核),H5 在普通浏览器
- 开发成本:小程序有固定语法 / 组件,需适配微信规则;H5 需兼容多浏览器
- 性能:小程序加载快(有缓存机制),H5 依赖网络(首屏加载可能慢)
- 功能限制:小程序有微信生态支持(如支付、分享),但接口 / API 有限制;H5 功能更灵活,但依赖浏览器支持
4. Vue3 与 Vue2 的核心区别
-
响应式原理:Vue2 用 Object.defineProperty,Vue3 用 Proxy(支持数组索引、新增属性)
-
API 风格:Vue2 以 Options API 为主,Vue3 支持 Composition API(更灵活复用逻辑)+ Options API
-
性能:Vue3 重写虚拟 DOM、优化编译,初始化 / 更新速度比 Vue2 快 1.3-2 倍
-
其他:
- Vue3 支持多根节点组件
- 移除过滤器(用计算属性 / 方法替代)
- 引入 Teleport( teleport 组件,跨 DOM 渲染)
- Pinia 替代 Vuex
- 支持 TypeScript 更友好
5. script setup 与 defineComponent 的区别
- script setup:Vue3.2 + 语法糖,简洁高效,直接写 Composition API,无需 return(变量 / 函数自动暴露给模板)
<script setup>
import { ref } from 'vue'
const count = ref(0) // 直接在模板用{{ count }}
</script>
- defineComponent:传统写法,需显式 return 变量 / 函数,支持 Options API,适合老项目迁移
<script>
import { defineComponent, ref } from 'vue'
export default defineComponent({
setup() {
const count = ref(0)
return { count } // 必须return才能在模板用
}
})
</script>
6. 前端性能优化核心技巧
-
网络优化:
- 资源压缩(JS/CSS/HTML/ 图片)
- 图片优化(懒加载、WebP 格式、雪碧图)
- 接口优化(合并接口、缓存接口数据、分页加载)
- 用 CDN 加载第三方资源
-
渲染优化:
- 减少回流 / 重绘(批量修改 DOM、脱离文档流)
- 懒加载组件(Vue 的 defineAsyncComponent、React 的 React.lazy)
- 用 keep-alive 缓存组件
-
代码优化:
- Tree-shaking 移除无用代码
- 代码分割(Webpack splitChunks)
- 避免闭包过度使用、减少全局变量
- 防抖节流处理高频事件(滚动、输入)
💡面试加分小技巧
- 遇到不会的题,先讲相关知识点:“这个问题我没深入研究,但我知道和 XX 知识点相关,比如 XXX”,别直接说 “不会”🤔
- 结合项目实战:每个知识点尽量说 “我在项目中用 XX 做过 XX 需求,遇到 XX 问题,用 XX 方案解决”,体现落地能力
- 主动拓展:面试官问 A,可补充 “A 的原理是 XX,还有个类似方案 B,适用场景是 XX”,展现知识面
- 保持自信:声音洪亮、眼神交流,面试是双向选择,不用过度紧张✨