# 两道代码题 面试题1 完成 Component 类代码的书写,要求: 1. 修改数据时能够触发 render 方法的执行 2. 同步变更时需要合并,仅触发一次 render 方法 ```js class Component { data = { name: "", }; constructor() { } render() { console.log(`render - name: ${this.data.name}`); } } const com = new Component(); // 要求以下代码需要触发 render 方法,并且同步变更需要合并 com.data.name = "张三"; com.data.name = "李四"; com.data.name = "王五"; setTimeout(() => { com.data.name = "渡一"; }, 0); ``` 面试题2 以下两段代码在 Vue 中分别渲染几次?为什么? 代码一: ```vue ``` 代码二: ```vue ``` - 代码一:2次,初始化渲染1次,之后虽然在 for 循环中修改了 5 次响应式数据,但是会被合并,因此之后只会渲染 1次。 - 代码二:6次,初始化渲染1次,之后每一个 setTimeout 中修改一次响应式数据就会渲染1次。 >参考答案: > >**代码一(同步赋值)** > >会渲染两次: > >1. 初始化渲染一次:在组件挂载时,Vue 会进行一次初始渲染,将 rCount 的初始值 0 渲染到 DOM 中。 > >2. 响应式数据更新和批处理: > - 在 for 循环中,rCount.value 被依次赋值为 1, 2, 3, 4, 5. 每次赋值时,Vue 的响应式系统会检测到数据的变化。 > - 然而,这些变化发生在同一个同步代码块内,Vue 会将这些变化推入异步更新队列中。因为这些赋值操作是同步执行的,Vue 会在当前事件循环结束时对这些变化进行批处理(batching) > - Vue 的批处理机制会将这些同步的更改**合并为一次更新**,因此,无论有多少次对 rCount.value 的赋值,最终只会在异步队列中触发一次渲染更新。 > >3. 最终渲染一次:由于 Vue 的批处理机制,这段代码最终只会触发 一次 DOM 更新,渲染出 rCount 的最终值 5. > >总计渲染次数:2 次(初始化渲染 1 次 + 批处理渲染 1 次) > >**代码二(异步赋值)** > >会渲染六次: > >1. 初始化渲染一次:同样,组件挂载时会进行一次初始渲染,将 rCount 的初始值 0 渲染到 DOM 中。 > >2. 异步更新渲染: > - 在 for 循环中,每次迭代都会创建一个 setTimeout,每个 setTimeout 会在 0 毫秒后异步执行。在每个 setTimeout 的回调中,rCount.value 被依次赋值为 1, 2, 3, 4, 5 > - 由于每次赋值都发生在一个独立的异步回调中,Vue 的响应式系统会在每个异步回调执行后,立即触发相应的更新流程。每次 setTimeout 回调都会使 rCount.value 发生变化,因此每次都需要进行一次渲染更新。 > >3. 每个异步回调导致一次渲染:因此,这段代码会触发 5 次 DOM 更新,每次将 rCount 渲染为 1 到 5. > >总计渲染次数:6 次(初始化渲染 1 次 + 5 次异步更新渲染) --- -EOF-