ref
接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象仅有一个 .value
property,指向该内部值。
非响应式:
<template>
<div>
<span>{{ msg }}</span>
<el-button @click="handleChangeMSG">change msg</el-button>
</div>
</template>
<script setup lang="ts">
let msg:string = 'lcy666'
const handleChangeMSG = ():void => {
msg = 'lcy888'
}
</script>
使用ref定义变量实现响应式
<template>
<div>
<span>{{ msg }}</span>
<el-button @click="handleChangeMSG">change msg</el-button>
</div>
</template>
<script setup lang="ts">
import { ref, Ref } from "vue";
// Ref:是TS对应的类型
let msg: Ref<string> = ref("lcy666");
const handleChangeMSG = (): void => {
// 注意:被ref包裹的变量,在赋值的时候需要给变量的.value赋值
msg.value = "lcy888";
};
</script>
----------------ts的另一种写法--------------
<template>
<div>
<span>{{ msg }}</span>
<el-button @click="handleChangeMSG">change msg</el-button>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue";
// 也可以书写为如下:
let msg = ref<string | number>("lcy666");
const handleChangeMSG = (): void => {
// 注意:被ref包裹的变量,在赋值的时候需要给变量的.value赋值
msg.value = "lcy888";
};
</script>
unref
如果参数是一个ref,则返回内部值,否则返回参数本身。这是 val = isRef(val) ? val.value : val
的语法糖函数。
<template>
<div>首页~~~~~~~~~</div>
</template>
<script setup lang="ts">
import { ref, Ref, unref } from "vue";
const getNumber = (num: number | Ref<number>): number => {
return unref(num);
};
const number = 10;
const refNumber = ref<number>(10);
console.log("number", getNumber(number)); // number 10
console.log("refNumber", getNumber(refNumber)); //refNumber 10
</script>
toRef
可以用来为源响应式对象上的某个 property 新创建一个 ref。然后,ref 可以被传递,它会保持对其源 property 的响应式连接。通俗来讲就是相当于对象的浅拷贝。
1、原始对象是响应式对象,数据更新,视图更新
<template>
<div>首页~~~~~~~~~</div>
<el-button @click="add">增加fooRef</el-button>
<el-button @click="add1">增加state.foo</el-button>
<div>fooRef---{{fooRef}}</div>
<div>state.foo---{{state.foo}}</div>
</template>
<script setup lang="ts">
import {reactive, toRef} from 'vue'
const state = reactive({
foo: 1,
bar: 2
})
const fooRef = toRef(state, 'foo')
const add = ()=>{
fooRef.value++
console.log(state.foo)
console.log(fooRef.value)
}
const add1 = ()=>{
state.foo++
console.log(state.foo)
console.log(fooRef.value)
}
</script>
2、原始数据是非响应式对象,数据更新,视图不更新
<template>
<div>
<button @click="handleChange">change</button>
{{ state }}
</div>
</template>
<script setup lang="ts">
import { reactive, toRef } from 'vue'
const obj = {
foo: 1,
bar: 1
}
// bar 转化为响应式对象
const state = toRef(obj, 'bar')
const handleChange = () => {
state.value++
console.log(obj, state);
}
</script>
toRefs
批量创建ref对象---解构,主要是方便使用(普通的直接解构会使变量失去响应式)
<template>
<div>
{{ foo }} --- {{ bar }}
</div>
</template>
<script setup lang="ts">
import { reactive, toRefs } from 'vue'
const obj = reactive({
foo: 1,
bar: 1
})
let { foo, bar } = toRefs(obj)
</script>
isRef
用于检测值是否是一个ref对象
<script setup lang="ts">
import { ref, isRef, Ref } from "vue";
const refNum: Ref<number> = ref(2);
const norNum: number = 2;
console.log(isRef(refNum)); // true
console.log(isRef(norNum)); // false
</script>
customRef
创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。它需要一个工厂函数,该函数接收 track
和 trigger
函数作为参数,并且应该返回一个带有 get
和 set
的对象。
<template>
<div>首页~~~{{name}}</div>
<el-button @click="changeName">按钮</el-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(newVal:T){
trigger();
value = newVal
}
}
})
}
let name = myRef<string>('lcy');
const changeName = ()=>{
name.value='lcy666'
}
</script>
shallowRef
创建一个跟踪自身 .value
变化的 ref,但不会使其值也变成响应式的
1、修改属性不是响应式的
<template>
<div>首页~~~{{ author }}</div>
<el-button @click="changeAuthor">按钮</el-button>
</template>
<script setup lang="ts">
import { shallowRef, Ref } from 'vue'
interface Obj {
name: string
}
let author: Ref<Obj> = shallowRef({
name: 'lcy'
})
const changeAuthor = () => {
author.value.name = 'lcy666'
console.log(author.value);
}
</script>
2、直接修改为另一个对象是响应式的
<template>
<div>首页~~~{{ author }}</div>
<el-button @click="changeAuthor">按钮</el-button>
</template>
<script setup lang="ts">
import { shallowRef, Ref } from 'vue'
interface Obj {
name: string
}
let author: Ref<Obj> = shallowRef({
name: 'lcy'
})
const changeAuthor = () => {
author.value = {
name:'lcy666'
}
console.log(author.value);
}
</script>
triggerRef
手动执行与 shallowRef 关联的任何作用 (effect),可以理解为强制更新
还是上边shallowRef的第一个例子,配合triggerRef:
<template>
<div>首页~~~{{ author }}</div>
<el-button @click="changeAuthor">按钮</el-button>
</template>
<script setup lang="ts">
import { shallowRef, Ref,triggerRef } from 'vue'
interface Obj {
name: string
}
let author: Ref<Obj> = shallowRef({
name: 'lcy'
})
const changeAuthor = () => {
author.value.name = 'lcy666'
console.log(author.value,'triggerRef')
triggerRef(author)
}
</script>