当前位置: 首页 > news >正文

vue(穿透闭包/利用闭包)的几种方式

闭包

let count = 0setInterval(() => {console.log(count) // ❌ 总是拿到旧值(如果 count 被闭包锁死)
}, 1000)

✅ 解决思路

核心思想就是:不要让闭包“锁死”旧的变量引用,而是通过全局/引用对象来拿“实时的”值。

方案 1:用 let 定义在外部作用域(非响应式场景:非监听值)

let count = 0setInterval(() => {console.log(count) // ✅ 每次取到最新的 count
}, 1000)setTimeout(() => {count = 5 // 改变外部变量
}, 3000)

⚠️ 注意:这里不能用 const,因为 const 不能重新赋值。

 

方案 2:用对象/引用来“共享”值

const state = { value: 0 }setInterval(() => {console.log(state.value) // ✅ 永远是最新值
}, 1000)setTimeout(() => {state.value = 10
}, 3000)

 

方案 3(在 Vue 中):用 refreactive

<script setup>
import { ref, onMounted } from 'vue'const count = ref(0)onMounted(() => {setInterval(() => {console.log(count.value) // ✅ 每次都是最新的值}, 1000)
})// 修改值
setTimeout(() => {count.value = 99
}, 3000)
</script>

 

 

方案 4:用 globalThis 挂全局变量(非响应)

globalThis.count = 0setInterval(() => {console.log(globalThis.count) // ✅ 始终最新
}, 1000)setTimeout(() => {globalThis.count = 20
}, 3000)

总结

  • 闭包 stale value 问题 = 回调函数拿到的是“当时定义的旧变量”

  • 想要在闭包里始终取到“最新值”,必须:

    1. let/ref/reactive/对象引用

    2. 或挂到 globalThis(非响应式)

 

闭包

闭包其实就是一种“记住外部变量”的机制
如果你 想利用闭包,核心就在于:把你要“保留下来的变量”定义在 外层函数作用域,让内层函数引用它。

📌 闭包的经典定义

闭包就是 函数 + 它能访问的外部作用域

 

1. 会在闭包中读到旧值的情况

这些情况容易产生“stale value”(旧值):

ref 本身的值(解包后的 .value

const count = ref(0)setTimeout(() => {console.log(count.value) 
}, 1000)count.value = 5

如果闭包里“直接拿 count.value 的结果”,而不是引用 count,就会卡住旧值。

例子(错误写法):

const old = count.value  // ❌ 捕获的是快照
setTimeout(() => {console.log(old) // 永远是最初的值
}, 1000)

 

props(传入时解构过的)

<script setup>
const props = defineProps({ title: String })
const { title } = props  // ❌ 这里解构会丢响应式
setTimeout(() => {console.log(title)  // 永远是最初传入的 title
}, 2000)
</script>

 

响应式对象解构出来的字段

const state = reactive({ count: 0 })
const { count } = state // ❌ 这时候 count 已经是普通变量setInterval(() => {console.log(count) // 永远是初始化值
}, 1000)

 

!!!!!!!!!!!不会读旧值的情况:

这些写法闭包里永远能拿到最新的值:

ref / reactive 本身(不要解构或展开)

setInterval(() => {console.log(count.value) // ✅ 始终是最新值
}, 1000)

toRefs 解构(保持响应式引用)

const state = reactive({ count: 0 })
const { count } = toRefs(state)  // ✅ 保持响应式setInterval(() => {console.log(count.value)  // ✅ 最新值
}, 1000)

直接 watch 监听

watch(() => props.title, (val) => {console.log('最新 title:', val)
})

. 总结一句话

在 Vue 中:

  • 捕获“值” → 容易 stale(旧值)

  • 捕获“ref/响应式引用” → 始终最新

http://www.wxhsa.cn/company.asp?id=510

相关文章:

  • 记录.Net中使用WMI的一些坑,触摸失效和发布增加 PublishTrimmed裁剪异常
  • 多态--成员变量、成员函数、静态函数
  • Linux操作系统相关问题汇总
  • Java学习
  • 鲜花 9.10
  • 【工具】配置笔记本电脑安装centos7关闭盖子不休眠
  • 括号匹配
  • ECT-OS-JiuHuaShan框架的真正意义是打破还原论和人类中心论,公理是客观存在与数学逻辑,不依赖于人类理解与否。
  • z-index的使用方案
  • 再见 PS!豆包 Seedream 4.0 发布,图片生成、合成、编辑、美颜…,一句话搞定!!
  • 鲜花 9.10 - Gon
  • Iframe 全屏嵌入实验
  • 全面获取TSC频率:提升性能分析与基准测试精度
  • 【rdma】RoCE、IB和TCP等网络的基本知识及差异对比
  • WindTerm_2.7.0
  • VMWare Esxi防火墙添加白名单访问及ip异常无法登录解决办法
  • 鸿蒙,下一个iPhone时刻?
  • dw
  • 5%付费率背后,鸿蒙成独立开发者的“商业理想国”
  • HarmonyOS编写教师节贺卡
  • 3天赚2万!开发者的梦想也可以掷地有声!
  • 【IoTDB 线上小课 19】开源时序数据库 Apache IoTDB,四大优势解决企业选型难题!
  • java课前问题思考
  • nano快捷键指南
  • 个人开发者从0到1(BeeCount:一款开源的跨平台个人记账应用)
  • 网络通信中的死锁
  • 学生开发者经验|豆包大模型 + TRAE,让 AI 应用快速落地
  • java课前问题
  • CSP-S模拟19
  • union类型