1.ref
接收一个值返回一个响应式且可变的ref对象。ref对象仅有一个.value property,指向该内部值。
<template>
msg: {{ msg }}
<button @click="change">change msg</button>
</template>
<script setup lang="ts">
// ref为函数 Ref为类型
import {ref, Ref} from "vue";
const msg: Ref<string> = ref('hello')
const change = () => {
msg.value = 'bye'
}
</script>
注:在代码中访问ref创建的响应式对象需要用.value访问,在模版中使用响应式对象不需要使用.value
2.isRef
判断一个值是不是ref响应式对象
<template>
<button @click="estimate">
isRef
</button>
</template>
<script setup lang="ts">
import {isRef, Ref, ref} from "vue";
const msg: Ref<string> = ref('hello')
const num: number = 666;
const estimate = () => {
console.log(isRef(msg)) // true 内部使用响应式对象的__v_isRef值判断
console.log(isRef(num)) // false
}
</script>
3.shallowRef
浅层的ref响应式,只对第一层的.value做响应式的处理
<template>
{{ msg.info }}
<button @click="change">
isRef
</button>
</template>
<script setup lang="ts">
import {Ref, shallowRef} from "vue";
interface Msg {
info?: string
}
// 浅层的响应式对象 只对第一层也就是.value层做响应式的监听。
// 可以作为优化性能的手段使用
const msg: Ref<Msg> = shallowRef({
info: "hello"
})
const change = () => {
msg.value.info = 'bye' // 此时ref对象的值会发生改变 但是视图并不会更新
msg.value = {
info: 'bye'
} // 此时ref对象的值会发生改变 并且视图会更新
}
</script>
4.triggerRef
<template>
{{ msg.info }}
<button @click="change">
isRef
</button>
</template>
<script setup lang="ts">
import {Ref, shallowRef, triggerRef} from "vue";
interface Msg {
info?: string
}
// 浅层的响应式对象 只对第一层也就是.value层做响应式的监听。
// 可以作为优化性能的手段使用
const msg: Ref<Msg> = shallowRef({
info: "hello"
})
const change = () => {
msg.value.info = 'bye' // 此时ref对象的值会发生改变 但是视图并不会更新
// 通过 triggerRef 可以使视图强制更新
triggerRef(msg)
}
</script>
5.customRef
自定义Ref对象
<template>
<div>{{ msg }}</div>
<button @click="change">change msg</button>
<div>{{ text }}</div>
<button @click="changeText">change text</button>
</template>
<script setup lang="ts">
import {customRef} from "vue";
function myRef<T>(value: T) {
return customRef((track, trigger) => {
// 必须返回一个对象
return {
get() {
track() // 追踪数据
return value
},
set(newValue) {
console.log(newValue)
value = newValue
trigger() // 触发响应 更新视图
}
}
})
}
const msg = myRef<string>('hello')
const change = () => {
msg.value = 'bye'
}
// 应用实现一个防抖ref
function useDebouncedRef<T>(value: T, delay: number) {
let timer: any = null
return customRef<T>((track, trigger) => ({
get() {
track()
return value
},
set(newValue) {
clearTimeout(timer)
timer = setTimeout(() => {
value = newValue
// ...do something
trigger()
}, delay)
}
}))
}
const text = useDebouncedRef<string>('', 2000)
const changeText = () => {
text.value = '延迟2s出现'
}
</script>
6.Ref和shallowRef小问题
<template>
{{ msg }}
{{ shallowMsg.info }}
<button @click="change">change</button>
</template>
<script setup lang="ts">
import {ref, shallowRef} from "vue"
const msg = ref('hello')
const shallowMsg = shallowRef({
info: 'HELLO'
})
const change = () => {
// ref的更新会造成 shallowRef的视图更新
msg.value = 'bye'
shallowMsg.value.info = 'BYE'
}
</script>