一、ref、shallowRef、trigger
ref支持所有类型
可以粗略理解为 ref = shallowRef + triggerRef
1、通过ref获取dom元素
<p ref="_ref">这是ref获取dom元素</p>
import {ref,shallowRef, triggerRef} from 'vue'
const _ref = ref()
console.log(_ref.value?.innerText)
2、实现数据响应
import {ref,shallowRef, triggerRef} from 'vue'
//ref
type M = {
name:string,
age:number
}
const personObj= ref<M>(
{
name:'孙悟空',
age:90
}
)
const fn1= ()=>{
personObj.value.name = '白骨精' //视图也会更新
console.log(personObj)
}
//shallowRef
const man = shallowRef ({name:'张三'})
const fn1= ()=>{
/**
* man是shallowRef对象,直接更改value值不会更新视图,调用triggerRef强制更新
* 并且会受ref变量personObj更改值的影响(personObj.value.name = '白骨精')
* 所以ref和shallowRef不要写在一起
* 可以粗略理解为 ref = shallowRef + triggerRef
*/
man.value.name = '李四'
triggerRef(man)
console.log(man) //视图会更新
}
二、reactive、shallowReactive
reactive只接收引用类型 array、object、map
shallowReactive与shallowRef的问题一样,shallowReactive只能响应第一层
//对象场景
type M2 = {
name:string,
age:number
}
let from = reactive<M2>({
name:'yyx',
age:18
})
from.age = 90 //不需要.value 和ref不一样,ref取值/赋值都需要.value
//数组场景
let list = reactive<string[]>([])
list = ['aaa','bbb','ccc']
//数据异步场景(从接口请求回来)
/**
* 异步数据不能直接 = 赋值
* 通过push
* 或者定义为对象,包裹起来
*/
let list = reactive<string[]>([])
setTimeout(() => {
const res = ['aaa','bbb','ccc']
list.push(...res) //通过push注入值,不能直接 = 赋值
}, 3000);
/**或者*/
let data = reactive<any>({
list:[]
})
setTimeout(() => {
const res = ['aaa','bbb','ccc']
data.list = res
}, 3000);
三、toRef、toRefs、toRaw
只能对响应式的对象有用,非响应式的 视图毫无变化;
reactive的值被解构出来丢失了响应式,这个时候就要用toRef、toRefs;
为了单独提取对象中的一个,然后变成响应式,可以把toRef、toRefs理解为解构操作;
import {reactive,toRef, toRefs,toRaw} from 'vue'
/**
* toRef
* 一次性解构一个
*/
const toRef_Obj = reactive({
name:'游芸霞',
nickname:'fenyin'
})
/**只更新视图,但是toRef_Obj内的数据并未变化 */
let {name,nickname} = toRef_Obj
name = 'youyunxia' //这样写toRef_Obj的name还是'游芸霞“
/**双向响应式,视图、数据都发生变化 */
let _toRef_name = toRef(toRef_Obj,'name')
_toRef_name.value = 'youyunxia' //这样写toRef_Obj的name就会变成'youyunxia“
/**
* toRefs
* 和toRef一样,只是toRefs一次性解构多个
*/
let {name,nickname} = toRefs(toRef_Obj)
name.value = '张三'
console.log('toRefs========',name,nickname)
/**
* toRaw
* 不想要响应式的proxy时,可以用toRaw转化
*/
console.log('响应式=============',toRef_Obj)
console.log('非响应式===========',toRaw(toRef_Obj))
toRaw()效果图