共计 3334 个字符,预计需要花费 9 分钟才能阅读完成。
导读 | 这篇文章主要为大家介绍了 vue3+ts 中 ref 及 reactive 如何指定类型的实现示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪 |
ref 的基础特性
ref 约等于 reactive({value: x})
ref() 可以定义时无参数,第一次赋值任意类型,然后就不能增加属性
const refa = ref(6)
const rcta = reactive({value: 12})
console.log('refa:', refa) //RefImpl{...}
console.log('refa:', refa.value) //6
console.log('rcta:', rcta) //Proxy {value: 12}
console.log('rcta.value:', rcta.value) //12
const refb = ref({name: 'bbb'})
console.log('refb:', refb.value, refb.value.name) //Proxy{name: 'bbb'} bbb
//refb.value.age=18 // 报错 // 类型 {name: string;} 上不存在属性 age
如何在 ref 中指定类型
const a = ref('') // 根据输入参数推导字符串类型 Ref
const b = ref([]) // 可以通过范型显示约束 Ref
const c: Ref = ref([]) // 声明类型 Ref
const list = ref([1, 3, 5])
console.log('list 前:', list.value)
list.value[1] = 7
console.log('list 后:', list.value)
type typPeople = {
name: string
age: number
}
const list2: Ref = ref([])
console.log('list2- 前:', list2.value) //{} 不是空数组,而是空对象
list2.value.push({name: '小张', age: 18})
console.log('list2- 后:', list2.value[0]) //{name: '小张', age: 18}
********* ref 内部值指定类型 *********
const foo = ref ('foo')
foo.value = 123
********* 如果 ref 类型未知,则建议将 ref 转换为 Ref:*********
function useState (initial: T) {const state = ref(initial) as Ref
return state
}
const item: typPeople = {name: 'aa', age: 18}
const x1 = useState(item) // x1 类型为: Ref
const x2 = ref(item) //x2 类型为: Ref
console.log('ref.value:', x1.value, x1.value.name)
//Proxy{name: 'aa', age: 18} aa
reactive
返回对象的响应式副本
reactive(x) 必须要指定参数,所以类型就已经确定了,也不能增加属性
const count = ref(1)
console.log('ref:', count) //RefImpl{...}
// 当 ref 分配给 reactive 时,ref 将自动解包
const obj = reactive({a: count}) // 不需要 count.value
console.log(obj.a) // 1
console.log(obj.a === count.value) // true
//obj.b=7 // 添加属性会报错 // {a: number;}上不存在属性 b
//const str=reactive("aaa") // 这是报错的,reactive 参数只能是对象
const arr = reactive([1, 2]) // 数组,其实结果还是对象
const obj = reactive({0: 1, 1: 2})
console.log('arr', arr) //Proxy {0: 1, 1: 2}
console.log('obj', obj) //Proxy {0: 1, 1: 2}
//reactive 定义和 ref 不同,ref 返回的是 Ref<T> 类型,reactive 不存在 Reactive<T>
// 它返回是 UnwrapNestedRefs<T>,和传入目标类型一致,所以不存在定义通用 reactive 类型
function reactiveFun<T extends object>(target: T) {const state = reactive(target) as UnwrapNestedRefs<T>
return state
}
type typPeople = {
name: string
age: number
}
const item: typPeople = {name: 'aa', age: 18}
const obj1 = reactive(item) //obj1 类型为: {name: string; age: number;}
const obj2 = reactiveFun(item) //obj2 类型为: {name: string; age: number;}
isRef、isReactive
// isRef 检查值是否为一个 ref 对象
console.log('是否为 ref:', isRef(count)) //true
//isProxy 检查对象是否是 由 reactive 或 readonly 创建的 proxy
//readonly 是原始对象的只读代理
console.log('ref 是否为 proxy:', isProxy(count)) //false
console.log('reactive 是否为 proxy:', isProxy(obj)) //true
//isReactive 检查对象是否是由 reactive 创建的响应式代理
console.log('isReactive 判断:', isReactive(obj)) //true
toRef、toRefs、toRaw
toRef 当你要将 prop 的 ref 传递给复合函数时,toRef 很有用
const state = reactive({
foo: 1,
bar: 2
})
console.log(state.foo) //1
state.foo++
console.log(state.foo) //2
const fooRef = toRef(state, 'foo')
fooRef.value++
console.log(state.foo) //3 但 state.foo 并没有.value 属性,不要混淆
toRefs 将响应式对象 Proxy 转换为普通对象,且元素都指向原始对象的 ref
toRaw 返回 reactive 或 readonly 代理的原始对象,当然也可以返回 ref 的原始对象
const state = reactive({
foo: 1,
bar: 2
})
console.log(state) //Proxy {foo: 1, bar: 2}
const refs1 = toRefs(state) //toRefs 将响应式对象 Proxy 转换为普通对象
console.log('toRefs:', refs1) //{foo: ObjectRefImpl, bar: ObjectRefImpl}
const refs2 = toRaw(state) //toRaw 返回 reactive 或 readonly 代理的原始对象
console.log('toRaw:', refs2) //{foo: 1, bar: 2}
const ref1 = ref(5) //ref 并不是 Proxy, 而是 RefImpl
const refs3 = toRefs(ref1) // 不报错,但没意义
以上就是 vue3+ts 中 ref 及 reactive 指定类型实现示例的详细内容.
正文完
星哥说事-微信公众号
![post-qrcode](https://www.xgss.net/wp-content/uploads/2023/07/二维码-微信公众号256x256.jpg)