Vue3基础知识-setup()、ref()和reactive()

一、完整代码

1. 组件文件(App.vue)

html 复制代码
<template>
  <!--Vue3组件可以没有跟标签-->
  <!--直接写school。模板解析ref对象自动调用.value-->
  <h1>{{school}}</h1>
  <h1>{{student.name}}</h1>
  <h1>{{student.age}}</h1>
  <button @click="changeInfo">修改信息</button>
  <hr>
  <h1>{{school2}}</h1>
  <h1>{{student2.name}}</h1>
  <h1>{{student2.age}}</h1>
  <button @click="changeInfo2">修改信息</button>
</template>

<script>

import {reactive, ref} from "vue";

export default {
  name: 'App',
  created() {
    console.log(this)
  },
  /*
  setup():
    作用:为组件准备所需资源(数据、方法、依赖等),替代了Vue2中data、methods、computed 等分散的选项
    执行时机:beforeCreate生命周期钩子之前执行,其内部的this是undefined(不能通过this访问组件实例)
  注:setup()不能是async函数。因为返回值再是return对象,而是promise,模板看不到return对象中的属性
  */
  setup(){
    //知识点1:ref()。加工生成ref引用对象
    //ref传入基础数据类型:ref对象的原型有value属性(值为传入值)及其响应式set和get
    let school = ref("北京大学")

    //ref传入对象数据类型:ref对象的原型有value属性(值为传入值)及其响应式set和get
    //传入的对象也需实现响应式,继续加工生成Proxy对象(reactive函数实现)而非ref对象
    //即:student.value拿到的是Proxy对象
    let student = ref({
      name:"张三",
      age:18
    })
    function changeInfo(){
      //注1:无需this.school.value。
      //注2:写法 school = "清华大学" 表示school值为string类型的,不触发响应式
      school.value = "清华大学"

      //注:写法不是:student.value.name.value = "李四"。
      student.value.name = "李四"
      student.value.age = 19
    }
    //知识点2:reactive()。加工生成Proxy对象(可监听属性增删改查);即解决了Vue2直接增删属性和数组下标响应式问题(参考ch01-10)
    //需传入对象类型数据,基本数据类型不会实现响应式
    let school2 = reactive("北京大学")//无响应式
    let student2 = reactive({
      name:"张三",
      age:18
    })
    function changeInfo2(){
      school2 = "清华大学"
      student2.name = "李四"
      student2.age = 19
    }
    //返回的对象可在模板中使用
    return{
      school,
      student,
      changeInfo,
      school2,
      student2,
      changeInfo2,
    }
  }
}
</script>

<style>

</style>

2. 入口文件(main.js)

javascript 复制代码
//引入不是Vue的构造函数,是一个名为createApp的工厂函数
import { createApp } from 'vue'
import App from './App.vue'
//创建实例对象app,比vm更轻量级
createApp(App).mount('#app')

二、核心知识点解析

1. ref:处理响应式的「万能工具」

ref 的设计初衷是处理所有数据类型的响应式,无论是基础类型还是对象类型,核心是生成一个ref包装对象。

1.1 工作原理
  • 传入基础类型(如 school = ref("北京大学")):

    生成的ref原型结构为 { value: "北京大学", get value(), set value() },通过 valuegetter/setter 触发响应式(追踪依赖、更新视图)。

  • 传入对象类型(如 student = ref({ name: "张三" })):

    生成的ref 内部会自动调用 reactive,将对象转成 Proxy,此时 student.value 拿到的是 Proxy 对象,确保嵌套属性(如 nameage)也能响应式。

1.2 注意事项
  • ref对象使用 .value时机

    模板会自动对 ref 数据「解包」(直接写 {``{ school }} 即可),但在 setup 函数内部,必须通过 school.value 访问 / 修改,否则无法触发响应式。

  • 响应式的错误写法

    若写 school = "清华大学"(而非 school.value = "清华大学"),会导致 school 从「ref 包装对象」变成「普通字符串」,不是响应式(模板不会更新)。

2. reactive:处理对象的「专属工具」

reactive专门为对象类型设计的响应式 API ,核心是生成 Proxy 对象,可以监听对象属性的增删改查(解决了 Vue2 中「对象增删属性无响应」「数组通过下标修改内容无响应」的问题)。

2.1 工作原理
  • 传入对象后,reactive 会返回一个 Proxy 代理对象,所有对对象属性的操作(如 student2.name = "李四")都会被 Proxy 拦截,从而触发响应式。

  • 不支持基础类型

    若传入基础类型(如 reactive("北京大学")),Vue 会给出警告,且数据无响应式(因为 Proxy 无法代理基础类型)。

2.2 注意事项
  • 无需 .value

    reactive 生成的是 Proxy 对象,直接修改属性即可(如 student2.age = 19),无需像 ref 那样加 .value

  • 避免「响应式丢失」

    不要将 reactive 对象解构赋值(如 const { name } = student2),解构后 name 会变成普通变量,修改时无响应式;若需解构,可配合 toRefs 工具。

3. ref 与 reactive区别

对比维度 ref reactive
支持数据类型 所有类型(基础 / 对象) 仅对象类型(数组 / 对象)
访问方式 setup 中需 .value,模板自动解包 直接访问属性(无需 .value
返回值类型 ref包装对象(含 value 属性) Proxy 对象
适用场景 基础类型、单个对象属性 复杂对象 / 数组(多属性)

三、如何选择 ref 和 reactive?

  1. 优先用 ref 的场景

    • 处理基础数据类型(string/number/boolean);
    • 只需响应式管理单个对象属性(如 count = ref(0));
    • 模板中使用更简洁(无需嵌套访问)。
  2. 优先用 reactive 的场景

    • 处理复杂对象 / 数组(如用户信息、列表数据);
    • 需要频繁操作对象的多个属性(如 user.nameuser.age 一起修改);
    • 避免频繁写 .value(setup 中操作更简洁)。
相关推荐
芜青2 小时前
【Vue2手录12】单文件组件SFC
前端·javascript·vue.js
冷冷的菜哥2 小时前
react实现无缝轮播组件
前端·react.js·typescript·前端框架·无缝轮播
hrrrrb2 小时前
【Python】字符串
java·前端·python
阿笑带你学前端2 小时前
Supabase云同步架构:Flutter应用的数据同步策略
前端
Martin-Luo2 小时前
Vue3 通过json配置生成查询表单
javascript·vue.js·json
梦想CAD控件2 小时前
(在线CAD平台)网页集成CAD SDK的方法
前端·javascript·github
万少2 小时前
可可图片编辑 HarmonyOS(6)水印效果
前端·harmonyos
掘金约基奇_2 小时前
JS-SDK开发企微侧边栏
前端·javascript
FlowGram2 小时前
低代码设计态变量挑战与设计 — 前端变量引擎介绍
前端·低代码