声明响应式状态
要为 JavaScript 对象创建响应式状态,可以使用 reactive 方法,这个方法可以实现对象的响应式
import { reactive } from 'vue'
// 响应式状态
const state = reactive({
count: 0
})
当将 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
创建独立的响应式值作为 refs
独立的原始值 (例如,一个字符串)
import { ref } from 'vue'
const count = ref(0)
import { ref } from 'vue'
const count = ref(0)
console.log(count.value) // 0
count.value++
console.log(count.value) // 1
Ref 展开
当 ref 作为渲染上下文 (从 setup() 中返回的对象) 上的 property 返回并可以在模板中被访问时,它将自动展开为内部值。不需要在模板中追加 .value:
<template>
<div>
<span>{{ count }}</span>
<button @click="count ++">Increment count</button>
</div>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const count = ref(0)
return {
count
}
}
}
</script>
访问响应式对象
// reative 将解构所有深层的 refs,同时维持ref的响应性
这句话的意思就是 reative 可以解构 refs,不需要 .value 获取值,它会自动展开内部值
const count = ref(0) const state = reactive({ count }) console.log(state.count) // 0 state.count = 1 console.log(count.value) // 1
响应式状态解构
当我们想使用大型响应式对象的一些 property 时,可能很想使用 ES6 解构来获取我们想要的 property:
import { reactive } from 'vue'
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
遗憾的是,使用解构的两个 property 的响应性都会丢失。对于这种情况,我们需要将我们的响应式对象转换为一组 ref。这些 ref 将保留与源对象的响应式关联:
import { reactive, toRefs } from 'vue'
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 } = toRefs(book)
title.value = 'Vue 3 Detailed Guide' // 我们需要使用 .value 作为标题,现在是 ref
console.log(book.title) // 'Vue 3 Detailed Guide'
toRef
可以用来为源响应式对象上的某个 property 新创建一个 ref。然后,ref 可以被传递,它会保持对其源 property 的响应式连接。
const state = reactive({ foo: 1, bar: 2 }) const fooRef = toRef(state, 'foo') fooRef.value++ console.log(state.foo) // 2 state.foo++ console.log(fooRef.value) // 3
toRefs
将响应式对象转换为普通对象,其中结果对象的每个 property 都是指向原始对象相应 property 的 ref。
const state = reactive({ foo: 1, bar: 2 }) const stateAsRefs = toRefs(state) /* stateAsRefs 的类型: { foo: Ref<number>, bar: Ref<number> } */ // ref 和原始 property 已经“链接”起来了 state.foo++ console.log(stateAsRefs.foo.value) // 2 stateAsRefs.foo.value++ console.log(state.foo) // 3
当从组合式函数返回响应式对象时,toRefs 非常有用,这样消费组件就可以在不丢失响应性的情况下对返回的对象进行分解/扩散:
function useFeatureX() { const state = reactive({ foo: 1, bar: 2 }) // 操作 state 的逻辑 // 返回时转换为ref return toRefs(state) } export default { setup() { // 可以在不失去响应性的情况下解构 const { foo, bar } = useFeatureX() return { foo, bar } } }
isRef
检查值是否为一个 ref 对象。
使用 readonly 防止更改响应式对象
import { reactive, readonly } from 'vue'
const original = reactive({ count: 0 })
const copy = readonly(original)
// 通过 original 修改 count,将会触发依赖 copy 的侦听器
original.count++
// 通过 copy 修改 count,将导致失败并出现警告
copy.count++ // 警告: "Set operation on key 'count' failed: target is readonly."
生命周期钩子

export default { setup() { // mounted onMounted(() => { console.log('Component is mounted!') }) } }
在 setup() 中使用 provide
provide 函数允许你通过两个参数定义 property:
- property 的 name (
<String>类型) - property 的 value
<!-- src/components/MyMap.vue --> setup() { provide('location', 'North Pole') provide('geolocation', { longitude: 90, latitude: 135 }) }
<!-- src/components/MyMarker.vue --> setup() { const userLocation = inject('location', 'The Universe') const userGeolocation = inject('geolocation') return { userLocation, userGeolocation } }
添加响应性
import { provide, reactive, ref } from 'vue'
setup() {
const location = ref('North Pole')
const geolocation = reactive({
longitude: 90,
latitude: 135
})
provide('location', location)
provide('geolocation', geolocation)
}
修改响应式 property
人生很漫长,或许我只是你人生中微不足道的一小段,只是你人生中的惊鸿一瞥。
浙公网安备 33010602011771号