字数
732 字
阅读时间
4 分钟
reactive
- 仅对对象类型有效(对象、数组和 Map、Set 这样的集合类型),而对 string、number 和 boolean 这样的 原始类型 无效
- 不可以随意地 " 替换 " 一个响应式对象,因为这将导致对初始引用的响应性连接丢失( Vue 的响应式系统是通过属性访问进行追踪的,因此必须始终
保持对该响应式对象的相同引用
JavaScript 没有可以作用于所有值类型的 " 引用 " 机制
javascript
const state = reactive({ count: 0 })
// n 是一个局部变量,同 state.count
// 失去响应性连接
let n = state.count
// 不影响原始的 state
n++
// count 也和 state.count 失去了响应性连接
let { count } = state
// 不会影响原始的 state
count++
// 该函数接收一个普通数字,并且
// 将无法跟踪 state.count 的变化
callSomeFunction(state.count)ref
- 创建可以使用任何值类型的响应式 ref
javascript
const obj = {
foo: ref(1),
bar: ref(2)
}
// 该函数接收一个 ref
// 需要通过 .value 取值
// 但它会保持响应性
callSomeFunction(obj.foo)
// 仍然是响应式的
const { foo, bar } = obj解包
- 当 ref 在模板中作为顶层属性被访问时,它们会被自动 " 解包 "
- 当一个
ref被嵌套在一个响应式对象中,作为属性被访问或更改时,它会自动解包
当 ref 作为响应式数组或像 Map 这种原生集合类型的元素被访问时,不会进行解包
javascript
const books = reactive([ref('Vue 3 Guide')])
// 这里需要 .value
console.log(books[0].value)
const map = reactive(new Map([['count', ref(0)]]))
// 这里需要 .value
console.log(map.get('count').value)toRef 和 toRefs
toRef:可以用来为源响应式对象上的某个 property 新创建一个 ref。然后,ref 可以被传递,它会保持对其源 property 的响应式连接
toRefs:可以批量创建多个 ref 对象(解决 reactive 生成的 proxy 对象解构会失去响应式的问题,可以使用 toRefs 响应式对象转换为一个个的 ref 使用
javascript
// 使用场景
const people = reactive({
timer: null,
happy: 100,
money: 0
})
return toRefs(people)
// toRefs原理
function toRefs(target) {
const ret = {};
for (const key in target) {
ret[key] = toRef(target, key);
}
return ret;
}使用场景
第一种写法:除了对象都用 ref 来定义
js
let switchKG = ref(false)
console.log(switchKG.value)
let arr = ref([])
arr.value = [1, 2, 3, 4, 5]
console.log(arr.value)
let Obj = reactive({
arr: []
})
reactive.arr = [1, 2, 3, 4, 5]第二种写法:都用 reactive 来定义,然后用 toRefs 进行导出到页面使用
javascript
<template>
<div>{{arr}}</div>
<div>{{obj}}</div>
<div>{{swithKW}}</div>
</template>
<script setup>
import {reactive, toRefs} from "vue";
let state = reactive({
swithKW:false,
arr: [],
obj: {}
})
console.log(state.arr)
console.log(state.obj)
//导出到页面使用
const {swithKW, arr, obj } = toRefs(state)
</script>参考
从vue3.0源码推导reactive与ref 的用法及场景 - 掘金