reactive
等同于Vue2.x中的Vue.observable()
.
依赖跟踪技术,让视图能够自动更新。
组件中data()返回的对象,会自动包裹上reactive
.
reactive
能够unwrap所有深层的refs
,同时保留reactivity
。
// ref用.value去代替原始值
//在reactive内的ref,都不用再使用.value了。
const count = ref(1)
const obj = reactive({ count })
// ref will be unwrapped
console.log(obj.count === count.value) // true
// it will update `obj.count`
count.value++
console.log(count.value) // 2
console.log(obj.count) // 2
// it will also update `count` ref
obj.count++
console.log(obj.count) // 3
console.log(count.value) // 3
template会被编译成render函数,并以这些响应式数据为参数。
除了用reactive
,将数据变为响应式,还有其它方法:
ref
的引入
ref
用来包裹基本类型,并用value指向其原始值从
setup()
返回后, 会被浅解包裹。作为响应式对象的属性被访问时,自动
unwraps
到value属性。新的ref替代旧的ref
Ref unwrapping
仅发生在它被放在响应式对象中(nested)。在数组或者Map中访问ref时,不会触发Ref unwrapping
。
const count = ref(0)
const state = reactive({
count
})
console.log(state.count) // 0
state.count = 1
console.log(count.value) // 1
// 新的ref替代旧的ref
const otherCount = ref(2)
state.count = otherCount
console.log(state.count) // 2
console.log(count.value) // 1
//Ref unwrapping 不会触发例子
const books = reactive([ref('Vue 3 Guide')])
// need .value here
console.log(books[0].value)
const map = reactive(new Map([['count', ref(0)]]))
// need .value here
console.log(map.get('count').value)
从reactive object 生成ref的方式
toRef/toRefs
的引入
const state = reactive({
foo: 1,
bar: 2
})
const fooRef = toRef(state, 'foo')
const book = reactive({
author: 'Vue Team',
year: '2020',
title: 'Vue 3 Guide',
description: 'You are reading this book right now ;)',
price: 'free'
})
// 下面这种解构的方法,失去了响应特性
let { author, title } = book
// 而应该这么用
let { author, title } = toRefs(book)
toRefs
特别适合组合函数的返回值,这样在调用时,就能够使用解构操作符了。例如
function useFeatureX() {
const state = reactive({
foo: 1,
bar: 2
})
// logic operating on state
// convert to refs when returning
return toRefs(state)
}
export default {
setup() {
// can destructure without losing reactivity
const { foo, bar } = useFeatureX()
return {
foo,
bar
}
}
}
readonly
的引入
import { reactive, readonly } from 'vue'
const original = reactive({ count: 0 })
const copy = readonly(original)
// mutating original will trigger watchers relying on the copy
original.count++
// mutating the copy will fail and result in a warning
copy.count++ // warning: "Set operation on key 'count' failed: target is readonly."