Vue3中普通对象为何自动变为响应式?测试现象存疑
问题:Vue3中普通对象/变量修改为何能触发视图更新?
有文章提到普通对象不具备响应式特性,但实际测试发现,普通字符串变量和普通对象的属性修改后,视图居然能自动更新。测试代码如下:
<template> {{ personName }} <!-- 会变成Amy,为什么? --> {{ person.name }} <!-- 会变成Amy,为什么? --> {{ personRef.name }} {{ personReactive.name }} <button @click="changeName('Amy')">changeName</button> </template> <script setup> import { ref, reactive } from "vue"; let personName = "John"; const person = { name: "John" }; const personRef = ref({ name: "John" }); const personReactive = reactive({ name: "John" }); const changeName = (name) => { personName = name; person.name = name; personRef.value.name = name; personReactive.name = name; }; </script>
在测试环境中运行后,点击按钮所有值都变成了Amy,这是为什么?是不是遗漏了Vue文档中的某些内容?
解答
这不是普通对象/变量具备了响应式特性,而是组件重渲染带来的被动更新:
真正的响应式触发重渲染:
personRef和personReactive是通过Vue官方响应式API(ref/reactive)创建的响应式数据,修改它们的属性时,Vue会自动检测到变化并触发组件的重渲染流程。普通数据的被动更新:
- 普通变量
personName和普通对象person本身不具备响应式能力,修改它们的操作不会主动通知Vue更新视图。 - 但当
personRef/personReactive的修改触发组件重渲染时,模板会重新执行一次,此时会读取personName和person.name的最新值,所以看起来像是它们的修改也更新了视图。
- 普通变量
验证方法:
如果修改changeName函数,只操作普通数据、不触碰响应式数据:const changeName = (name) => { personName = name; person.name = name; // 注释掉响应式数据的修改 // personRef.value.name = name; // personReactive.name = name; };此时点击按钮,视图不会有任何变化——因为没有触发组件重渲染,模板不会重新读取普通数据的最新值。
内容的提问来源于stack exchange,提问作者PaintyJoy
相关产品推荐
相关产品推荐

