这是我参与8月更文挑战的第2天,活动详情查看: 8月更文挑战
什么是响应式
响应性是一种允许我们以声明式的方式去适应变化的编程范例。
当一个值依附另一个值进行计算时, 如果前一个值发生了变化, 依附的那个也会同时进行变更.
典型案例参见 excel 函数. 当单元格A3=SUM(A1:A2)时, 此时更改A1或A2任意一个发生改变时, A3会立即作出响应更新.
响应式是Vue3的核心API。
官方也把此响应式API进行单独打包,即便不使用Vue3的情况下也可以独立使用:@vue/reactivity
响应式API-Reactive
Reactive 是Vue3中核心方法,是响应式API的心脏。
Vue3核心响应式方法有两种: 一个是 ref 它是对单个值创建的响应式, 另一个 reactive 它是对一个对象创建的深度响应式.
其余的一些方法都是围绕着这两种响应式进行的扩展类方法.
有关 ref 响应式的学习参见这里: Vue3 响应式API-Refs.
reactive有3个关键方法:
- reactive()
- isProxy()
- isReactive()
reactive 创建响应式
传入一个对象返回对象的响应式副本
const obj = reactive({ count: 0 })
转换后的对象是一个深度响应的. 它基于ES2015 Proxy 的实现中, 返回的 proxy 是不等于原始对象的。建议只使用响应式 proxy,避免依赖原始对象。
const origin = { count: 0 }
const current = reactive(origin)
console.log(origin === current) // false
reactive 将解包所有深层的 refs,同时维持 ref 的响应性。
const count = ref(1)
const obj = reactive({ count })
// ref 会被解包
console.log(obj.count === count.value) // true
// 它会更新 `obj.count`
count.value++
console.log(count.value) // 2
console.log(obj.count) // 2
// 它也会更新 `count` ref
obj.count++
console.log(obj.count) // 3
console.log(count.value) // 3
当将 ref 分配给 reactive property 时,ref 将被自动解包。
const count = ref(1)
const obj = reactive({})
obj.count = count
console.log(obj.count) // 1
console.log(obj.count === count.value) // true
isProxy 检查对象是否是Proxy对象
检查对象是否是由 reactive 或 readonly 创建的 proxy。
const obj = reactive({})
console.log(isProxy(obj)) // true
isReactive 检查对象是否是Reactive响应式对象
检查对象是否是由 reactive 创建的响应式代理。
import { reactive, isReactive } from 'vue'
export default {
setup() {
const state = reactive({
name: 'John'
})
console.log(isReactive(state)) // -> true
}
}
如果该代理是 readonly 创建的,但包裹了由 reactive 创建的另一个代理,它也会返回 true。
import { reactive, isReactive, readonly } from 'vue'
export default {
setup() {
const state = reactive({
name: 'John'
})
// 从普通对象创建的只读 proxy
const plain = readonly({
name: 'Mary'
})
console.log(isReactive(plain)) // -> false
// 从响应式 proxy 创建的只读 proxy
const stateCopy = readonly(state)
console.log(isReactive(stateCopy)) // -> true
}
}