首先,reactive和ref是用来干啥的?
reactive和ref都是Vue3中的响应式API。
reactive将一个普通的JavaScript对象转换为响应式对象。这意味着如果该对象的属性发生变化,那么所有依赖于该属性的组件都会自动更新。
ref则可以将一个基本类型或对象转换为响应式对象。与reactive不同,ref会返回一个对象,其中包含value属性来访问值,并且只有在更新时才能触发依赖项更新。
因此,reactive和ref都是用于创建响应式数据,以便在Vue3中实现数据绑定和状态管理。
reactive的例子
import { reactive } from 'vue'
const state = reactive({
count: 0,
message: 'Hello World'
})
console.log(state.count) // 0
console.log(state.message) // Hello World
// 在组件中使用
export default {
setup() {
return {
state
}
}
}
在这个例子中,我们将包含count
和message
属性的原始对象转换为响应式对象。现在,每当我们更新count
或message
属性时,所有依赖于这些属性的组件都会自动更新。
ref的例子
import { ref } from 'vue'
const count = ref(0)
console.log(count.value) // 0
count.value++ // 更新值
console.log(count.value) // 1
// 在组件中使用
export default {
setup() {
return {
count
}
}
}
在这个例子中,我们使用ref
将一个数字转换为响应式对象。现在,每次我们更改count
的值时,他们都会触发依赖项更新。注意我们通过count.value
来访问值。
在 Vue2 中,我们使用 Object.defineProperty
来实现响应式。当我们修改了数据属性或添加新的属性时,它们都能自动触发视图渲染更新。
Vue2 中的使用例子如下:
let vm = new Vue({
el: '#app',
data: {
message: 'Hello World',
count: 0
}
})
console.log(vm.message) // Hello World
console.log(vm.count) // 0
vm.message = 'Hello Vue'
vm.count++
// 在模板中使用
<div>
<p>{{ message }}</p>
<p>{{ count }}</p>
</div>
在 Vue2 中,我们将数据定义在组件实例的 data
选项中。当我们更改 message
或 count
属性的值时,相关模板都会自动更新。
值得注意的是,在 Vue2 中,我们需要使用一些特殊的技巧才能处理嵌套数据或动态属性。这也是 Vue3 引入 reactive
和 ref
的原因之一,它们可以让我们更方便地处理嵌套数据和动态属性。
在 Vue2 中,使用 Object.defineProperty
来实现数据响应式。这意味着只有在初始状态下存在的属性才能被追踪和更新。如果我们想要追踪嵌套对象或动态属性,我们需要使用一些额外的技巧。
嵌套对象
假设我们有一个名为 user
的对象,其中包含 name
和 age
属性。现在我们要让 age
属性响应式,可以通过以下代码实现:
let vm = new Vue({
el: '#app',
data: {
user: {
name: 'Alice'
}
},
computed: {
age() {
return this.user.age
}
}
})
这里使用了一个计算属性 age
来实现 user.age
的响应式。这可以正常工作,但是如果我们需要嵌套更深的属性,这种方式会变得越来越繁琐。
动态属性
在 Vue2 中,当我们添加新属性时,这些属性将不会被自动设置为响应式。这意味着如果我们想要一个具有动态属性的响应式对象,我们需要使用 Vue.set
方法来实现:
let vm = new Vue({
el: '#app',
data: {
user: {
name: 'Alice'
}
},
methods: {
addAge() {
// 使用 Vue.set 方法
this.$set(this.user, 'age', 18)
}
}
})
在这个例子中,我们使用 $set
方法手动将 age
添加到 user
对象中。
除了处理嵌套数据和动态属性外,Vue3 中的 `reactive` 和 `ref` 与 Vue2 的数据响应式还有一些其他区别:
1. 组件实例中的数据
在 Vue2 中,所有在 `data` 中声明的数据都会被添加到组件实例中,我们可以通过 `this` 访问它们。然而,如果我们使用计算属性或 `watcher` 来访问数据,则会创建新的响应式实例,而不是使用组件实例中的数据。
在 Vue3 中,所有使用 `reactive` 和 `ref` 响应式创建的数据都不会自动添加到组件实例中。如果我们需要在组件实例中访问它们,我们需要将这些数据显式地暴露给组件。
2. 数据更新
在 Vue2 中,无论是在哪里修改数据属性的值,都会触发视图更新。这样就可能导致不必要的更新和性能问题。
在 Vue3 中,只有在依赖于数据的视图才会更新。这意味着只有在模板、计算属性或其他响应式数据中使用的数据才会触发更新。
3. 数据类型
在 Vue2 中,所有数据都被视为响应式,即使它们不需要进行响应式处理,比如一个简单的字符串或数字。
在 Vue3 中,只有使用 `reactive` 或 `ref` 声明的数据才是响应式的。对于不需要响应式处理的数据,我们可以使用普通的 JavaScript 变量或对象来提高性能。
当然,这些都是一些比较细微的区别,但它们说明了 Vue3 在性能和使用方面的改进。
虽然使用ref比较简单,但是你要知道,ref是vue团队基于reactive的基础上研制的