ref 函数
ref函数用来定义一个基础类型的响应式的数据(主要针对基础类型数据)
示例:声明一个name的响应式变量
import { ref } from 'vue'
let name = ref('')
ref声明的变量在方法中使用时需要使用.value去取值
console.log(name.value)
在模板中使用时不需要.value
<span>{{name}}<span>
如果ref声明的是基础数据类型使用 Object.defineProperty 通过 get 和 set 实现的响应式数据
如果ref声明的是是对象则使用 proxy 代理对象实现的响应式数据(内部会自动通过reactive转为代理对象)
reactive 函数
reactive 函数用来定义一个对象类型的响应式数据
示例:声明一个info的响应式对象类型的变量
import { reactive } from 'vue'
let info = reactive({
name:'XXX',
age:18
})
reactive声明的变量在方法中使用时不需要使用.value去取值可以直接使用
console.log(info.name)
在模板中使用时不需要.value
<span>{{info.name}}<span>
reactive 函数接收一个对象或数组,返回一个代理对象(proxy 对象),可以实现数组、深层对象的响应式数据,这是 vue2.0 中无法实现的,底层基于 Proxy。
toRef函数
toRef函数基于响应式对象上的一个属性,创建一个对应的 ref。这样创建的 ref 与其源属性保持同步:改变源属性的值将更新 ref 的值,反之亦然。
const state = reactive({
foo: 1,
bar: 2
})
const fooRef = toRef(state, 'foo')
// 更改该 ref 会更新源属性
fooRef.value++
console.log(state.foo) // 2
// 更改源属性也会更新该 ref
state.foo++
console.log(fooRef.value) // 3
toRef() 这个函数在你想把一个 prop 的 ref 传递给一个组合式函数时会很有用:
<script setup>
import { toRef } from 'vue'
const props = defineProps(/* ... */)
// 将 `props.foo` 转换为 ref,然后传入
// 一个组合式函数
useSomeFeature(toRef(props, 'foo'))
</script>
当 toRef 与组件 props 结合使用时,关于禁止对 props 做出更改的限制依然有效。尝试将新的值传递给 ref 等效于尝试直接更改 props,这是不允许的。在这种场景下,你可能可以考虑使用带有 get 和 set 的 computed 替代。即使源属性当前不存在,toRef() 也会返回一个可用的 ref。这让它在处理可选 props 的时候格外实用,相比之下 toRefs 就不会为可选 props 创建对应的 refs。
toRefs函数
toRefs函数将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象相应属性的 ref。每个单独的 ref 都是使用 toRef() 创建的。
示例:
const state = reactive({
foo: 1,
bar: 2
})
const stateAsRefs = toRefs(state)
/*
stateAsRefs 的类型:{
foo: Ref<number>,
bar: Ref<number>
}
*/
// 这个 ref 和源属性已经“链接上了”
state.foo++
console.log(stateAsRefs.foo.value) // 2
stateAsRefs.foo.value++
console.log(state.foo) // 3
当从组合式函数中返回响应式对象时,toRefs 相当有用。使用它,消费者组件可以解构/展开返回的对象而不会失去响应性:
function useFeatureX() {
const state = reactive({
foo: 1,
bar: 2
})
// ...基于状态的操作逻辑
// 在返回时都转为 ref
return toRefs(state)
}
// 可以解构而不会失去响应性
const { foo, bar } = useFeatureX()
toRefs 在调用时只会为源对象上可以枚举的属性创建 ref。如果要为可能还不存在的属性创建 ref,请改用 toRef。
vue3官网