下面链接中用reactive和ref分别创建了两个变量,都接收数字1作为参数,绑定到界面上时,虽然控制台有warning “value cannot be made reactive: 1”,但是界面上的两个数字确实都会随着定时器的调用而响应式变化:https://sfc.vuejs.org/#eNp9kD...
而且当我去掉用ref定义的变量时,reactive就不会响应式了,这又是为啥呢?
下面链接中用reactive和ref分别创建了两个变量,都接收数字1作为参数,绑定到界面上时,虽然控制台有warning “value cannot be made reactive: 1”,但是界面上的两个数字确实都会随着定时器的调用而响应式变化:https://sfc.vuejs.org/#eNp9kD...
而且当我去掉用ref定义的变量时,reactive就不会响应式了,这又是为啥呢?
Vue SFC Playground 这个行为太奇怪了,reactive 基本类型照道理确实不该跟着响应,我在本地项目里测试楼主的代码也没有复现这个行为。
我在 Playground 里把 script setup
语法糖写法改成了以前的 export default setup
写法,发现编译出来的代码有些不一样,export default setup
的行为是正常的,不会跟着响应。
虽然结论确实如 @木木剑光 所说,蹭着 msgRef 更新了,但改个写法最终行为就不一致,这种现象本身还是显得太诡异了。
根据这个 issue https://github.com/vuejs/core... 的讨论说法,不同编译环境/运行时版本最终生成的代码,行为就是会不一样,有说是为了 DevTools 处理的。
同样是 DEV
模式,Playground 里 script setup
编译出来的 setup return 值里多加了 get/set 处理。
script setup
写法(reactive 也会跟着更新)
export default setup
写法(reactive 不会跟着更新)
27 回答13k 阅读
6 回答2.3k 阅读✓ 已解决
8 回答3.5k 阅读✓ 已解决
6 回答1.3k 阅读✓ 已解决
5 回答5.3k 阅读✓ 已解决
3 回答3.5k 阅读✓ 已解决
4 回答1.6k 阅读✓ 已解决
其实这个 Demo 中 reactive 的变量并不是响应式的, 看下 vue/reactivity 的源码就知道了,reactive 只能代理对象
至于为什么加上 msgRef 创建的变量就两个都会更新,原因是此处 msgRef 是一个响应式的对象,vue3 的依赖收集其实是以组件为单位的,所以这里其实 render 都会被收集为 msgRef 的依赖
当 msgRef 更新后,触发更新依赖,render 会重新跑一遍,基于diff算法来看那些部分需要更新,此时 msgReactive 只是恰好也更新了而已,相当于蹭着 msgRef 上了一趟车