在 Web 开发的漫漫长河中,从早期的“套模版”到如今的“数据驱动”,每一次技术的跃迁都极大地提升了开发者的生产力。今天,我们将结合实际代码,深入探讨 Vue 3 中最核心的概念之一——ref,看它是如何在前人的基础上,带领我们进入响应式驱动的新时代。
完整项目结构及 App.vue源码链接:gitee.com/hong-strong…
一、 早期时代:MVC 与纯后端套模版
在 Web 开发的早期,我们主要采用 MVC(Model-View-Controller) 模式。如 server.js 所示,后端不仅负责数据的查询(Model),还负责页面的渲染(View)。
代码回溯:Node.js 原生渲染
JavaScript
// server.js 片段
function generateUserHTML(users) {
const userRows = users.map(user => `
<tr>
<td>${user.id}</td>
<td>${user.name}</td>
<td>${user.email}</td>
</tr>
`).join('');
return `<html>...<tbody>${userRows}</tbody>...</html>`;
}
痛点分析:
- 耦合度高:后端开发需要编写 HTML 字符串,逻辑极其混乱。
- 性能低下:哪怕只是修改一个用户名,也需要刷新整个页面,服务器重新生成 HTML。
二、 启蒙时代:旧的前后端分离与 DOM 编程
随后,我们进入了 AJAX 引领的前后端分离时代。后端只提供接口(API),前端通过 JavaScript 动态获取数据并更新页面。
代码回溯:传统的 DOM 操作
JavaScript
fetch('http://localhost:3000/users')
.then(res => res.json())
.then(data => {
const tbody = document.querySelector('tbody');
tbody.innerHTML = data.map(user => `
<tr>
<td>${user.id}</td>
<td>${user.name}</td>
<td>${user.email}</td>
</tr>
`).join('');
})
关键进化:前后端开发解耦。前端开发者只需关注 data 的展示。
残留问题:开发者依然要分心去管理 DOM 节点。你需要手动定位 tbody,手动拼接字符串。这并不是纯粹的业务逻辑,而是“机械的体力活”。
三、 响应式时代:Vue ref 的“魔法”
Vue 3 的出现,标志着我们正式进入了**数据驱动界面(Data-Driven UI)**的时代。核心利器就是 ref。
代码解析:App.vue 的优雅实现
在 App.vue 中,我们不再看到任何 document.querySelector。
程式碼片段
<script setup>
import { ref, onMounted } from 'vue';
// 1. 定义响应式数据
const users = ref([]);
onMounted(() => {
fetch('http://localhost:3000/users')
.then(res => res.json())
.then(data => {
// 2. 修改数据,界面会自动“动”起来
users.value = data;
})
})
</script>
<template>
<tr v-for="user in users" :key="user.id">
<td>{{user.id}}</td>
<td>{{user.name}}</td>
<td>{{user.email}}</td>
</tr>
</template>
深度解析:ref 到底做了什么?
ref 不仅仅是一个简单的变量包装器。它利用了 JavaScript 的 Proxy(或 Object.defineProperty)机制:
- 包装对象:当你调用
ref([])时,Vue 将这个数组包装成一个具有.value属性的特殊对象。 - 依赖收集(Track) :当模板(Template)中使用
users时,Vue 会默默记录下:“噢,这个表格依赖于users”。 - 派发更新(Trigger) :当你执行
users.value = data时,Vue 会触发通知,告诉所有依赖此数据的地方:“数据变了,请重新渲染!”
四、 核心对比:为什么 ref 更优?
| 维度 | 旧前后端分离 (DOM 编程) | Vue 响应式驱动 (ref) |
|---|---|---|
| 关注点 | 业务逻辑 + 节点操作 | 纯业务逻辑 (Focus on Data) |
| 代码量 | 较多,且包含大量字符串拼接 | 精简,通过声明式语法渲染 |
| 维护性 | 难。修改结构需重写 JS 逻辑 | 易。修改数据自动同步 UI |
| 性能 | 频繁操作 innerHTML 性能开销大 | 虚拟 DOM 只更新差异部分 |
五、 总结与扩展
从 server.js 的字符串拼接,到 index.html 的手动 DOM 操作,再到 App.vue 的响应式驱动,技术的演进路径非常清晰:让开发者从繁琐的底层操作中解脱出来,聚焦于业务本身。
在 Vue 3 开发中,ref 是连接 JavaScript 逻辑与 UI 界的桥梁。它让我们不再去想“我该如何更新那个标签”,而是思考“我的数据现在是什么状态”。
注意:
- 处理基本类型(String, Number)时必用
ref。 - 在
<script setup>中使用需加.value,在模板中则不需要。 - 配合
json-server可以快速搭建后端环境,进行全栈式的前端响应式开发演练。