题目 9-题目 16
9.VUE2 的响应式原理中 Object.defineProperty 有什么缺陷
-
深度检测: Vue 2 中对于对象的处理是递归的;对于每个属性,Vue 会逐层使用 Object.defineProperty 将其转换成 getter/setter。这样,当你访问或修改嵌套较深的属性时(如 a.b.c),Vue 已经提前将 a、a.b 和 a.b.c 的属性转换为响应式,能够追踪它们的变化。
-
数组限制: Object.defineProperty 无法检测到数组索引的变化,因此 Vue 重写了数组的变异方法(如 push、pop、splice 等)来实现对数组的响应式监听。
-
对象属性添加或删除的限制: 因为 Object.defineProperty 只能在初始化的时候应用于属性,当你在一个已经创建的 Vue 实例上添加新属性时,这个新属性是非响应式的。如果你想要它是响应式的,需要使用 Vue.set()或 this.$set()方法添加新属性。
-
性能问题: 因为 Object.defineProperty 是递归地对对象的每一个属性进行处理,所以在处理具有大量属性或深层嵌套对象时,可能会有较大的性能开销。
10.vue 文件中,在 v-for 时给每项元素绑定事件需要用事件代理吗,为什么?
在 Vue 文件中,v-for 遍历数组时,为每项元素绑定事件通常不需要事件代理,但使用事件代理有其优势。这里是两种方式的对比:
测试代码
<div v-for="item in items" :key="item.id">
<button @click="handleClick(item)">Click me</button>
</div>
优点:
- 简洁:直接在每个元素上绑定事件,代码易于理解。
- 独立处理:每个元素的事件处理函数可以独立定义和处理。
缺点:
- 性能问题:如果列表非常大(如上万项),每个元素上都会绑定事件,可能导致性能开销和内存占用增加。
事件代理
测试代码
<div @click="handleParentClick">
<div v-for="item in items" :key="item.id">
<button :data-id="item.id">Click me</button>
</div>
</div>
优点:
- 性能优化:只在一个父元素上绑定事件,减少了绑定的事件处理函数数量,适用于大型列表。
- 内存使用:降低内存消耗,因为不需要为每个元素分配一个事件处理函数。
缺点:
- 代码复杂度:处理事件逻辑变得复杂,需要通过事件目标属性(如 data-id)来判断和处理具体的元素。