目录
[1. ref 部分](#1. ref 部分)
[1.1 ref定义基本数据类型](#1.1 ref定义基本数据类型)
[1.2 ref 定义引用数据类型](#1.2 ref 定义引用数据类型)
[2. reactive 函数](#2. reactive 函数)
[3. ref 和 reactive 对比](#3. ref 和 reactive 对比)
[3.1 原理](#3.1 原理)
[3.2 区别](#3.2 区别)
[3.3 使用原则](#3.3 使用原则)
在 Vue 3 中 ref 和 reactive 是用于创建响应式数据的两个核心函数。它们都属于 Composition API 的一部分,但适用于不同的场景和类型的数据。理解两者之间的区别和适用场景对于高效开发 Vue 应用至关重要。
1. ref 部分
1.1 ref定义基本数据类型
**作用:**定义响应式变量。
**语法:**let xxx = ref(初始值)。
**返回值:**一个RefImpl 的实例对象,简称 ref 对象,ref 的对象的 value属性是响应式的。
**注意点:**如果使用ref定义响应式数据,JS中操作数据需要 xxx.value,但模板中不需要。
代码如下所示
<template>
<div class="person">
<h3>我是Person组件</h3>
<h2>姓名:{{ name }}</h2>
<h2>年龄:{{ age }}</h2>
<button v-on:click="changeName">修改名字</button>
<button v-on:click="changeAge">修改年龄</button>
<button v-on:click="showTel">查看联系方式</button>
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
let name = ref('张三')
let age = ref(18)
let tel = ref('123456')
function changeName() {
name.value = '李四'
console.log(name)
}
function changeAge() {
age.value += 1;
console.log(age)
}
function showTel() {
alert(tel)
console.log(tel)
}
</script>
<style>
.person {
background: blue;
padding: 20px;
}
button{
margin: 0 5px;
}
</style>
控制台打印可以看到 ref 定义的响应式数据返回的是一个ref对象。
1.2 ref 定义引用数据类型
其实 ref 接收的数据可以是:基本类型、引用类型。
若 ref 接收的是引用类型,内部其实也是调用了 reactive 函数。
代码如下
<template>
<div class="person">
<h3>我是Person组件</h3>
<h2>姓名:{{ info.name }}</h2>
<h2>年龄:{{ info.age }}</h2>
<button v-on:click="changeName">修改名字</button>
<button v-on:click="changeAge">修改年龄</button>
<button v-on:click="showTel">查看联系方式</button>
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
let info = ref(
{name: '张三', age: 18, tel: '12345678901'}
)
console.log(info)
function changeName() {
info.value.name = '李四'
console.log(info.value.name)
}
function changeAge() {
info.value.age += 1;
console.log(info.value.age)
}
function showTel() {
alert(info.value.tel)
console.log(info.value.tel)
}
</script>
<style>
.person {
background: blue;
padding: 20px;
}
button {
margin: 0 5px;
}
</style>
如图所示,ref 定义引用数据类型,在外层是一个RedImpl 实例对象,而在内部是一个被proxy代理的对象。这也印证了" 若 ref 接收的是引用类型,内部其实也是调用了 reactive 函数 "。
2. reactive 函数
**作用:**定义一个响应式对象,基本类型不要用它,要用 ref,否则报错。
**语法:**let 响应式对象= reactive(源对象)。
返回值: 一个 Proxy 的实例对象,简称:响应式对象。
注意点: reactive 定义的响应式数据是"深层次"的。
代码如下
<template>
<div class="person">
<h3>我是Person组件</h3>
<h2>姓名:{{ info.name }}</h2>
<h2>年龄:{{ info.age }}</h2>
<button v-on:click="changeName">修改名字</button>
<button v-on:click="changeAge">修改年龄</button>
<button v-on:click="showTel">查看联系方式</button>
</div>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
let info = reactive(
{name: '张三', age: 18, tel: '12345678901'}
)
console.log(info)
function changeName() {
info.name = '李四'
console.log(info.name)
}
function changeAge() {
info.age += 1;
console.log(info.age)
}
function showTel() {
alert(info.tel)
console.log(info.tel)
}
</script>
<style>
.person {
background: blue;
padding: 20px;
}
button {
margin: 0 5px;
}
</style>
控制台打印 reactive 定义的引用对象info
如图所示, 打印的是一个Proxy实例对象。
3. ref 和 reactive 对比
3.1 原理
(1) ref的本质就是实例化了RefImpl类得到了一个对象,访问这个对象的value属性时触发track,设置这个对象的value属性时触发trigger
(2) reactive响应式的原理是:创建了一个被Proxy代理的对象,Proxy里面代理了各种操作,在读取的时候触发track函数,在写入的时候触发trigger函数。
要想更深入了解底层原理,可参考下面这篇文章 ↓ ↓ ↓
vue源码简析-vue响应式原理(ref和reactive的原理) - 知乎
3.2 区别
-
ref 可以定义基本数据类型、引用数据类型,而 reactive 只能定义引用数据类型。
-
ref 创建的变量必须用 .value(可以使用volar插件自动添加value),reactive不需要。
-
定义引用类型时,reactive 重新再分配一个对象,会失去响应式,可以使用 Object.assign整体替换。而 ref 重新分配对象时不会失去响应式。
3.3 使用原则
(1). 若需要一个基本类型的响应式数据,必须使用 ref。
(2). 若需要一个响应式对象,层级不深,ref`、reactive都可以。
(3). 若需要一个响应式对象,且层级较深,推荐使用 reactive。