Vue3 小白的疑惑:为什么用 const 定义的变量还能改?

明明用const定义了响应式变量(比如const name = ref("小明")),为什么还能通过name.value = "小红"修改它的值?

刚学 Vue3 的小伙伴,大概率会遇到这个 "反常识" 的困惑:

明明用const定义了响应式变量(比如const name = ref("小明")),为什么还能通过name.value = "小红"修改它的值?

要知道在普通 JavaScript 里,const声明的变量可是 "一旦赋值就不能改" 的啊!今天咱们用 5 分钟把这个问题讲透,从此对 Vue3 的响应式不再迷茫。

先搞懂:普通 JS 里的 const 和 let 到底差在哪?

在聊 Vue3 之前,得先回顾下基础 ------ 很多人其实没真正搞懂const的 "不能改" 到底指什么。

比如这段普通 JS 代码:

javascript 复制代码
// 用let声明的变量:可以重新赋值
let userName1 = "小明";
userName1 = "小红"; // 合法,没问题
// 用const声明的变量:不能重新赋值
const userName2 = "小明";
userName2 = "小红"; // 报错!Assignment to constant variable

这里的关键是:const限制的是 "变量的引用",而不是 "变量的值"

如果const声明的是 "引用类型"(比如对象、数组),情况就不一样了:

javascript 复制代码
// const声明对象:变量本身的引用不能改,但对象内部的属性可以改
const user = { name: "小明" };
user.name = "小红"; // 合法!不会报错
user.age = 18;      // 也合法!
// 但不能给user重新赋一个新对象
user = { name: "小刚" }; // 报错!因为改变了变量的引用

对于有 C 语言基础的同学来说,这和指针的逻辑很像:const 修饰的变量就像 const 指针(如 char* const p),指针变量 p 本身存储的内存地址不能改(对应 JS 里变量的引用不能变),但指针指向的内存空间里的数据可以改(对应 JS 里引用类型内部的属性能改)。一句话总结:const就像给变量上了 "锁",但只锁 "变量指向谁",不锁 "指向的内容里有什么"

回到 Vue3:ref 到底做了什么?

理解了普通 JS 的规则,再看 Vue3 的ref就简单了。

当我们写const name = ref("小明")时,Vue3 到底干了什么?

其实ref("小明")会帮我们创建一个 "响应式容器对象" ,你可以把它想象成一个 "装着值的小盒子",结构大概是这样的:

javascript 复制代码
// ref("小明")的本质:返回一个包含value属性的对象
const name = {
  value: "小明" // 我们要修改的,其实是这个盒子里的value
};

所以:

  1. 我们用const声明name,是为了锁定 name 这个 "盒子" 本身------ 不让它被换成其他 "盒子"(比如不能再写name = ref("小刚"));
  1. 而name.value = "小红"修改的是盒子里的内容,并没有改变name指向的 "盒子",这完全符合const的规则。

用一张图更直观:

伪代码 复制代码
const name = ref("小明") → name → [响应式盒子: { value: "小明" }]
name.value = "小红" → name还是指向同一个盒子 → [响应式盒子: { value: "小红" }]
name = ref("小刚") → 试图让name指向新盒子 → 报错!(const不允许)

再延伸:reactive 也是同样的道理吗?

对!reactive虽然不用写.value,但本质和ref一样,都是 "修改对象内部属性"。

比如:

vue 复制代码
const user = reactive({ name: "小明" });
user.name = "小红"; // 合法!修改的是对象内部属性
user = reactive({ name: "小刚" }); // 报错!试图改变user的引用

甚至可以这么理解:ref其实是对reactive的 "封装",帮我们把基本类型(数字、字符串)变成了 "可以被跟踪的对象"。

最后总结:Vue3 里该怎么用 const 和 let?

记住一个核心原则:只要是响应式变量,就用 const;只有非响应式变量需要重新赋值时,才用 let

具体场景:

变量类型 推荐声明方式 原因
ref 创建的变量 const 只改.value,不改变量引用
reactive 创建的变量 const 只改对象内部属性,不改变量引用
非响应式且需要重新赋值的变量 let 比如普通名字切换let tempName = "小明"; tempName = "小红"
函数(方法、钩子) const 函数不需要重新赋值,用 const 更安全

比如正确的写法:

vue 复制代码
<script setup>
// 响应式变量:用const
const name = ref("小明");
const user = reactive({ name: "小明" });
// 方法:用const
const handleRename = () => {
  name.value = "小红"; // 改内部属性,合法
  user.name = "小红"; // 改内部属性,合法
};
// 非响应式且需要改的变量:用let
let tempName = "小明";
const handleTempRename = () => {
  tempName = "小红"; // 需要重新赋值,用let
};
</script>

看到这里,你应该彻底明白为什么 Vue3 里到处都是const了吧?其实不是const"失效" 了,而是我们利用了 "对象引用不变,内部属性可改" 的特性,配合 Vue3 的响应式系统实现了数据更新。

下次再遇到这个疑问,就想想那个 "装值的小盒子"------ 你改的是盒子里的名字,不是盒子本身,所以const当然不会拦着你啦!

相关推荐
铁皮饭盒10 小时前
Next.js 风格路由内置?Bun FileSystemRouter 凭啥这么香
javascript
乘风gg10 小时前
多 Agent 不是万能的!搞懂这 5 个原则,少走 1 年弯路!
前端·agent·ai编程
猩猩程序员11 小时前
Vercel 推出 Agent 框架 Eve:让 AI Agent 像写 Web 应用一样简单
前端
小林ixn11 小时前
别再背八股了!从 5 个真实场景彻底搞懂 JavaScript 的 this
javascript
爱读源码的大都督11 小时前
Claude Code源码分析(三):为什么系统提示词中需要有tools呢?
前端·人工智能·后端
爱勇宝11 小时前
Claude Code 被曝暗藏“隐形检测”代码:封代理不是最可怕的,可怕的是你根本不知道它在干什么
前端·后端·程序员
小牛不牛的程序员12 小时前
我用 Claude Code 半天撸完了一个完整网站,AI 编程到底提升了多少效率?
前端
东风破_12 小时前
JavaScript 面试常考的字符串算法:从反转字符串到回文判断
前端·javascript
巴勒个啦12 小时前
D3.js 入门实战:用力导向图可视化项目依赖关系
javascript
ITOM运维行者12 小时前
从零搭建企业级服务器监控体系:踩坑实录与架构设计
前端·后端