一篇搞懂vue3中如何使用ref、reactive实现响应式数据

news/2025/2/22 19:59:21

ref 可实现 基本类型、对象类型响应式数据

reactive:只能实现 对象类型响应式

ref实现 基本类型 数据响应式: 

javascript"><template>
  <div class="person">
    <h2>姓名:{{ name }}</h2>
    <h2>年龄:{{ age }}</h2>
    <button @click="changeName">修改名字</button>
    <button @click="changeAge">修改年龄</button>
    <button @click="showTel">查看联系方式</button>
  </div>
</template>


<script lang="ts" setup name="person234">
import { ref } from 'vue' //想让哪个数据是响应式的,就用ref包裹

    // 定义数据
    //ref()是一个函数,用来包裹数据,让数据变成响应式的
      let name = ref('张三')
      let age = ref(25)
      let tel = '123-456-7890'
      
      console.log(name)
      
    // 定义方法
      function changeName() {
        name.value = '李四'

        console.log(name)
      }
      function changeAge() {
        age.value = 30        //使用 .value 才能改变ref包裹的数据(包裹之后就变成对象了)
      }
      function showTel() {
        alert(tel)
        console.log(tel)
      }
</script>

<style scoped>
.person {
    background-color: rgb(25, 120, 109);
    box-shadow: 0 0 10px;
    border-radius: 10px;
    padding: 20px;
  }
button {
  margin: 10px;
}
</style>

ref() 包裹之后,name就变成了一个对象 ,修改数据要通过 .value

 ref处理 对象数据 响应式:

javascript"><template>
  <div class="person">
    <h2>一辆{{ car.brand }}车,价值{{ car.price }}w</h2>
    <button @click="changePrice">修改汽车价格</button>
    <hr>
    <h2>喜欢的游戏:</h2>
    <ul>
      <li v-for="g in games" :key="g.id">{{ g.name }}</li>
    </ul>
    <button @click="changeFirstgame">修改第一个游戏</button>
  </div>
</template>

<script lang="ts" setup name="Person">
import { ref } from 'vue'
    
  let car = ref({ brand: '奔驰', price: 100 })

  let games = ref([
        {id: 1, name: '王者荣耀'},
        {id: 2, name: '英雄联盟'},
        {id: 3, name: '绝地求生'}
  ])
 
  // 定义方法
  function changePrice() {
    car.value.price += 10     //ref响应式只有.value才能变成响应式
    console.log(car)
  }

function changeFirstgame() {  //ref响应式只有.value才能变成响应式
    games.value[0].name = '植物大战僵尸'
  }

</script>

<style scoped>
.person {
    background-color: rgb(25, 120, 109);
    box-shadow: 0 0 10px;
    border-radius: 10px;
    padding: 20px;
  }
button {
  margin: 10px;
}
li {
  font-size: 20px;
}
</style>

reactive实现对象类型响应式数据:

javascript"><template>
  <div class="person">
    <h2>一辆{{ car.brand }}车,价值{{ car.price }}w</h2>
    <button @click="changePrice">修改汽车价格</button>
    <hr>
    <h2>喜欢的游戏:</h2>
    <ul>
      <li v-for="g in games" :key="g.id">{{ g.name }}</li>
    </ul>
    <button @click="changeFirstgame">修改第一个游戏</button>
    <hr>
    <button @click="changeC">修改c的值:{{ obj.a.b.c }}</button>
  </div>
</template>

<script lang="ts" setup name="Person">
  import { reactive } from 'vue'
    // 定义数据
    //reactive()是一个函数,用来包裹对象数据,让其变成响应式的
  let car1 = {brand: '宝马', price: 200 }
  let car = reactive({ brand: '奔驰', price: 100 })
  console.log(car1)
  console.log(car)

  let games = reactive([
        {id: 1, name: '王者荣耀'},
        {id: 2, name: '英雄联盟'},
        {id: 3, name: '绝地求生'}
  ])
  //不管c的值有多深的嵌套,只要是reactive包裹的,都是响应式的
  let obj = reactive({
  a: {
    b: {
      c: 10
    }
  }
  })
    // 定义方法
  function changePrice() {
    car.price += 10
  }

  function changeFirstgame() {
    games[0].name = '植物大战僵尸'
  }
  function changeC() {
    obj.a.b.c = 100
  }
</script>

<style scoped>
.person {
    background-color: rgb(25, 120, 109);
    box-shadow: 0 0 10px;
    border-radius: 10px;
    padding: 20px;
  }
button {
  margin: 10px;
}
li {
  font-size: 20px;
}
</style>

 ​​​

 

ref 和 reactive之间的区别:

 ref 用于定义基本类型数据、对象类型数据。

ref 创建的变量必须使用 .value (可以使用VueOfficial插件 启用dot value来优化)

reactive 用来定义:对象类型数据。

reactive重新分配一个新对象,会失去响应式(可以使用car.value、Object.assign去整体替换)。

javascript"><script lang="ts" setup name="Person">
import { ref } from 'vue'

let car = ref({ brand: '奔驰', price: 100 })
let sum = ref(0)

// 定义方法
function changePrice() {
  car.value.price += 10
}
function changeBrand() {
  car.value.brand = '宝马'
}
function changeCar() {
  // 这样写不行,因为car是一个ref对象,不能直接赋值
  // car = { brand: '保时捷', price: 1000 } 

  // 直接替换对象
  // car.value = { brand: '保时捷', price: 1000 } 

  // 合并对象属性
  Object.assign(car.value, { brand: '保时捷', price: 1000 }) 
}

function changeSum() {
  sum.value += 1
}
</script>
  • 使用原则:

  1. 若需要一个基本类型的响应式数据,必须使用ref

  2. 若需要一个响应式对象,层级不深,refreactive都可以。

  3. 若需要一个响应式对象,且层级较深,推荐使用reactive


http://www.niftyadmin.cn/n/5862712.html

相关文章

【HeadFirst系列之HeadFirst设计模式】第7天之命令模式:封装请求,轻松实现解耦!

命令模式&#xff1a;封装请求&#xff0c;轻松实现解耦&#xff01; 大家好&#xff01;今天我们来聊聊设计模式中的命令模式&#xff08;Command Pattern&#xff09;。如果你曾经需要将请求封装成对象&#xff0c;或者希望实现请求的撤销、重做等功能&#xff0c;那么命令模…

多目标粒子群优化算法-MOPSO-(机器人路径规划/多目标信号处理(图像/音频))

具体完整算法请跳转&#xff1a;多目标粒子群优化算法-MOPSO-&#xff08;机器人路径规划/多目标信号处理&#xff08;图像/音频&#xff09;&#xff09; 多目标粒子群优化算法&#xff08;Multi-Objective Particle Swarm Optimization&#xff0c;MOPSO&#xff09;是一种基…

后“智驾平权”时代,谁为安全冗余和体验升级“买单”

线控底盘&#xff0c;正在成为新势力争夺下一个技术普及红利的新赛点。 尤其是进入2025年&#xff0c;比亚迪、长安等一线传统自主品牌率先开启高阶智驾的普及战&#xff0c;加上此前已经普及的智能座舱&#xff0c;舱驾智能的「科技平权」进一步加速行业启动「线控底盘」上车窗…

jmeter提取json中的多个返回值写入CSV文件供下一个接口调用(实操)

1、写一个线程&#xff0c;查询当前所有的病人数据 2、接口返回所有病人的数据后&#xff0c;下一个查询接口需要使用患者的床位与患者pid数据&#xff08;床位与pid一一对应 不重复&#xff09;。使用json提取器&#xff0c;提取接口返回值中的床位bedno、患者pid&#xff08;…

在Linux上创建一个Docker容器并在其中执行Python脚本

在Linux上创建一个Docker容器并在其中执行Python脚本的过程&#xff0c;涉及多个方面的内容&#xff0c;包括安装Docker、编写Dockerfile、构建镜像、运行容器等。 1. 安装Docker 在Linux上使用Docker之前&#xff0c;你需要确保系统已安装Docker。Docker支持的Linux发行版有…

pytorch预训练模型下载保存路径更改

正常情况下&#xff0c;torch预训练模型在线下载&#xff0c;下模型后的地址默认是&#xff1a; ~/.cache/torch/hub/checkpoints如果没有预先下载好预训练模型&#xff0c;在运行这个代码后&#xff0c;自动下载预训练模型的。 如果要更改路径&#xff0c;有两种办法&#x…

在windows下安装windows+Ubuntu16.04双系统(下)

这篇文章的内容主要来源于这篇文章&#xff0c;为正式安装windowsUbuntu16.04双系统部分。在正式安装前&#xff0c;若还没有进行前期准备工作&#xff08;1.分区2.制作启动u盘&#xff09;&#xff0c;见《在windows下安装windowsUbuntu16.04双系统(上)》 二、正式安装Ubuntu …

服务器socket端口绑定失败解决方案

一.服务器socket端口绑定失败 问题 在学习socket的使用&#xff0c;服务器使用的是libevent框架&#xff0c;绑定和监听的是服务器的私网ip以及8000端口号。 运行程序却输出打印信息&#xff1a;"bind error"。 //初始化监听 socket 并开始监听客户端连接 void S…