目录
什么是 ref
?
ref
是 Vue 3 提供的一种响应式数据包装器,用于将基本类型(如 String
, Number
, Boolean
)转换为响应式对象。它的核心特性是:
- 通过
.value
属性访问原始值 - 当值变化时自动触发视图更新
// 创建 ref
const count = ref(0);
// 访问值
console.log(count.value); // 输出: 0
// 修改值
count.value += 1;
// 在模板中自动解包
<template>{{ count }}</template> <!-- 直接显示 1 -->
Ref vs Reactive
特性 ref reactive
适用类型 基本类型 + 对象/数组(内部自动转换) 仅对象/数组
语法糖 支持直接在模板中使用 不支持
性能开销 更轻量 稍高
💡 最佳实践:优先用 ref 处理简单状态,复杂对象用 reactive
基础用法
- 基本类型
javascript
// String
const name = ref('Alice');
// Number
const age = ref(25);
// Boolean
const isLoading = ref(false);
- 对象/数组
javascript
// 对象
const user = ref({
name: 'Bob',
age: 30
});
// 数组
const hobbies = ref(['Reading', 'Coding']);
- 函数返回值
javascript
const computedRef = ref(() => {
return Math.random();
});
// 手动触发更新
computedRef.value = () => Math.random();
进阶技巧
- 组件通信(父子组件)
javascript
// ParentComponent.vue
<template>
<ChildComponent :initial-count="count" />
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const count = ref(0);
</script>
// ChildComponent.vue
<template>
<p>来自父组件的值: {{ initialValue }}</p>
</template>
<script setup>
import { defineProps } from 'vue';
const props = defineProps({
initialValue: Number
});
</script>
- 表单双向绑定
html
<template>
<input v-model="inputValue" type="text">
<p>输入内容: {{ inputValue }}</p>
</template>
<script setup>
import { ref } from 'vue';
const inputValue = ref('');
</script>
- 避免直接修改 .value
javascript
// ❌ 错误用法
const count = ref(0);
count = 1; // 丢失响应性
// ✅ 正确用法
count.value = 1;
实战案例:待办事项应用
html
<template>
<div>
<h1>{{ todoList }}</h1>
<input v-model="newTodo" placeholder="添加新任务" @keyup.enter="addTodo" />
<ul>
<li v-for="todo in todos" :key="todo.id">
{{ todo.text }}
<button @click="removeTodo(todo.id)">删除</button>
</li>
</ul>
</div>
</template>
<script setup>
import { ref } from 'vue';
const todos = ref([
{ id: 1, text: '学习 Vue 3' },
{ id: 2, text: '完成实战项目' }
]);
const newTodo = ref('');
function addTodo() {
if (newTodo.value.trim()) {
todos.value.push({
id: Date.now(),
text: newTodo.value
});
newTodo.value = '';
}
}
function removeTodo(id) {
todos.value = todos.value.filter(todo => todo.id !== id);
}
</script>
总结
✅ 推荐场景:基础状态管理、简单表单字段、跨组件同步简单数据
❌ 不推荐场景:复杂对象层级嵌套(优先用 reactive)
🚀 高级用法:结合 computed、watch 实现复杂业务逻辑
掌握 ref 的灵活运用能显著提升 Vue 3 项目的开发效率!🚀