一、Vue2 核心机制
1. Vue2 的响应式原理是什么?
-
答案 :
Vue2 通过Object.defineProperty
给对象的每个属性添加getter
和setter
,当数据被访问或修改时,自动触发视图更新。 -
通俗解释 :
就像给每个数据绑了一个"监控摄像头",数据一变化,立即通知页面刷新。 -
代码示例 :
javascriptconst data = { name: '张三' }; Object.defineProperty(data, 'name', { get() { console.log('有人读取name了'); }, set(newVal) { console.log('有人修改name了,更新页面!'); } });
2. Vue 的生命周期钩子有哪些?
- 核心钩子 :
- beforeCreate :实例刚创建,数据观测和事件还未初始化(无法访问
data
)。 - created:数据已初始化,可调用接口,但 DOM 未渲染(常用于数据请求)。
- beforeMount:模板编译完成,但未挂载到页面。
- mounted:DOM 已渲染完成,可操作 DOM 或第三方库(如初始化地图)。
- beforeUpdate:数据变化前,可获取更新前的 DOM 状态。
- updated:数据变化后,DOM 已更新(避免在此修改数据,可能导致死循环)。
- beforeDestroy:实例销毁前,清理定时器或解绑事件。
- destroyed:实例销毁完成。
- beforeCreate :实例刚创建,数据观测和事件还未初始化(无法访问
- 口诀:创建 → 挂载 → 更新 → 销毁,每个阶段都有"前"和"后"。
二、模板与指令
3. v-if
和 v-show
的区别?
v-if
:条件为假时,元素从 DOM 中移除。适合切换频率低的场景(如权限控制)。v-show
:通过 CSS 的display: none
隐藏元素,DOM 仍存在。适合频繁切换的场景(如折叠面板)。- 比喻 :
v-if
像拆房子(重建成本高),v-show
像关灯(快速切换)。
4. computed
和 watch
的区别?
-
computed
:- 缓存:依赖的数据不变时,直接返回缓存结果。
- 场景:多数据影响的复杂计算(如购物车总价)。
javascriptcomputed: { total() { return this.price * this.quantity; } }
-
watch
:- 监听:数据变化时执行异步或复杂操作(如搜索请求)。
- 场景:数据变化后需要额外处理(如路由参数变化重新加载数据)。
javascriptwatch: { searchText(newVal) { this.fetchData(newVal); } }
三、组件通信
5. 父子组件如何通信?
-
父 → 子:
html<!-- 父组件传递数据 --> <Child :msg="parentMsg" />
javascript// 子组件接收 props: ['msg']
-
子 → 父:
html<!-- 子组件触发事件 --> <button @click="$emit('update', data)">提交</button>
html<!-- 父组件监听 --> <Child @update="handleUpdate" />
6. 非父子组件如何通信?
-
Event Bus(事件总线):
javascript// 创建全局事件中心 const bus = new Vue(); // 组件A发送事件 bus.$emit('message', 'Hello'); // 组件B监听事件 bus.$on('message', (msg) => { console.log(msg); });
-
Vuex(状态管理) :
集中管理共享状态,适合中大型项目。
四、进阶问题
7. Vue 的虚拟 DOM 是什么?有什么优势?
- 虚拟 DOM:用 JavaScript 对象描述真实 DOM 结构。
- 优势 :
- 减少 DOM 操作:通过对比新旧虚拟 DOM,找出最小更新范围。
- 跨平台:可渲染到非浏览器环境(如移动端、服务器)。
- 比喻:虚拟 DOM 像建筑图纸,直接修改图纸比拆房子重建更高效。
8. Vue 的 key
有什么作用?
- 作用:帮助 Vue 识别节点的唯一性,优化更新性能。
- 场景 :在
v-for
循环中必须使用唯一key
。 - 反例 :
没有key
时,列表顺序变化可能导致元素错误复用(如输入框内容错乱)。
9. Vue 的 nextTick
是做什么的?
-
作用:在下次 DOM 更新后执行回调,用于获取更新后的 DOM。
-
场景 :修改数据后立即操作 DOM。
javascriptthis.message = '更新了'; this.$nextTick(() => { console.log('DOM 已更新:', this.$el.textContent); });
五、性能优化
10. 如何优化 Vue 应用的性能?
- 编码优化 :
- 合理使用
v-if
和v-show
。 - 避免
v-for
和v-if
同时用在同一元素。
- 合理使用
- 加载优化 :
- 路由懒加载:
const Home = () => import('./Home.vue')
- 图片懒加载:
vue-lazyload
插件。
- 路由懒加载:
- 缓存优化 :
-
使用
keep-alive
缓存组件:html<keep-alive> <router-view></router-view> </keep-alive>
-
附:高频问题速查表
问题方向 | 高频考点 |
---|---|
响应式原理 | Object.defineProperty 、依赖收集 |
生命周期 | created vs mounted 、beforeDestroy |
组件通信 | props/$emit、Event Bus、Vuex |
指令与语法 | v-if /v-show 、v-for +key |
性能优化 | 懒加载、keep-alive 、虚拟 DOM |
进阶原理 | 虚拟 DOM 原理、nextTick 机制 |