vue3 reactive() 的局限性:对解构操作不友好,ref似乎也有这个问题?-灵析社区

爱打瞌睡的三角龙

[https://cn.vuejs.org/guide/essentials/reactivity-fundamentals...](https://link.segmentfault.com/?enc=e%2FuncrWeAl7tU%2FmwWwPqpg%3D%3D.7Qae9c%2BSkAYB6gEPlsM6nYV%2F6Q2Oiu6V%2BPeDlhcTTmwB0DyBICxddOG9zm5BqLYU4Bq19fwEz7rD3MoTySG60JQr8HJQ7ZCZbovoNJbRZJXjgzmnXIwrn7LthTi157YM) [https://play.vuejs.org/#eNp9UcFuwjAM/ZUoF4qoShE3VJC2iQM7bNO2Y...](https://link.segmentfault.com/?enc=5%2Fu%2Ff62ruoKywQXF1yBX%2FA%3D%3D.Hp%2BiD3d4dy%2FvLQFsEjJkJltwEyBVlp6nC24d9zkWWsdcavuBNK%2BvwMuJ1%2B342yY%2BxoQdvUBktqGeV7lqfaeHXkZqntIPYkhqLOyXxEvBOh9pfuyFGfuiOMVRUQI7DiTeOBoMNaeKtCxist4QEuJ2IxcaIjBDzZe9t21g3bT3i5Zsx9QEZE6KSKRjRh8LwHCgvnlvbOf%2FOFYSJ4QhJ5MChWu%2F3JvHAmKiQOQWFZFVs83HwApPm1jEbV%2B%2BzAwx1n%2F4JrF1Hs4PrNLbC9RHAmz7BZvS%2Bwj4PURXybh4CDFEe2moiCMMyuAZVIh4QsDQ2UJ%2FyAVyVLAzy2EV3InRAQBVmmiA6MlWVg1CkeGzbUJtvYLL%2FRnCQ9ABuc4C%2FhfiS6Jzv9HsbM9mO1k25L0iuSdWDpnz7XEbvKZvUM5mdn250a4ahWDk6USzUNVZxWIA5foMTu3o0kOir44GMqH%2B1EDAacKrYy%2Ftp5G2a50aHsPc9MvaBTwkm2ujPg7ftngBBMyA2O2d3acqS%2Fjvk3UA9LrcJsAUilXGbzloevmyekLKDKWXqC%2B8QfJmehKyzbJeguK1jFlJ8JfuQePq4t%2BXa%2BnlUIFwJrHfMLEFn9tPm6Wgq8tR0w4HASpuZ5IpmgwyFUV%2B) 如代码所示,解构丢失响应性连接似乎并不只是reactive的“局限性”

阅读量:16

点赞量:0

问AI
因为截至目前, JS 无法监听变量的赋值行为 ,不管是 "Object.defineProperties" 还是 "Proxy",其实都是拦截对象的属性变化 ,而不是监听变量的赋值 。 const a = 0; let b = 1; var c = 2; «👆这里的 "a"、"b"、"c" 都是“变量”,对它们的赋值,是无法监听的。» let obj = { a: 0, b: 1 } let { a } = obj; «👆这里的 "obj.a"、"obj.b" 都是“对象的属性”,对这些属性的赋值行为可以通过 "Proxy" 或者 "Object.defineProperties" 拦截到。 但是对**"obj"本身**重新赋值的行为,是无法被监听的,同理,对从 "obj" 中解构出来并重新命名为"a"的变量的赋值,也无法被监听。» 其实也正是因为变量赋值无法被监听,Vue3 才搞出 "ref" 这个东西来,把基础类型包装进一个对象里,就可以对这个对象的属性".value"进行监听了。 不过 JS 不能监听,不代表无法实现这样的语义,有一个比较年轻的 Svelte 框架,通过预编译,对用户屏蔽类似的包装过程,所以如果是使用 Svelte 的话,延时器回调中对变量赋值,可以直接反映到视图上: let x = 0; const interval = setInterval(() => { x++; x >= 100 && clearInterval(interval); }, 1e3); Hello world!{x} 但是 Vue 目前不允许这样写。 其实 "Vue 有过一个提案" (https://link.segmentfault.com/?enc=QVbOwfyH994pqUGHmMsMWA%3D%3D.lCHziyJ%2FN0R3bXRehISrxaoeKe8MZ5%2FuCgzPogWmHLAh9hGDsbhuw3AUtGDNbtfTrJ%2FO9e5BQc9jXv%2Bu8ogwNg%3D%3D),用 JS 的 label 语句来代替 "ref" 函数: ref:count = 0; count++ 但是由于这个提案给 label 语句带来了歧义,在 Vue 社区和开发者群体中引起了强烈的反对,因此只得作罢,所以时至今日, Vue 的响应式还是以监听对象属性的方式来完成,对解构而来的变量重新赋值不会被监听。