Vue响应式内部机制:selected变更时v-for为何重新渲染?
为什么Vue能在
selected变更时重新渲染v-for列表? 嘿,这个问题问到Vue响应式系统的核心点上了!咱们一步步拆解,你就能明白背后的逻辑:
首先得明确一个前提:selected必须是Vue实例的响应式属性——比如在Vue 2里你把它放在data选项里,Vue 3里用ref或reactive定义它。如果它不是响应式的,那Vue确实不会管它的变化。
接下来看具体的执行流程:
- 首次渲染时的依赖收集:当组件第一次渲染,
v-for遍历todos生成每个<li>的时候,会调用isSelected(todo.text)来计算class。这时候在isSelected方法内部,你肯定访问了this.selected(或者Vue 3里的selected.value)对吧?这个访问动作会被Vue的响应式拦截器(Vue 2里是Object.defineProperty,Vue 3里是Proxy)捕获到。 - 关联属性与渲染Watcher:Vue的每个响应式属性都对应一个依赖收集器(Dep),当属性被访问时,当前负责组件渲染的「渲染Watcher」会被自动添加到这个Dep的依赖列表里。简单说就是,Vue记下来了:“哦,这个组件的渲染依赖了
selected这个属性”。 - 属性变更时的更新触发:当
selected的值发生变化时,响应式属性的setter会被触发,它会通知Dep里所有的依赖(也就是那个渲染Watcher):“我变了!快更新!”。 - 重新渲染与DOM diff:渲染Watcher收到通知后,会重新执行组件的渲染函数。这时候
v-for会重新计算每个<li>的class(因为isSelected会再次执行,用新的selected值),Vue会通过虚拟DOM的diff算法对比新旧渲染结果,只更新那些class发生变化的<li>,而不是整个列表重新渲染。
你提到的todos变更时的重新渲染,其实是同一个逻辑:todos作为响应式数组,它的变更会触发自己的Dep通知渲染Watcher,进而重新执行渲染函数。而selected的特殊之处在于,它不是直接出现在模板的v-for表达式里,而是通过一个方法间接被访问,但Vue的依赖收集机制能穿透方法调用,捕获到对响应式属性的访问——这可不是什么“反射”,而是响应式系统在属性访问阶段就完成的依赖追踪。
内容的提问来源于stack exchange,提问作者shineability
相关产品推荐
相关产品推荐

