Vue 3 reactive 函数:创建响应式对象的完整指南
在 vue 3 的 Composition api 中,reactive() 函数专门用来创建对象类型的响应式数据。无论是普通对象、数组、Map 还是 Set,reactive 都能让它们变成响应式的。
reactive 的基本用法
使用 reactive 前需要先引入:
import { reactive } from 'vue'创建响应式对象很简单:
const user = reactive({
name: '张三',
age: 25,
address: {
city: '北京',
street: '朝阳区'
}
})在模板中使用这些数据:
<template>
<div class="person">
<h2>{{ user.name }}</h2>
<p>年龄: {{ user.age }}</p>
<p>城市: {{ user.address.city }}</p>
</div>
</template>验证响应式特性
让我们添加按钮来验证数据的响应式特性:
<template>
<div>
<h2>{{ user.name }}</h2>
<p>年龄: {{ user.age }}</p>
<p>城市: {{ user.address.city }}</p>
<button @click="incrementAge">增加年龄</button>
<button @click="updateCity">更新城市</button>
</div>
</template>
<script lang="ts" setup>
import { reactive } from 'vue'
const user = reactive({
name: '张三',
age: 25,
address: {
city: '北京',
street: '朝阳区'
}
})
const incrementAge = () => {
user.age++
}
const updateCity = () => {
user.address.city = '上海'
}
</script>点击"增加年龄"按钮时,页面上的年龄显示会立即更新。点击"更新城市"按钮时,城市信息也会实时变化。这就是响应式数据的威力——数据变化时,界面自动更新。
处理数组和嵌套数据
reactive 同样适用于数组和复杂的嵌套结构:
const todos = reactive([
{ id: 1, text: '学习 Vue 3' },
{ id: 2, text: '掌握响应式' }
])在模板中展示数组数据:
<template>
<div>
<h2>{{ user.name }}</h2>
<p>年龄: {{ user.age }}</p>
<p>城市: {{ user.address.city }}</p>
<button @click="incrementAge">增加年龄</button>
<button @click="updateCity">更新城市</button>
<ul>
<li v-for="todo in todos" :key="todo.id">
{{ todo.text }}
</li>
</ul>
<button @click="addTodo">添加任务</button>
</div>
</template>
<script lang="ts" setup>
import { reactive } from 'vue'
const user = reactive({
name: '张三',
age: 25,
address: {
city: '北京',
street: '朝阳区'
}
})
const todos = reactive([
{ id: 1, text: '学习 Vue 3' },
{ id: 2, text: '掌握响应式' }
])
const incrementAge = () => {
user.age++
}
const updateCity = () => {
user.address.city = '上海'
}
const addTodo = () => {
todos.push({
id: todos.length + 1,
text: `访问${user.address.city}`
})
}
</script>这里有几个重要概念:
- v-for 指令用于循环渲染数组元素
- :key="todo.id" 为每个元素提供唯一标识,帮助 Vue 高效更新
- 使用 push 方法向响应式数组添加元素,界面会自动更新
深层响应式特性
reactive 创建的响应式对象具有深层响应性,即使是多层嵌套的对象也是响应式的:
<template>
<div>
<h2>嵌套对象值: {{ test.x.y.c }}</h2>
<button @click="updateNestedValue">更新嵌套值</button>
</div>
</template>
<script lang="ts" setup>
import { reactive } from 'vue'
const test = reactive({
x: {
y: {
c: 666
}
}
})
const updateNestedValue = () => {
test.x.y.c = 777
}
</script>点击按钮时,即使修改的是深层嵌套的属性,界面也会正确更新。
reactive 的常见操作
对象操作
const state = reactive({
user: {
name: '李四',
age: 30
},
settings: {
theme: 'dark',
language: 'zh-CN'
}
})
// 修改属性
state.user.name = '王五'
// 添加新属性
state.user.gender = '男'
// 删除属性
delete state.user.age数组操作
const list = reactive(['苹果', '香蕉', '橙子'])
// 添加元素
list.push('葡萄')
// 删除元素
list.splice(1, 1) // 删除第二个元素
// 修改元素
list[0] = '西瓜'
// 过滤数组
const filteredList = list.filter(item => item !== '香蕉')reactive 与 ref 的区别
理解 reactive 和 ref 的区别很重要:
reactive 专门用于对象类型(对象、数组、Map、Set)
ref 可以用于任何类型,包括基本类型
reactive 返回的是原始对象的 Proxy 对象
ref 返回的是包含 value 属性的对象
import { reactive, ref } from 'vue'
// 使用 reactive 处理对象
const user = reactive({ name: '张三', age: 25 })
// 使用 ref 处理基本类型
const count = ref(0)
const message = ref('Hello')
// 使用 ref 处理对象(不推荐)
const userRef = ref({ name: '李四', age: 30 })
// 访问时需要 .value
console.log(userRef.value.name)实际应用场景
表单处理
<template>
<form @submit.prevent="handleSubmit">
<input v-model="formData.username" placeholder="用户名">
<input v-model="formData.email" placeholder="邮箱">
<input v-model="formData.password" type="password" placeholder="密码">
<button type="submit">注册</button>
</form>
</template>
<script lang="ts" setup>
import { reactive } from 'vue'
const formData = reactive({
username: '',
email: '',
password: ''
})
const handleSubmit = () => {
console.log('提交数据:', formData)
// 这里可以发送数据到服务器
}
</script>购物车功能
<template>
<div>
<div v-for="item in cart.items" :key="item.id" class="cart-item">
<span>{{ item.name }}</span>
<span>¥{{ item.price }}</span>
<span>数量: {{ item.quantity }}</span>
<button @click="increaseQuantity(item.id)">+</button>
<button @click="decreaseQuantity(item.id)">-</button>
</div>
<p>总价: ¥{{ cart.total }}</p>
</div>
</template>
<script lang="ts" setup>
import { reactive, computed } from 'vue'
const cart = reactive({
items: [
{ id: 1, name: '商品A', price: 100, quantity: 1 },
{ id: 2, name: '商品B', price: 200, quantity: 2 }
],
total: computed(() => {
return cart.items.reduce((sum, item) => sum + item.price * item.quantity, 0)
})
})
const increaseQuantity = (id: number) => {
const item = cart.items.find(item => item.id === id)
if (item) item.quantity++
}
const decreaseQuantity = (id: number) => {
const item = cart.items.find(item => item.id === id)
if (item && item.quantity > 1) item.quantity--
}
</script>注意事项
直接替换会失去响应性
// 错误做法
let state = reactive({ count: 0 })
state = { count: 1 } // 失去响应性
// 正确做法
Object.assign(state, { count: 1 })解构会失去响应性
const state = reactive({ count: 0, name: 'test' })
// 错误:解构后失去响应性
const { count, name } = state
// 正确:使用 toRefs 保持响应性
import { toRefs } from 'vue'
const { count, name } = toRefs(state)响应式对象在异步中仍然有效
const state = reactive({ data: null })
setTimeout(() => {
state.data = '异步数据' // 仍然响应式
}, 1000)总结
reactive 是 Vue 3 Composition API 的核心功能之一,它让对象类型的数据变得响应式。无论是简单的对象、复杂的嵌套结构还是数组,reactive 都能很好地处理。
记住这些要点:
- reactive 专门用于对象类型数据
- 具有深层响应性,嵌套对象也是响应式的
- 支持所有正常的 JavaScript 对象操作
- 与 ref 配合使用可以覆盖所有数据类型需求
掌握 reactive 的使用,能够让你在 Vue 3 开发中更加得心应手,构建出响应迅速、用户体验良好的应用。
本文内容仅供个人学习/研究/参考使用,不构成任何决策建议或专业指导。分享/转载时请标明原文来源,同时请勿将内容用于商业售卖、虚假宣传等非学习用途哦~感谢您的理解与支持!