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;适合表单、列表这种复杂结构数据。

相关推荐
mldong21 小时前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排1 天前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60611 天前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角1 天前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!1 天前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰1 天前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
mayaairi1 天前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen1 天前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马1 天前
AI源码分析:拆解模型底层实现逻辑
前端
BillKu1 天前
全局样式变量:CSS 自定义属性(--border-color)和SCSS 变量($border-color)的说明
javascript·css·scss