Vue3:ref和reactive实现响应式数据

一、情景说明

Vue2中,我们已经知道数据的响应式,是什么含义

就是,在data块中,定义的变量,在页面中引用后

任何地方修改了该变量,页面中引用的变量会立即显示最新数值。

这块,我们学习了

插值语法:{``{}}

单向绑定指令:v-bind

双向绑定指令:v-model

那么,在Vue3中,没有了data块,如何实现数据的响应式了?

二、响应式数据

Person.vue组件

html 复制代码
<template>
    <div class="person">
        <h2>姓名:{{name}}</h2>
        <h2>年龄:{{age}}</h2>
        <h2>地址:{{address}}</h2>
        <button @click="changeName">修改名字</button>
        <button @click="changeAge">修改年龄</button>
        <button @click="showTel">查看联系方式</button>
    </div>
</template>

<script lang="ts" setup name="Person">
    // 数据,原来是写在data中的,此时的name、age、tel都不是响应式的数据
    let name = '张三'
    let age = 18
    let tel = '13888888888'
    let address = '北京昌平区宏福苑·宏福科技园'

    // 方法
    function changeName() {
        name = 'zhang-san' //注意:这样修改name,页面是没有变化的
        console.log(name) //name确实改了,但name不是响应式的
    }
    function changeAge() {
        age += 1 //注意:这样修改age,页面是没有变化的
        console.log(age) //age确实改了,但age不是响应式的
    }
    function showTel() {
        alert(tel)
    }
</script>

1、ref实现基本类型的数据响应式

针对上面的组件,我们想要实现name、age两个变量的数据响应式效果。
script引用函数:

javascript 复制代码
import {ref} from 'vue'

创建变量:

javascript 复制代码
  let name = ref('张三')
  let age = ref(18)

读取变量:

html 复制代码
        <h2>姓名:{{name}}</h2>
        <h2>年龄:{{age}}</h2>

修改变量:
JS中操作ref创建的变量时候需要.value

javascript 复制代码
  // 方法
  function changeName() {
    name.value = 'zhang-san'
  }
  function changeAge() {
    age.value += 1 
  }

2、ref实现对象类型的数据响应式

底层是reactive实现的功能
script引用函数:

javascript 复制代码
import {ref} from 'vue'

创建变量:

javascript 复制代码
  let car = ref({brand:'奔驰',price:100})
  let games = ref([
    {id:'aysdytfsatr01',name:'王者荣耀'},
    {id:'aysdytfsatr02',name:'原神'},
    {id:'aysdytfsatr03',name:'三国志'}
  ])

读取变量:

html 复制代码
 <h2>汽车信息:一辆{{car.brand}}车,价值{{car.price}}万</h2>
 <li v-for="g in games" :key="g.id">{{g.name}}</li>

修改变量:
JS中操作ref创建的变量时候需要.value

javascript 复制代码
  function changePrice(){
    car.value.price += 10
    console.log(car.value.price)
  }
  function changeFirstGame(){
    games.value[0].name = '流星蝴蝶剑'
  }

3、reactive实现对象类型的数据响应式

script引用函数:

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

创建变量:

创建了3个响应式对象数据

javascript 复制代码
  // 数据
  // 单个对象数据
  let car = reactive({brand:'奔驰',price:100})
  // 数组型对象
  let games = reactive([
    {id:'aysdytfsatr01',name:'王者荣耀'},
    {id:'aysdytfsatr02',name:'原神'},
    {id:'aysdytfsatr03',name:'三国志'}
  ])
  // 多层次对象
  let obj = reactive({
    a:{
      b:{
        c:666
      }
    }
  })

读取变量:

html 复制代码
 <h2>汽车信息:一辆{{car.brand}}车,价值{{car.price}}万</h2>
 <li v-for="g in games" :key="g.id">{{g.name}}</li>
 <h2>测试:{{obj.a.b.c}}</h2>

修改变量:

javascript 复制代码
    // 方法
    function changePrice(){
        car.price += 10
        console.log(car.price)
    }
    function changeFirstGame(){
        games[0].name = '流星蝴蝶剑'
    }
    function changeObj(){
        obj.a.b.c = 999
    }

4、注意事项

reactive创建的对象变量,被重新分配一个新对象时,会失去 响应式效果
ref创建的对象类型变量,不存在这个问题。

问题重现:

reactive定义一个对象类型的变量

javascript 复制代码
    let car = reactive({brand:'奔驰',price:100})

需求:

给car重新赋值一个对象

无效写法:

javascript 复制代码
car = {brand:'奥拓',price:1}
car = reactive({brand:'奥拓',price:1})

有效写法:

javascript 复制代码
Object.assign(car,{brand:'奥拓',price:1})

三、对比

  • 宏观角度看:
  1. ref用来定义:基本类型数据对象类型数据

  2. reactive用来定义且只能定义:对象类型数据

  • 区别:
  1. ref创建的变量必须使用.value(可以使用volar插件自动添加.value)。
  2. reactive重新分配一个新对象,会失去 响应式(可以使用Object.assign去整体替换)。
  • 使用原则:
  1. 若需要一个基本类型的响应式数据,必须使用ref
  2. 若需要一个响应式对象,层级不深,refreactive都可以。
  3. 若需要一个响应式对象,且层级较深,推荐使用reactive
相关推荐
小月鸭1 天前
如何理解HTML语义化
前端·html
jump6801 天前
url输入到网页展示会发生什么?
前端
诸葛韩信1 天前
我们需要了解的Web Workers
前端
brzhang1 天前
我觉得可以试试 TOON —— 一个为 LLM 而生的极致压缩数据格式
前端·后端·架构
yivifu1 天前
JavaScript Selection API详解
java·前端·javascript
这儿有一堆花1 天前
告别 Class 组件:拥抱 React Hooks 带来的函数式新范式
前端·javascript·react.js
十二春秋1 天前
场景模拟:基础路由配置
前端
六月的可乐1 天前
实战干货-Vue实现AI聊天助手全流程解析
前端·vue.js·ai编程
一 乐1 天前
智慧党建|党务学习|基于SprinBoot+vue的智慧党建学习平台(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·学习
BBB努力学习程序设计1 天前
CSS Sprite技术:用“雪碧图”提升网站性能的魔法
前端·html