携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 29 天,点击查看活动详情
start
- 今天学习一下 vue3 的 toRef api
toRef()
官方解释:
基于响应式对象上的一个属性,创建一个对应的 ref。这样创建的 ref 与其源属性保持同步:改变源属性的值将更新 ref 的值,反之亦然。
示例:
<script setup>
import { ref, toRef } from 'vue'
let obj1 = {
name: '我是第一个测试数据',
}
let a = ref(obj1.name)
let obj2 = {
name: '我是第二个对象',
}
let b = toRef(obj2, 'name')
a.value = '修改1'
b.value = '修改2'
console.log(a, b)
console.log(obj1, obj2)
// {name: '我是第一个测试数据'}
// {name: '修改2'}
obj1.name = '全新的数据111'
obj2.name = '全新的数据222'
console.log(a.value, b.value)
// 修改1
// 全新的数据222
</script>
由上述案例可得:
-
使用 ref 去获取的响应式对象,接收到的是一个纯数值。上述示例的 obj1 和 a 无关联;
-
使用 toRef 去获取的响应式对象,创建的 ref 和原属性保持同步。上述示例的
obj2
和b
,b.value
修改会影响obj2
,obj2.name
修改会影响b.value
。
toRefs()
官方解释:
将一个响应式对象转换为一个普通对象,这个普通对象的每个属性都是指向源对象相应属性的 ref。每个单独的 ref 都是使用 toRef() 创建的。
示例:
<script setup>
import { toRefs } from 'vue'
let obj = {
name: '我是一个对象',
age: 18,
}
let b = toRefs(obj)
obj.name = '全新的数据'
console.log(obj.name, b.name.value)
// 全新的数据
// 全新的数据
b.name.age = 250
console.log(obj.age, b.age.value)
// 18 18
</script>
由上述案例可得:
- toRefs 作用其实和 toRef 类似,只不过 toRef 是对一个个属性手动赋值,而 toRefs 是自动解构赋值。
shallowReactive()
官方解释:
reactive() 的浅层作用形式。
示例:
<template>
<div>
<!-- 第一层的是响应式的 -->
{{ state.foo }}
<input v-model="state.foo" type="text" />
<br />
<!-- 深层次的不是是响应式的 -->
{{ state.nested.bar }}
<input v-model="state.nested.bar" type="text" />
</div>
</template>
<script setup>
import { shallowReactive, isReactive } from 'vue'
const state = shallowReactive({
foo: 1,
nested: {
bar: 2,
},
})
console.log(isReactive(state)) // true
console.log(isReactive(state.nested)) // false
</script>
结论:
- shallow 英文释义 浅的;
- shallowReactive() 是 reactive() 的浅层作用形式;
readonly()
官方解释:
接受一个对象 (不论是响应式还是普通的) 或是一个 ref,返回一个原值的只读代理。
示例:
<script setup>
import { readonly } from 'vue'
var obj = {
name: '你好番茄',
hobby: {
game: 'CSGO',
},
}
var b = readonly(obj)
b.name = '通过只读修改'
// Set operation on key "name" failed: target is readonly. {name: '你好番茄', hobby: {…}}
/* 浅层无法修改 */
b.hobby.game = '不玩游戏了'
// Set operation on key "game" failed: target is readonly. {game: 'CSGO'}
/* 深层无法修改 */
</script>
结论:
- readonly 英文释义 只读;
- 返回一个只读代理,深层也无法修改
shallowReadonly()
官方解释:
readonly 的浅层作用形式
示例:
<script setup>
import { shallowReadonly } from 'vue'
var obj = {
name: '你好番茄',
hobby: {
game: 'CSGO',
},
}
var b = shallowReadonly(obj)
b.name = '通过只读修改'
// Set operation on key "name" failed: target is readonly. {name: '你好番茄', hobby: {…}}
/* 浅层无法修改 */
b.hobby.game = '不玩游戏了'
/* 深层可以修改 */
console.log(obj, b.hobby.game)
// {name: '你好番茄', hobby: {…}}
// '不玩游戏了'
</script>
结论:
- shallowReadonly 是 readonly 的浅层作用形式
toRaw()
官方解释:
- 根据一个 Vue 创建的代理返回其原始对象。
- toRaw() 可以返回由 reactive()、readonly()、shallowReactive() 或者 shallowReadonly() 创建的代理对应的原始对象。
示例:
<script setup>
import { ref, reactive, toRaw } from 'vue'
var obj = {
age: 18,
}
var a = reactive(obj)
console.log(toRaw(a), toRaw(a) === obj)
// {age: 18}
// true
var obj2 = {
name: '222',
}
var b = ref(obj2)
console.log(toRaw(b), toRaw(b) === obj2)
// RefImpl {name: "222"}
// false
</script>
总结:
- toRaw() 返回的是原始对象;
- 原本的代理对象不受影响;
markRaw
官方解释:
将一个对象标记为不可被转为代理。返回该对象本身
示例:
<script setup>
import { reactive, markRaw, isReactive } from 'vue'
var obj = {
age: '213',
other: {
age: 1,
},
}
var foo = markRaw(obj)
// 1. 原本的对象无法代理
console.log(isReactive(reactive(obj))) // false
// 2. markRaw返回的对象也无法代理
console.log(isReactive(reactive(foo))) // false
// 3.拦截的对象的属性是可以代理的
console.log(isReactive(reactive(foo.other))) // true
</script>
总结:
- markRaw标记的对象,无法代理;
- markRaw的返回值为原本对象;
- markRaw标记的对象内部,可以代理;
end
简单总结一下,
- 主要是针对一些其他的常见 api做了初步体验,以及基本功能有了一个熟悉的过程;
- 其主要逻辑就是弥补 ref 和 reactive的不足;
- 深入对这些方法的使用,后期再做补充;