一 ref
ref是什么
- 可以生成 值类型(即基本数据类型) 的响应式数据;,
- 值存在ref对象的value里, 通过value来修改值;
- 用于模板和reactive, 也可当做dom里的ref使用
- ref 不仅可以用于响应式,还可以用于模板的 DOM 元素。
使用: let a = ref(1);
取值: a.value
<template>
<p ref="elemRef">今天是周一</p>
</template>
<script>
import { ref, onMounted } from 'vue'
export default {
name: 'RefTemplate',
setup(){
const elemRef = ref(null)
onMounted(() => {
console.log('ref template', elemRef.value.innerHTML, elemRef.value)
})
return{
elemRef
}
}
}
</script>
二 reactive toRef toRefs
reactive是什么
让对象变成响应式的对象, reactive可直接对ref对象解包
使用: let a = reactive({name:1, age: 1})
取值: a.name,
注意: 如果对reactive响应式对象进行解构的话, 会失去响应式
正确用法: 使用toRef, toRefs
let a = reactive({name: 'aaa', age: 1});
return {
...toRefs(a)
}
let a = reactive({name: 'aaa', age: 1});
let b = toRef(a, 'age');
return {
b
}
三 最佳使用方式
- 用 reactive 做对象的响应式,用 ref 做值类型的响应式。
- setup 中返回 toRefs(state) ,或者 toRef(state, ‘xxx’) 。
- 为了防止误会产生, ref 的变量命名尽量都用 xxxRef ,这样在使用的时候会更清楚明了。
- 合成函数返回响应式对象时,使用 toRefs
四 深入理解
-
为什么需要用ref
值类型(即基本数据类型)无处不在,如果不用 ref 而直接返回值类型,会丢失响应式。
比如在 setup 、 computed 、合成函数等各种场景中,都有可能返回值类型。
Vue 如果不定义 ref ,用户将自己制造 ref ,这样反而会更加混乱。 -
为何ref需要.value属性
通过上面的分析我们知道, ref 需要通过 .value 来修改值。这看起来是一个很麻烦的操作,总是频繁的 .value 感觉特别琐碎。那为什么一定要 .value 呢?我们来揭开它的面纱。
ref 是一个对象,这个对象不丢失响应式,且这个对象用 value 来存储值。
因此,通过 .value 属性的 get 和 set 来实现响应式。
只有当用于 模板 和 reactive 时,不需要 .value 来实现响应式,而其他情况则都需要。 -
为什么需要toRef和toRefs
与 ref 不一样的是, toRef 和 toRefs 这两个兄弟,它们不创造响应式,而是延续响应式。创造响应式一般由 ref 或者 reactive 来解决,而 toRef 和 toRefs 则是把对象的数据进行分解和扩散,其这个对象针对的是响应式对象而非普通对象。总结起来有以下三点:
初衷: 在不丢失响应式的情况下,把对象数据进行 分解或扩散。
前提: 针对的是响应式对象( reactive封装的)而非普通对象。
注意: 不创造响应式,而是延续响应式。