Vue 中 computed 修改使用的属性

 我来答
舒适还明净的海鸥i
2022-06-23 · TA获得超过1.7万个赞
知道小有建树答主
回答量:380
采纳率:0%
帮助的人:70.3万
展开全部

学习 Vue 计算属性的时候有个疑问❓, 那就是在计算属性中修改使用的属性值, 会不会因为 Vue 的响应式而造成死循环

计算属性可以理解为是一个 getter 函数, 获取新值, 但是 vue 会做一层缓存, 只有改变才会重新计算

举个栗子🌰 :
假设有个属性叫 name , 现在需要一个计算属性 newName , 但是需要在取 newName 的时候再把 name 改成初始值, 由于 name 每次修改的值都不是上一次的值都会触发响应式, 理论上写一个点击方法用来修改一次 name 的值, 处理流程应该是 name --> newName --> name --> newName --> name --> newName .... 然而事实并不会如此

首先要知道流程是什么?
修改 name 的值, 会触发响应式, 那么响应式会调用 trigger 函数, trigger 函数最终会调用 newName 里的响应式副作用( ReactiveEffect )的 scheduler , 而 scheduler 可以根据 ComputedRefImpl 查到实现为 triggerRefValue(this); 也就是调用计算属性 get value 函数, 此时就是在执行 ReactiveEffect 捕捉的 getter 函数并且将该副作用设置为活跃状态的 ReactiveEffect , 也是外面写的 newName 函数, 在这里执行 newName 就会出现对 name 赋新值触发新的 trigger

可以注意的是 trigger 的 key 为正在修改的属性名称, 也就是 name , vue 使用一个 map 通过 key 为 name 来存储 ReactiveEffect 对象

回到上面, 在 newName 中触发新的 trigger , 实际上最后执行的是 triggerEffects , 在这里会对所有的副作用进行遍历, 当然在 newName 中副作用只有一个也就是通过 name 为 key 存储的 ReactiveEffect 对象, 此时它也是活跃状态的 ReactiveEffect , 根据 triggerEffects 中 effect !== activeEffect || effect.allowRecurse 这个判断, 正在执行的 effect 不等于活跃状态的 effect 或者允许递归才会调度 scheduler , 由于当前的 effect === activeEffect, 所以不会执行 newName 的 scheduler 也就不会去执行

结果: vue 内部处理的可能出现死循环的情况, 估计以前某个版本会出现死循环, 到现在 eslint 都会提示 Unexpected side effect in "newName" computed property. 错误

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式