目录
编辑
1. ref 部分
1.1 ref定义基本数据类型
1.2 ref 定义引用数据类型
2. reactive 函数
3. ref 和 reactive 对比
3.1 原理
3.2 区别
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 区别
1. ref 可以定义基本数据类型、引用数据类型,而 reactive 只能定义引用数据类型。
2. ref 创建的变量必须用 .value(可以使用volar插件自动添加value),reactive不需要。
3. 定义引用类型时,reactive 重新再分配一个对象,会失去响应式,可以使用 Object.assign整体替换。而 ref 重新分配对象时不会失去响应式。
3.3 使用原则
(1). 若需要一个基本类型的响应式数据,必须使用 ref。
(2). 若需要一个响应式对象,层级不深,ref`、reactive都可以。
(3). 若需要一个响应式对象,且层级较深,推荐使用 reactive。