Vue 3 中的 ref
完全指南
Vue 3 引入了 Composition API
,其中 ref
是关键的一部分。ref
可以让我们更方便地在组件中定义响应式数据,在模板中使用 <script setup>
语法糖时尤为简洁。本文将详细讲解 Vue 3 中 ref
的概念、用途及常见用法,并通过示例展示如何在实际开发中利用 ref
提升开发效率。
一、什么是 ref
ref
是 Vue 3 Composition API 中定义响应式数据的核心函数。ref
可以使基本类型(字符串、数字、布尔值等)和复杂数据类型(数组、对象等)都具备响应式特性。当 ref
定义的数据发生变化时,Vue 会自动追踪并更新模板中对应的数据展示。
使用 ref
创建响应式数据
在 Vue 3 中,通过引入 ref
函数,我们可以轻松定义一个响应式数据。ref
会返回一个包含值的对象,通过 .value
属性访问和修改数据。
import { ref } from 'vue'; const count = ref(0); // 定义一个响应式的计数器变量 console.log(count.value); // 访问 count 的值,输出 0 count.value = 10; // 修改 count 的值 console.log(count.value); // 访问修改后的值,输出 10
复制
在上述示例中,我们通过 ref(0)
创建了一个响应式的 count
,并通过 .value
访问或更改其值。
二、基础用法
1. 定义和修改响应式数据
在 <script setup>
中,可以直接使用 ref
来定义数据并应用在模板中:
<template> <div> <p>当前计数:{{ count }}</p> <button @click="increment">增加计数</button> </div> </template> <script setup> import { ref } from 'vue'; const count = ref(0); // 定义响应式变量 count function increment() { count.value++; // 更新 count 的值 } </script>
复制
解释:
count
是响应式的,当count.value
更新时,<p>{{ count }}</p>
会自动重新渲染。- 在模板中直接使用
count
时,Vue 会自动解析.value
,无需手动调用count.value
。
2. 响应式数据的双向绑定
ref
常用于实现双向绑定,比如将表单输入的内容实时绑定到变量中:
<template> <div> <input v-model="username" placeholder="请输入用户名" /> <p>您输入的用户名是:{{ username }}</p> </div> </template> <script setup> import { ref } from 'vue'; const username = ref(''); // 定义响应式变量 username </script>
复制
解释:
v-model
指令会自动绑定输入值到username
变量,并且每次输入内容变化时,Vue 会自动更新视图中的展示值。
三、 ref
与复杂数据类型
1. 对象类型的 ref
ref
不仅可以定义基本类型数据,还可以定义对象类型。我们可以直接修改对象内部的属性,Vue 会自动监听并更新。
<template> <div> <p>用户名:{{ user.name }}</p> <p>年龄:{{ user.age }}</p> <button @click="updateUser">修改用户名</button> </div> </template> <script setup> import { ref } from 'vue'; const user = ref({ name: '张三', age: 25 }); function updateUser() { user.value.name = '李四'; // 修改对象内部属性 } </script>
复制
注意:虽然 user
是一个对象,但仍需要通过 user.value
访问其属性。
2. 数组类型的 ref
当 ref
定义数组时,可以直接使用数组的修改方法(如 push
、pop
等),Vue 会响应式地跟踪数组内容的变化。
<template> <div> <p>任务列表:</p> <ul> <li v-for="task in tasks" :key="task">{{ task }}</li> </ul> <button @click="addTask">添加任务</button> </div> </template> <script setup> import { ref } from 'vue'; const tasks = ref(['学习 Vue 3', '完成项目']); function addTask() { tasks.value.push('新任务'); // 向数组中添加元素 } </script>
复制
在这个例子中,Vue 会监听 tasks
数组的变化,每次调用 addTask
方法时,新的任务会自动添加到列表中并显示在页面上。
四、ref
在 DOM 中的应用
1. 获取 DOM 元素的引用
在 Vue 3 中,可以通过 ref
获取 DOM 元素的引用,这样可以更灵活地操作 DOM 元素。
<template> <div> <input type="text" ref="inputRef" placeholder="请输入内容" /> <button @click="focusInput">聚焦输入框</button> </div> </template> <script setup> import { ref } from 'vue'; const inputRef = ref(null); // 定义一个 DOM 引用 function focusInput() { inputRef.value.focus(); // 调用 DOM 的 focus 方法 } </script>
复制
解释:
inputRef
是一个 DOM 引用,通过<input ref="inputRef">
绑定到具体的输入框。- 当点击按钮时,
focusInput
方法会聚焦到输入框。
2. 监听 DOM 元素的变化
在某些场景下,我们可能需要在 DOM 元素变化时获取最新的高度、宽度等属性,可以结合 ref
和 Vue 的 onMounted
钩子实现。
<template> <div ref="boxRef" class="box">我是一个方块</div> </template> <script setup> import { ref, onMounted } from 'vue'; const boxRef = ref(null); onMounted(() => { console.log("方块高度:", boxRef.value.offsetHeight); }); </script> <style scoped> .box { width: 100px; height: 100px; background-color: skyblue; } </style>
复制
解释:
boxRef
用来引用.box
元素。onMounted
钩子在组件挂载后执行,获取并输出方块的高度。
五、toRefs
与 reactive
的结合
ref
更适合管理单一数据,而如果我们有多个属性的对象需要响应式管理,通常会使用 reactive
。当我们希望在组合 API 中把 reactive
对象的属性暴露到模板中时,可以使用 toRefs
将 reactive
转换为 ref
。
示例:
<template> <div> <p>用户名:{{ user.name }}</p> <p>年龄:{{ user.age }}</p> <button @click="incrementAge">增加年龄</button> </div> </template> <script setup> import { reactive, toRefs } from 'vue'; const user = reactive({ name: '张三', age: 25 }); function incrementAge() { user.age++; } const userRefs = toRefs(user); </script>
复制
六、总结
- 定义响应式数据:
ref
用于定义基本数据类型和复杂数据类型的响应式数据。 - 双向绑定:
ref
变量可以通过v-model
实现表单的双向绑定。 - DOM 引用:使用
ref
获取并操作 DOM 元素。 - 与
reactive
结合:在需要处理多个属性的对象时,建议使用reactive
和toRefs
组合。
ref
是 Vue 3 响应式系统中的核心工具,通过熟练掌握 ref
,可以在 Vue 开发中更加灵活地实现数据绑定和界面交互。