响应式原理

    reactive 相当于 Vue 2.x 中的 Vue.observable() API ,为避免与 RxJS 中的 observables 混淆因此对其重命名。该 API 返回一个响应式的对象状态。该响应式转换是“深度转换”——它会影响嵌套对象传递的所有 property。

    Vue 中响应式状态的基本用例是我们可以在渲染期间使用它。因为依赖跟踪的关系,当响应式状态改变时视图会自动更新。

    这就是 Vue 响应式系统的本质。当从组件中的 data() 返回一个对象时,它在内部交由 reactive() 使其成为响应式对象。模板会被编译成能够使用这些响应式 property 的。

    响应式基础 API 章节你可以学习更多关于 reactive 的内容。

    1. import { ref } from 'vue'
    2. const count = ref(0)

    ref 会返回一个可变的响应式对象,该对象作为它的内部值——一个响应式的引用,这就是名称的来源。此对象只包含一个名为 value 的 property :

    1. import { ref } from 'vue'
    2. const count = ref(0)
    3. console.log(count.value) // 0
    4. count.value++
    5. console.log(count.value) // 1

    当 ref 作为渲染上下文 (从 中返回的对象) 上的 property 返回并可以在模板中被访问时,它将自动展开为内部值。不需要在模板中追加 :

    访问响应式对象

    ref 作为响应式对象的 property 被访问或更改时,为使其行为类似于普通 property,它会自动展开内部值:

    1. const count = ref(0)
    2. count
    3. })
    4. console.log(state.count) // 0
    5. state.count = 1
    6. console.log(count.value) // 1

    如果将新的 ref 赋值给现有 ref 的 property,将会替换旧的 ref:

    1. const otherCount = ref(2)
    2. state.count = otherCount
    3. console.log(state.count) // 2
    4. console.log(count.value) // 1

    当我们想使用大型响应式对象的一些 property 时,可能很想使用 ES6 解构 (opens new window)来获取我们想要的 property:

    1. import { reactive } from 'vue'
    2. const book = reactive({
    3. author: 'Vue Team',
    4. description: 'You are reading this book right now ;)',
    5. price: 'free'
    6. })
    7. let { author, title } = book

    遗憾的是,使用解构的两个 property 的响应式都会丢失。对于这种情况,我们需要将我们的响应式对象转换为一组 ref。这些 ref 将保留与源对象的响应式关联:

    1. import { reactive, toRefs } from 'vue'
    2. const book = reactive({
    3. author: 'Vue Team',
    4. year: '2020',
    5. title: 'Vue 3 Guide',
    6. description: 'You are reading this book right now ;)',
    7. price: 'free'
    8. })
    9. let { author, title } = toRefs(book)
    10. console.log(book.title) // 'Vue 3 Detailed Guide'

    你可以在 部分中了解更多有关 refs 的信息

    有时我们想跟踪响应式对象 ( 或 reactive) 的变化,但我们也希望防止在应用程序的某个位置更改它。例如,当我们有一个被 provide 的响应式对象时,我们不想让它在注入的时候被改变。为此,我们可以基于原始对象创建一个只读的 Proxy 对象: