ref的定义
接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象具有指向内部值的单个 property
ref的使用
在vue2里面,想要使一个数据变成响应式( 数据改变-> 视图改变 -> 数据改变 )都是在data函数中定义一个属性,用v-model绑定,那么在Vue3里面,该怎么在setup里面定义响应式数据呢?
下方代码作为参考
<template>
<div>ref的使用</div>
<p>{{ count }} ----count</p>
<p>{{ number }} ----number</p>
<el-button @click="addCount" type="primary">添加count</el-button>
<el-button @click="addNumber" type="primary">添加Number</el-button>
</template>
<script>
/**
* ref 是一个函数,一般用来定义基本数据类型的响应式数据
* 返回一个RefImpl对象,通过操作对象的vlaue属性,来实现响应式数据
* */
import { defineComponent, ref } from "vue";
export default defineComponent({
name: "App",
setup() {
let count = 20;
const number = ref(10);
function addNumber() {
number.value++;
console.log("addNumber函数触发,number原理上自增",number);
}
function addCount() {
count += 1
console.log("addCount函数触发,addCount原理上自增",count);
}
return { count, number, addNumber, addCount };
},
});
</script>
如之前所说,setup是所有组合式API的入口,那么如我们之前习惯,在函数中定义一个变量count,通过return返回count变量,在html视图模板中是可以正常使用变量count,那么我们通过触发addCount函数来改变数据,看视图是否发生变化?
使用平时习惯定义变量
那么使用ref来定义数据呢?
通过以上代码来看,在vue3中,想实现响应式数据,需要通过ref来实现
ref 使用总结
总结:
在vue3中,想实现响应式数据,需要通过ref来实现
通过操作refImpl对象的value值,来实现响应式数据
这里操作的简单的数据类型(字符串,数值,布尔等)
也可以操作复杂的数据类型,如数组、对象,
但是一般操作复杂数据类型,我们会用到reactive
使用ref来定义复杂数据类型,实际上内部是做了一层转换
底层还是用reactive来实现的
reactive的定义
返回对象的响应式副本
响应式转换是“深层”的——它影响所有嵌套 property。在基于 ES2015 Proxy 的实现中,返回的 proxy 是不等于原始对象的。建议只使用响应式 proxy,避免依赖原始对象。
以上摘自vue3官网文档描述reactive
我的理解:reactive是通过ES2015中的Proxy来实现对目标对象的一层代理,通过操作目标对象来返回一个代理对象,在vue3中想要获取复杂的响应式数据,都是通过操作代理对象来完成的,操作目标对象是不会发生响应式数据变化的
上图
reactive的使用
<template>
<div>reactive的使用</div>
<h3>{{ userInfo.name }}</h3>
<h3>{{ userInfo.age }}</h3>
<h3>{{ userInfo.wife }}</h3>
<el-button @click="updateUser" type="primary">更改对象</el-button>
</template>
<script>
/**
* reactive:返回的是一个proxy的代理对象,被代理的叫做目标对象
* 把复杂的数据类型变成响应式数据。
* 通过修改代理对象的值来达到响应式数据
* const proxy = reactive(obj): 接收一个普通对象然后返回该普通对象的响应式代理器对象
* 响应式转换是“深层的”:会影响对象内部所有嵌套的属性
* 内部基于 ES6 的 Proxy 实现,通过代理对象操作源对象内部数据都是响应式的
* */
import { defineComponent, reactive } from "vue";
export default defineComponent({
name: "App",
setup() {
let obj = {
name: "小明",
age: 20,
wife: {
name: "小红",
age: 18,
cars: ["奔驰", "宝马", "特斯拉"],
},
};
const userInfo = reactive(obj);
let updateUser = () => {
userInfo.name = "胖虎";
console.log('通过更改假对象函数触发updateUser',obj, userInfo);
};
let updateWife = () => {
obj.wife.name = "静香";
console.log('通过更改真对象函数触发updateWife',obj, userInfo);
};
return { userInfo, updateUser };
},
});
</script>
通过看图跟上方代码以及控制台打印,我们可以知道通过reactive包裹的目标对象,使用proxy返回代理对象userInfo是可以实现响应式数据变化的小明变胖虎的,而直接去操作目标对象obj虽然可以达到目标对象的内容修改,但是无法实现响应式数据视图变化,胖虎的媳妇还是小红,得不到静香
reactive的总结
在vue3代码中,在setup入口中的组合式API,响应式数据都是通过reactive来实现的,
ref一般用来定义简单数据类型(数值,字符串,布尔等),
reactive一般用来应以对象、数组,ref也可来定义复杂数据类型,
但是会被转换成reactive,为了区分辨识度,
我们统一使用ref来定义基本数据类型,reactive来定义复杂数据类型
下一节
ref和reactive实现响应式数据的原理
> 记录不易,希望能得到您的一个小手手,点赞👍是我坚持下去的动力
> 一起加油吧,如果理解错误,还请指正,尽快修改,谢谢大家