vue3 中的 ref 和 reactive 的区别

450 阅读1分钟

vue3 中的 ref 和 reactive 的区别

Vue3 为开发者提供 ref 和 reactive 两个 API 来实现响应式数据,这也是我们使用 Vue3 开发项目中经常用到的两个 API。

  • ref 用于将数据转换为响应式数据,基本数据类型使用 Object.defineProperty(),引用类型同 reactive 一样使用 proxy
  • reactive 方法用来创建响应式对象,它接收一个对象/数组参数,返回对象的响应式副本

ref 和 reactive操作的数据类型不同:

  • ref:将数据变为响应式数据,可用于基本数据类型 和 引用数据类型
  • reactive:将数据变为响应式数据,只能用于引用类型数据 【注意】:在 js 中使用 ref 响应式数据,需要加.value

ref 和 reactive 响应式原理不同:

  • ref:对于基本数据类型的数据使用 Object.defineProperty()进行响应式,对于引用数据类型的数据使用 proxy 进行响应式
  • reactive:只能用于引用数据类型,使用 proxy 进行响应式
// ref响应式
import { ref } from 'vue'
//  字符串
let refValue = ref('Chris1993')
let setRefValue = () => {
  refValue.value = 'Hello Chris1993'
}
// 对象
let refObj = ref({ name: 'Chris1993' })
let setRefObj = () => {
  refObj.value.name = 'Hello Chris1993'
}
// reactive响应式
import { reactive } from 'vue'
// 对象
let reactiveObj = reactive({ name: 'Chris1993' })
let setReactiveObj = () => {
  reactiveObj.name = 'Hello Chris1993'
}
// 数组
let reactiveArr = reactive(['a', 'b', 'c', 'd'])
let setReactiveArr = () => {
  reactiveArr[1] = 'Hello Chris1993'
}
<!-- 响应式对象解构 -->
<template>
  <div class="about">
    <h1>ref</h1>
    <h1>refStr:{{ refStr }}</h1>
    <h1>refObj:{{ refObj }}</h1>
    <h1>name:{{ name }}</h1>
    <h1>age:{{ age }}</h1>
    <h1>{{ refArr }}</h1>
    <button @click="btn">btn</button>
    <hr />
    <h1>reactive</h1>
    <h1>{{ reactObj }}</h1>
    <h1>{{ reatArr }}</h1>
    <h1>name1:{{ name1 }}</h1>
    <h1>age1:{{ age1 }}</h1>
    <button @click="btn1">按钮</button>
  </div>
</template>
<script setup>
  import { ref, reactive, toRefs } from 'vue'
  // ref 字符串
  let refStr = ref('111')
  // ref 对象
  let refObj = ref({
    name: '111',
    age: 12,
  })
  // 解构ref对象,将ref对象的每一个属性 变为ref响应式数据
  // ref 对象和 结构出来的ref数据没有关联
  // ref对象改变 不会改变结构出来的ref数据
  // 结构出来的ref数据改变不会改变 ref 对象
  let { name, age } = refObj.value
  name = ref(name)
  age = ref(age)
  console.log('name', name)
  // ref 数组
  let refArr = ref([1, 2, 3])
  // ref响应化的数据,在模板中使用不需要.value,在js中使用需要.value
  const btn = function () {
    console.log('点击btn')
    refStr.value = '222'
    refObj.value.name = '222'
    name = '333'
    age = '3'
    refArr.value[0] = '000'
  }
  // reactive 对象
  let reactObj = reactive({
    name1: '111',
    age1: 12,
  })
  // reactive toRefs将proxy对象的所有属性解构为多个ref数据
  // proxy对象和ref数据是关联的
  // proxy对象属性值改变会导致ref数据改变
  // ref数据改变不会改变proxy对象的属性值
  let { name1, age1 } = toRefs(reactObj)
  console.log('name1', name1)
  // reactive 数组
  let reatArr = reactive([1, 2, 3])

  let btn1 = function () {
    console.log('btn1')
    reactObj.name1 = '222'
    name1 = '333'
    age1 = '3'
    reatArr[0] = '000'
  }
</script>