Vue3 使用基于 ES6 Proxy 的新的响应性系统。

详细内容可查阅 Reactivity Fundamentals

使用 ref()

Vue 有一个全局 ref() 方法,它在 JavaScript 原始类型创建一个响应式包装器。它通常只能用于基本类型:numberstringbooleanbigintsymbol

例如,下面是如何创建一个响应式计数器对象。

import { ref } from 'vue'

const count = ref(0)
console.log(count.value) // 0

++count.value

console.log(count) // 1

使用 Vue 的全局 watchEffect() 方法,您可以监视到引用的更新。

import { ref, watchEffect } from 'vue'

const count = ref(0)

watchEffect(function handler() {
  console.log(count.value)
})

// 打印 1,因为 Vue 知道在计数更改时调用 handler()
++count.value

使用 reactive()

Vue3 还引入了一个 reactive() 方法,其行为类似于 ref(),但用于对象。

reactive() 方法的作用是:为对象的属性增加响应性。在对象上调用 reactive(),就会得到一个代理对象,可以使用 watchEffect() 监听变化。

例如,在下面的例子中,因为 user 是响应式的,所以 watchEffect() 将在每次 user 更改时打印出 user.name 的值。

import { reactive, watchEffect } from 'vue'

const user = reactive({ name: 'O.O' })

watchEffect(() => {
  console.log(user.name) // 'D.O'
}) 

user.name = 'D.O'

相对于 Vue2 的 data 属性,reactive() 的最大改进是,当您添加新属性时,reactive() 可以监听到,而不仅仅是访问现有属性。

在下面的例子中,watchEffect() 足够智能,当您在 user 上添加一个新的属性 age 时,监听到行的变化:

import { reactive, watchEffect } from 'vue'

const user = reactive({ name: 'O.O' })

watchEffect(() => {
  console.log(user.age) // 18
})

user.age = 18

reactive() 消除了在事件循环的同一事件上发生的变化。下面的代码将打印 61 和 62,但不会打印 59 或 60,因为这些更改同步发生在 61之前。

import { reactive, watchEffect } from 'vue'

const user= reactive({ name: 'O.O' })

watchEffect(() => {
  console.log(user.age) // 61
})

user.age = 59
user.age = 60
user.age = 61

setImmediate(() => { user.age = 62 }) // 62