vue3 ref
ref
接受一个内部值并返回一个响应式且可变的ref对象。ref只有一个属性.value,且指向该内部值。
eg:不是响应式的msg,无法被vue3跟踪
<script setup>
let msg = '11';
const onChangeMsg = () => {
msg = '22';
}
</script>
<template>
<div>{{ msg }}</div>
<button v-on:click="onChangeMsg">点击改变</button>
</template>
<style scoped lang='scss'></style>
将以上案例改成响应的ref:
<script setup>
import { ref } from 'vue';
const msg = ref('11');
const onChangeMsg = () => {
msg.value = '22';
}
</script>
<template>
<div>{{ msg }}</div>
<button v-on:click="onChangeMsg">点击改变</button>
</template>
<style scoped lang='scss'></style>
Ref TS对应的接口:
interface Ref<T> {
value: T
}
isRef:判断一个对象是不是Ref对象
<script setup>
import { isRef, ref } from 'vue';
const msg = ref('1');
const msg1 = '2';
const onChangeMsg = () => {
msg.value = '3';
console.log(msg);
console.log(isRef(msg))//true
console.log(isRef(msg1))//false
}
</script>
<template>
<div>{{ msg }}</div>
<button v-on:click="onChangeMsg">点击改变</button>
</template>
<style scoped lang='scss'></style>
shallowRef:创建一个跟踪自身.value变化的ref,只有.value是响应的,不会递归深层的属性。ref()的浅层作用形式。
使用场景:
- 大型不可变的数据结构,如list只改变value。减少大型不可变结构的响应性开销,减少深度响应导致的性能负担。
- 与其他状态系统集成,如第三方的库的初始化和使用。
eg:页面不会响应
<script setup>
import { ref, shallowRef } from 'vue';
const msg = shallowRef({
name: 1
})
const sum = ref(10);
const onChangeMsg = () => {
msg.value.name = 2;//页面不会更新,但是msg内部的name会变化
console.log(msg.value.name);//2
}
</script>
<template>
<div>{{ msg }}</div>
<button v-on:click="onChangeMsg">点击改变</button>
<div>{{ sum }}</div>
</template>
<style scoped lang='scss'></style>
eg:修改.value,页面会改变
<script setup>
import { shallowRef } from 'vue';
const msg = shallowRef({
name: 1
})
const onChangeMsg = () => {
msg.value = { name: 2 };
}
</script>
<template>
<div>{{ msg }}</div>
<button v-on:click="onChangeMsg">点击改变</button>
</template>
<style scoped lang='scss'></style>
类型:
interface shallowRef<T> {
value: T
}
function shallowRef<T>(value: T): shallowRef<T>
triggerRef:强制触发依赖于一个浅层ref的副作用,通常在对浅引用的内部值进行深度变更后使用
<script setup>
import { shallowRef, triggerRef } from 'vue';
const msg = shallowRef({
name: 1
})
const onChangeMsg = () => {
msg.value.name = 2;
triggerRef(msg);
}
</script>
<template>
<div>{{ msg }}</div>
<button v-on:click="onChangeMsg">点击改变</button>
</template>
<style scoped lang='scss'></style>
customRef:创建一个自定义的ref,显式声明追踪依赖和触发更新的控制方式
是一个工厂函数,接受两个函数track,trigger为参数,返回一个有get和set的对象
<script setup>
import { customRef } from 'vue';
function myRef(value, delay = 400) {
//创建一个防抖ref,多次触发更新,只在最后一次set时才更新
let timeout;
return customRef((track, trigger) => {
return {
set: function (newVal) {
clearTimeout(timeout);
timeout = setTimeout(() => {
console.log('触发了set');
value = newVal;
trigger();
}, delay);
},
get: function () {
track();
return value;
}
}
})
}
const name = myRef('1');
const onChangeMsg = () => {
name.value = 2;
}
</script>
<template>
<div>{{ name }}</div>
<button v-on:click="onChangeMsg">点击改变</button>
</template>
<style scoped lang='scss'></style>
利用customRef实现一个防抖的ref
import { customRef } from 'vue'
export function useDebouncedRef(value, delay = 400) {
let timeout
return customRef((track, trigger) => {
return {
get() {
track()
return value
},
set(newVal) {
clearTimeout(timeout)
timeout = setTimeout(() => {
console.log('触发了')
trigger()
value = newVal
}, delay)
}
}
})
}