# 两道代码题
面试题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
{{rCount}}
```
代码二:
```vue
{{rCount}}
```
- 代码一: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-