ref()
<template>
<button @click="changeMsg">改变信息</button>
<div>{{ msg }}</div>
<div>{{ man }}</div>
</template>
<script lang="ts">
import { defineComponent,ref,Ref } from 'vue'
export default defineComponent({
setup() {
let msg: Ref<string> = ref("你好")
let man = ref({name:"wj"})
const changeMsg = () => {
msg.value = "我还好"
console.log(msg);
man.value.name = "hhhh"
console.log(man);
}
return {
msg,
man,
changeMsg
}
}
})
</script>
针对简单对象
针对复杂对象,但是内部的value被proxy代理了
isRef()
判断是不是一个ref对象
<template>
<button @click="handleClick">点击</button>
<div>{{ msg1 }}</div>
<div>{{ msg2 }}</div>
</template>
<script setup lang="ts">
import { ref,isRef } from 'vue'
let msg1 = ref("我是msg1")
let msg2 = "我是msg2"
const handleClick=()=>{
console.log(isRef(msg1)); //true
console.log(isRef(msg2)); //false
}
</script>
<style scoped></style>
shallowRef()
浅层响应式。创建一个跟踪自身 .value 变化的 ref,但不会使其值也变成响应式的
<template>
<button @click="handleClick">点击</button>
<div>{{ man }}</div>
</template>
<script setup lang="ts">
import { ref,shallowRef } from 'vue'
let man = shallowRef({
name: "wj",
code: {
js:true
}
})
const handleClick=()=>{
man.value.code.js = false;
console.log(man);
}
</script>
shallowRef
针对复杂对象,其value
内部直接是值,不是一个proxy
对象,无法做到深层响应
shallowRef
不可以和re
f同时使用,如果同时使用,shallowRef
也会深层响应
<template>
<button @click="handleClick">点击</button>
<div>ref:{{ refMan }}</div>
<div>shallowRef:{{ man }}</div>
</template>
<script setup lang="ts">
import { ref,shallowRef } from 'vue'
let man = shallowRef({
name: "wj",
code: {
js:false
}
})
let refMan = ref({
name: "小米",
code: {
ts:false
}
})
const handleClick = () => {
refMan.value.code.ts = true
man.value.code.js = true;
console.log(refMan);
console.log(man);
}
</script>
总结:
- ref 是深层次响应式,shallowRef 是浅层次响应式
- ref 和 shallowRef 不能写在一块,不然会影响shallowRef 造成视图更新
tiggerRef()
强制更新页面的DOM
<template>
<button @click="handleClick">点击</button>
<div>shallowRef:{{ man }}</div>
</template>
<script setup lang="ts">
import { shallowRef,triggerRef } from 'vue'
let man = shallowRef("我是shallowRef")
const handleClick = () => {
man.value = "我是shallowRef,我被改变了";
triggerRef(man)
console.log(man);
}
</script>
customRef()
官网介绍:https://cn.vuejs.org/api/reactivity-advanced.html#customref
创建一个自定义的 ref,显式声明对其依赖追踪和更新触发的控制方式。
<template>
<button @click="handleClick">点击</button>
<div>customRef:{{ obj }}</div>
</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) {
console.log("触发了");
value = newVal
trigger()
}
}
})
}
let obj = myRef<string>("我是customRef")
const handleClick = () => {
obj.value = "我是我是customRef,我被改变了";
console.log(obj);
}
</script>
使用场景:可以自由控制响应式处理,比如在接口调用时候(官网示例)
import { customRef } from 'vue'
export function useDebouncedRef(value, delay = 200) {
let timeout
return customRef((track, trigger) => {
return {
get() {
track()
return value
},
set(newValue) {
clearTimeout(timeout)
timeout = setTimeout(() => {
value = newValue
trigger()
}, delay)
}
}
})
}
reactive()
官网:https://cn.vuejs.org/guide/essentials/reactivity-fundamentals.html#reactive
1、reactive 限定了值类型,只能用于对象类型(Object、Array、集合(Map、Set))
<template>
<button @click="change">按钮</button>
<hr/>
<div>persion: {{ person }}</div>
</template>
<script setup lang="ts">
import { reactive } from 'vue'
let person = reactive({
name: "Tom",
age: 23,
gender:1
})
const change = () => {
person.name = "timi"
console.log(person);
}
</script>
2、不能替换整个对象:reactive是proxy对象,不能直接赋值,否则会破会其响应式
<template>
<button @click="noProxyChange">直接修改</button>
<hr/>
<div>list: {{ list }}</div>
</template>
<script setup lang="ts">
import { reactive } from 'vue'
let list:string[] = reactive<string[]>([])
const noProxyChange = () => {
let temp = ["1", "2", "3"]
//替换了整个list对象
list = temp
console.log(list);
}
</script>
解决方法:使用数组自带方法改变数组
<template>
<button @click="proxyChange">响应式修改</button>
<hr/>
<div>list: {{ list }}</div>
</template>
<script setup lang="ts">
import { reactive } from 'vue'
let list:string[] = reactive<string[]>([])
const proxyChange = () => {
list.push("1")
list.push("2")
list.push("3")
console.log(list);
}
</script>
<style scoped></style>
shallowReactive()
reactive() 的浅层作用形式
详情见文档:https://cn.vuejs.org/api/reactivity-advanced.html#shallowreactive
ref和reactive
- ref绑定对象类型时,通过源码知道也是调用的 reactive
- ref 取值和赋值都需要加
.value
,reactive 不需要