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>