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))//trueconsole.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 timeoutreturn customRef((track, trigger) => {return {get() {track()return value},set(newVal) {clearTimeout(timeout)timeout = setTimeout(() => {console.log('触发了')trigger()value = newVal}, delay)}}})
}