Vue中的ref和reactive到底在干嘛

ref

1. 先搞懂一个核心问题:Vue 怎么知道你改了数据,然后刷新页面?

Vue 需要盯着你的变量,一变就自动更新网页上显示的内容。

普通变量 Vue 盯不住:

ts 复制代码
let num = 1
num = 2

Vue:完全没感知,页面数字不会变。

2. ref 干的唯一一件事:给变量套一层「监控外壳」

ref(里面的值) 会生成一个外壳对象,Vue 专门盯着这个外壳。

ts 复制代码
import { ref } from 'vue'
const num = ref(1)

底层真实结构可以理解成这样:

js 复制代码
num = {
  // 真正存数字的地方
  value: 1,
  // Vue偷偷藏了监听代码
}
  • 外壳 num Vue能看见、能监控;
  • 真正的数据藏在 .value 里面。

改数据的时候,必须改 .value

ts 复制代码
num.value = 2

Vue 检测到你修改了外壳里的 value,立刻刷新页面。

如果你写成 num = 2,直接把整个监控外壳扔掉了,Vue 失去监控,页面不动。

3. 模板里为什么不用 .value?

模板是 Vue 单独处理的语法,它会自动帮你读取 .value。

vue 复制代码
<!-- 不用写 num.value -->
<div>{{ num }}</div>

4. 最简可运行对比,一眼看出差别

例子1:不用 ref(页面不更新)

js 复制代码
<script setup>
let count = 0
function add() {
  count++
  console.log(count) // 控制台数字变了,页面不动
}
</script>

<template>
  <p>数字:{{ count }}</p>
  <button @click="add">点我+1</button>
</template>

例子2:用 ref(页面同步更新)

js 复制代码
<script setup>
import { ref } from 'vue'
// 套监控外壳
const count = ref(0)
function add() {
  // 修改外壳内部的值
  count.value++
}
</script>

<template>
  <p>数字:{{ count }}</p>
  <button @click="add">点我+1</button>
</template>

5. ref 第二个用途:获取页面DOM标签

你想操作页面上的输入框、按钮,JS原生拿DOM很麻烦,用ref绑定:

js 复制代码
<script setup>
import { ref, onMounted } from 'vue'
// 空的监控外壳,专门存input元素
const inputDom = ref(null)

// 页面渲染完后
onMounted(() => {
  // inputDom.value 就是页面里的input标签
  inputDom.value.focus() // 自动光标聚焦输入框
})
</script>

<template>
  <!-- ref名字和变量对应 -->
  <input ref="inputDom" placeholder="搜索" />
</template>

Vue 把 ref 做成了模板特殊指令,自动帮你完成「查找 DOM、存入变量」这一步,不用手写 querySelector,这是框架封装出来的语法。

补充对比:

js 复制代码
<input id="searchInput" placeholder="搜索">

<script>
// 原生必须手动根据id获取DOM
const input = document.getElementById('searchInput')
// 页面加载完才能操作
window.onload = function() {
  input.focus()
}
</script>

Vue 简化后,不用写选择器,靠同名 ref 自动绑定,是框架提供的便利语法。

6. 一句话终极总结

ref = 给数字/字符串/布尔/DOM标签包一层 Vue 能监控的外壳;

代码里改值要 .value,模板里直接写变量名。

reactive

1. reactive 和 ref 是亲兄弟,作用一样:让数据变响应式,改了页面自动更新

区别只在于装的数据类型不一样:

  • ref:装单个简单值(数字、字符串、布尔、DOM),要用 .value
  • reactive:专门装 对象、数组 ,不用写 .value

2. 先看对比,一眼看懂

场景1:表单对象,用 reactive

ts 复制代码
import { reactive } from 'vue'

// 把整个表单变成响应式
const form = reactive({
  filename: '',
  status: '',
  id: 0
})

// 直接点属性修改,不用 .value
form.filename = '测试文档.pdf'
form.status = 'success'

场景2:如果硬用 ref 写对象(麻烦)

ts 复制代码
const form = ref({
  filename: ''
})
// 修改必须两层 .value,很啰嗦
form.value.filename = 'xxx'

3. reactive 底层原理

ref 是套一层 { value: xxx }

reactive 直接把整个对象本身变成可监听代理 ,不用包一层盒子,所以不用 .value。

4. 数组也用 reactive

ts 复制代码
const docList = reactive<DocumentRead[]>([])
// 直接push、修改数组,页面自动刷新
docList.push({ id: 1, filename: 'a.pdf', status: '' })

5. 核心优缺点

优点

修改属性简洁,不用每次打 .value,表单、列表首选。

大坑(重点)

不能直接替换整个对象!会丢失响应式

ts 复制代码
const form = reactive({ name: '' })

// ❌ 错误,直接覆盖整个对象,Vue 失去监听
form = { name: '新名字' }

// ✅ 正确,只改里面属性
form.name = '新名字'

ref 就没这个问题:

ts 复制代码
const form = ref({ name: '' })
// 可以直接替换 .value
form.value = { name: '新名字' }

6. ref 和 reactive 选择口诀

  1. 单个数字/字符串/布尔 / DOM引用 → ref
  2. 表单、JSON对象、列表数组 → reactive

7. 配套工具 toRefs(高频搭配 reactive)

如果你想把 reactive 对象拆分成单独变量,不丢失响应式:

ts 复制代码
import { reactive, toRefs } from 'vue'

const form = reactive({ name: '', id: 1 })
// 解构出独立ref变量
const { name, id } = toRefs(form)

// 此时 name、id 是 ref,修改需要 .value
name.value = '张三'

一句话总结

reactive 是 Vue 提供的API,专门把对象、数组转为响应式,直接 .属性 修改,不用写 .value;适合表单、列表这种复杂结构数据。

相关推荐
一 乐9 小时前
动漫书销售商城|基于springboot + vue动漫书销售商城(源码+数据库+文档)
java·数据库·vue.js·spring boot·毕业设计
admin and root9 小时前
「AI安全篇」实战AntiDebug自动化JS逆向加解密MCP
javascript·人工智能·网络安全·自动化·漏洞挖掘·cnvd·src赏金
前端snow10 小时前
ai agent --- postgreSQL 关系型数据库
前端
卷无止境11 小时前
ECharts:把数据变成故事的可视化利器
前端
Eric_见嘉11 小时前
在职前端 Skill 和 MCP 分享
前端·后端·agent
liangshanbo121511 小时前
面试题:如何优化 Webpack 的打包速度?
前端·webpack·node.js
wengad11 小时前
从 wangEditor 迁到 wangEditor-next
前端·javascript·vue.js
行者-全栈开发12 小时前
【前端/JS框架】CVE-2026-3854:GitHub Enterprise Server X-Stat注入XSS漏洞深度剖析与紧急修复指南
前端·javascript·github
计算机魔术师13 小时前
AMD砸82亿买下李飞飞,这次不卖芯片卖什么?
前端
hzxpaipai14 小时前
杭州企业官网怎么建设?从策划到上线的5步建站方法
运维·服务器·前端·网络