首页IT科技vuetorrent(谈谈 Vue toRef 和 reactive)

vuetorrent(谈谈 Vue toRef 和 reactive)

时间2025-08-04 04:34:55分类IT科技浏览5256
导读:reactive reactive 创建一个深层的对象的响应式代理,即对象根属性以及嵌套对象的属性都是响应式的。...

reactive

reactive 创建一个深层的对象的响应式代理              ,即对象根属性以及嵌套对象的属性都是响应式的              。

之所以嵌套对象也是响应式的                      ,是因为对于嵌套对象       ,将递归地转换为响应式                     。结构赋值结构了第一层的属性              ,那么第一层属性就了失去响应式                      ,但其嵌套下的对象还是响应式的        。

// 解构赋值 const { foo, bar } = { ...reactive({ foo: 1, bar: { val: 1 } }) }; <div>foo: {{ foo }}</div> <button @click="foo++">Change foo</button> <div>bar val: {{ bar.val }}</div> <button @click="bar.val++">Click bar val</button>

如上图所示       ,foo 只有在 bar.val 响应式更新之后才更新       。被解构赋值之后       ,foo 失去了响应式;bar 是嵌套对象                      ,其属性还是响应式的                     。

关于深层次和浅层次响应式的知识点请阅读:谈谈 Vue shallowRef 和 shallowReactive

toRef

toRef 是基于响应式对象上的一个属性              ,创建一个对应的 ref               。这里有非常重要的注意点       ,“响应式              ”              、“对象                     ”       。toRef 操作的是一个响应式数据                      ,且数据类型是对象              ,而不是一个普通对象,即便控制台不报错                      ,也会失去它的意义                     。

const obj = { foo: { bar: 1 } }; const state = toRef(obj, "foo"); function change() { state.value.bar++; console.log(state.value.bar, obj.foo.bar); } <div>obj: {{ obj.foo.bar }}</div> <div>foo: {{ state.bar }}</div> <button @click="change">Change foo bar</button>

如下图所示                      ,页面不发生更新:

但 state 确实是 Ref 类型:

也就是说,toRef 操作的数据不能是普通对象的属性               。

toRef 作用是什么?

延续响应式能力

下面是官方文档给出的示例              ,左看右看                     、上看下看都没看出个啥特别的。谜语人吧这是?

const state = reactive({ foo: 1, bar: 2 }) const fooRef = toRef(state, foo) // 更改该 ref 会更新源属性 fooRef.value++ console.log(state.foo) // 2 // 更改源属性也会更新该 ref state.foo++ console.log(fooRef.value) // 3

❓那么 toRef 有什么用呢?前面说到 reactive 被解构赋值之后第一层(根属性)失去了响应式                      ,而 toRef 可以让其继续保持响应式                     。

toRef 当作 ref 函数创建一个响应式数据不是响应式的       ,页面不更新              ,前面图2 中已经说明了                      。toRef 是延续响应式能力                      ,不是创建响应式数据。

对第一节中的例子进行修改:

// 在 reactive 中包裹了 toRefs const { foo, bar } = { ...toRefs(reactive({ foo: 1, bar: { val: 1 } })) };

图4 与 图1 进行对比       ,foo 确确实实是响应式的       ,页面也发生了变化              。不再因为 bar.val 更新而更新                      。

toRef 与 toRefs 的区别就是多了一个 s                      ,即批量延续 reactive 的响应式能力        。

转换 prop 为 Ref 类型

官方文档中有提到关于 prop 与 toRef 结合使用的案例              ,说非常有用              。有些函数需要的参数类型就是 Ref       ,比如 useRefHistory                      ,就需要传递 Ref 类型的数据:

组件 prop 不是一个 Ref 类型的数据:

console.log(isRef(props.foo)); // => false

因此              ,用 toRef 转换类型,与原始数据保持同步:

useRefHistory(toRef(props, "foo"));

总结

toRef 是延续响应式                      ,不是创建响应式数据                      ,不能等同于 ref 函数                     。为何是延续响应式,需要查阅源码方可知晓        。本博客只是从表现中得到的结论              ,没有从原理上进行总结                      ,属于经验之谈       。

toRef 只能基于响应式数据进行操作       ,对普通的对象进行操作得到的数据不是响应式的                     。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
js处理精度问题的方法(JavaScript:解决计算精度问题/mathjs/bignumber.js/big.js/decimal.js) 谷歌小恐龙技巧(基于STM32的小游戏——谷歌小恐龙(Chrome Dino Game))