开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情
何时需要用到ref或reactive?
在vue3中提供了组合式API,使用这些api通过与<script setup></script>一起结合使用。回归整正题,当我们使用组合式api时,可以通过ref或者reactive函数来创建响应式变量。
语法以及用法区别
创建响应式变量
ref
<script lang="ts" setup>
import { ref } from "vue";
const refV = ref("");
</script>
reactive
<script lang="ts" setup>
import { reactive } from "vue";
const refV = reactive([]);
</script>
区别
- ref创建的响应式变量通常需要使用.value来访问而reactive不需要。 如
<script lang="ts" setup>
const refV = ref("refValue");
const reactiveV = reactive(["reactiveValue"]);
console.log(refV.value);
console.log(reactiveV);
</script>
结果
- ref可以传入基本类型和引用类型而reactive只能传入引用类型,如const refO = ref('')是可以的 但是 const reactiveO = reactive('')是不行的(会失去响应式)
ref的一些特殊情况
- 在js代码中引用ref通常是需要需用.value来实现,但有一个例外情况: 当一个响应式对象的属性是一个ref时,访问和修改该属性不需要使用value。如
<script lang="ts" setup>
const refO = reactive({
refV: ref(""),
});
refO.refV = "newValue";
console.log(refO.refV); //结果是newValue
</script>
使用ref创建的响应式对象也一样
<script lang="ts" setup>
const refO = ref({
refV: ref(""),
});
refO.value.refV = "newValue";
console.log(refO.value.refV); //结果是newValue
</script>
- 当 ref 在模板中作为顶层属性被访问时,不需要使用.value,如
<script lang="ts" setup>
const refV = ref("This is a ref Obj");
</script>
在模板中使用可以直接访问
{{ refV }}
但假如ref不是作为顶级属性被访问时,则需要使用.value,如
<script lang="ts" setup>
const refV = {
refA: ref(1),
};
</script>
在模板中则需要使用{{ refV.refA.value + 1}}
- 当ref是模板中的插值表达式的最终值时,不需要使用.value,
如上述例子,假如插值表达式为
{{ refV.refA }}则页面上会返回1
toRef
toRef官方的解释是基于响应式对象上的一个属性,创建一个对应的 ref。这样创建的 ref 与其源属性保持同步。其实就是让你能够实现将reactive中的某个属性赋值给另一个变量时,改变该变量,reactive中的属性能够同步改变,反之亦然。想象这样一个场景,当远程服务器给我们返回这样一个json:
const resp = ref({
name: "JoeZhou",
ageObj: {
age: 18,
},
});
现在我们需要用到该返回中的age属性,并且需要对此属性做一些计算,由于拿取age的数据结构很长(resp.value.ageObj.age),我们想将其提取出来,当我们计算完时,想让resp上的age变成计算后的结果,还需要进行赋值操作,如
let age = resp.value.ageObj.age;
age += 1;
resp.value.ageObj.age = age;
通过toRef我们可以将其简化
const age = toRef(resp.ageObj.age);
age.value += 1;
对age的value赋值之后,resp中的ageObj中的age也会同步新值。
toRefs 其实和toRef的功能相似,它会对传入的对象的每个属性都使用toRef创一个ref,让我们使用解构赋值也不会失去对源数据的同步性。
如上述例子,假设ageObj中不止有age,还有birthday等等的属性,我们可以通过toRefs来实现一次性创建多个ref。
const { age, birthday } = toRefs(resp.value.ageObj);
age.value 进行操作
birthday.value进行操作
总结(总结为自我理解,如有错误请指出)
-
当创建是的引用型对象,且在上述不需要书写.value的情况下,使用ref和reactive几乎相同。
-
ref可以创建基本类型变量而reactive不行
-
通过toRef和toRefs实现将reactive中的某个属性赋值给另一个变量时,该变量和源数据“双向绑定”。我们可以借此简化代码。