如何理解 ref、toRef 和 toRefs
ref、toRef 和 toRefs 是什么
ref 是什么
- 生成值类型的响应式数据
- 可用于模板和 reactive
- 通过 .value 修改值
- 通过 ref 获取 dom
代码演示
js
<template>
<p ref="elemRef">ref demo {{ nameRef }} {{ state.age }}</p>
</template>
<script>
import {ref, reactive, onMounted} from 'vue'
export default {
name: "Ref",
setup() {
// 值类型 响应式
const nameRef = ref('lzw.')
const ageRef = ref(20)
const state = reactive({
name: nameRef,
age: ageRef
})
// 通过 .value 获取值修改值
setTimeout(() => {
console.log('ageRef', ageRef.value)
ageRef.value = 25 // .value 修改值
nameRef.value = 'lzw. A'
}, 2000)
// 通过 ref 获取 dom 元素
const elemRef = ref(null)
onMounted(() => {
console.log('elemRef', elemRef.value.innerHTML) // elemRef ref demo lzw. 20
})
return {
nameRef,
state,
elemRef
}
}
}
</script>
toRef 是什么
- 针对一个响应式对象(reactive 封装)的 prop(属性)
- 创建一个 ref,具有响应式
- 两者保持引用关系
代码演示
js
<template>
<p ref="elemRef">toRef demo {{ state.name }}{{ state.age }} - {{ ageRef }}</p>
</template>
<script>
import {toRef, reactive} from 'vue'
export default {
name: "Ref",
setup() {
// 对象实现响应式,使用 reactive
const state = reactive({
name: 'lzw.',
age: 20
})
// toRef 如果用于非响应式对象,产出的结果不具备响应式
// const state = {
// name: 'lzw.',
// age: 20
// }
// 响应式对象的一个属性实现响应式,使用 toRef
const ageRef = toRef(state, 'age')
setTimeout(() => {
state.age = 25 // state.age 和 ageRef 保持引用关系
}, 1000)
setTimeout(() => {
ageRef.value = 30 // state.age 和 ageRef 保持引用关系
}, 1000)
return {
state,
ageRef
}
}
}
</script>
toRefs 是什么
- 将响应是对象(reactive 封装)转为普通对象
- 对象的每个 prop(属性) 都是对应的 ref
- 两者保持引用关系
代码演示
js
<template>
<p ref="elemRef">toRefs demo {{ name }} {{ age }}</p>
</template>
<script>
import {toRefs, reactive} from 'vue'
export default {
name: "toRefs",
setup() {
// 对象实现响应式,使用 reactive
const state = reactive({
name: 'lzw.',
age: 20
})
// 将响应式对象变为普通对象,同时保留响应式
const stateAsRefs = toRefs(state)
// 每个属性,都是 ref 对象
// const {name: nameRef, age: ageRef} = stateAsRefs
setTimeout(() => {
state.age = 25
},1000)
return stateAsRefs
}
}
</script>
ref toRef 和toRefs 的最佳使用方式
合并函数返回响应式对象,比如
js
// 定义函数
function useFeatureX() {
const state = reactive({
x: 1,
y: 2,
});
// 返回时转为 ref
return toRefs(state);
}
export default {
setup() {
// 可以在不失去响应性的情况下破坏结构
const { x, y } = useFeatureX();
return { x, y };
},
};
- 用 reactive 做对象的响应式,用 ref 做值类型响应式
- setup 中返回 toRefs(state),或者 toRef(state,'xxx')
- ref 的变量命名都用 xxxRef
- 合并函数返回响应式对象时,使用 toRefs