当前位置: 首页 > 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.zskr.cn/news/1909.html

相关文章:

  • Linux操作系统相关问题汇总
  • 鲜花 9.10
  • ECT-OS-JiuHuaShan框架的真正意义是打破还原论和人类中心论,公理是客观存在与数学逻辑,不依赖于人类理解与否。
  • 【rdma】RoCE、IB和TCP等网络的基本知识及差异对比
  • 5%付费率背后,鸿蒙成独立开发者的“商业理想国”
  • 【IoTDB 线上小课 19】开源时序数据库 Apache IoTDB,四大优势解决企业选型难题!
  • 个人开发者从0到1(BeeCount:一款开源的跨平台个人记账应用)
  • java课前问题
  • 碳硫仪推荐品牌,是谁赢得用户口碑?
  • vue路由
  • 查看mysql具体使用那个glibc的版本的mysql
  • 【A】月半猫想吃麦当劳(待完坑)
  • 【A】宝宝肚肚打雷了(待完坑)
  • 【A】我头上有鸡脚 鸡脚(待完坑)
  • 登录认证-上篇:基于 Session 的传统身份验证
  • vLLM框架本地布署Qwen3-32B模型 - yi
  • 项目管理软件中有哪些不同的模块以及如何导出其报告?
  • Kubernetes命名空间(Namespace)
  • Microsoft 推出 .NET 10 RC 1
  • 高等代数 I
  • kotlin中的netty
  • flutter右滑返回直接返回到native问题
  • 如何用变量与函数实现随机生成数字交互?附完整教程
  • Linux系统简单源码安装NGINX版本1.28.0
  • 【项目实战】基于i.MX8M Plus的人工智能小车(AGV导航、视觉避障、自动跟随、颜色识别、防跌落)有教程代码
  • unity TimeLine SignalTrack
  • 根据端口找到进程id
  • 双因子验证网站(aspsms.com/en/registration/)无法注册——Capcha Error
  • mysql导入数据库,从基础命令到高效技巧
  • 基于“北斗+卫星互联网”的低空飞行服务保障基础设施