☕ 前言:为什么后端以前讨厌写前端?

作为后端开发,我们习惯了 类 (Class)对象 (Object)封装 (Encapsulation)依赖注入 (DI)
当我们看到 Vue2 的代码时,内心是崩溃的:

  • 满屏的 this:这个 this 到底指的是 Window 还是实例?
  • 代码割裂:实现一个“搜索”功能,变量要写在 data 里,逻辑要写在 methods 里,监听要写在 watch 里。屏幕滚来滚去,逻辑支离破碎。

Vue3 的 Composition API(组合式 API)简直就是后端开发者的福音。
别被这个高大上的名字吓到了。在后端眼里,它本质上就是把页面逻辑写成了“Java 类”!

今天,我们忘掉前端术语,用 OOP 的视角 重新认识 Vue3。


🧩 核心映射:Vue3 就是在写 Class

在 Java/Spring 中,我们写一个业务组件通常是这样的:

public class CounterService {
    // 1. 私有成员变量 (State)
    private int count = 0;

    // 2. 构造函数/初始化 (Init)
    public CounterService() {
        System.out.println("初始化...");
    }

    // 3. Getter 方法 (Computed)
    public int getDoubleCount() {
        return count * 2;
    }

    // 4. 公共方法 (Methods)
    public void increment() {
        this.count++;
    }
}

现在,请看 Vue3 (<script setup>) 的写法:

<script setup>
import { ref, computed, onMounted } from 'vue';

// 1. 成员变量 (ref = private field)
const count = ref(0);

// 2. 初始化 (onMounted = PostConstruct)
onMounted(() => {
    console.log("初始化...");
});

// 3. Getter 方法 (computed)
const doubleCount = computed(() => count.value * 2);

// 4. 公共方法 (function = method)
const increment = () => {
    count.value++; // 注意:JS里修改引用类型要用 .value
};
</script>

发现了吗?完全一一对应!
Vue3 终于允许我们将相关的变量和方法写在一起了,这就是 “高内聚” (High Cohesion)


🧱 进阶:Hooks 就是 Service 层

后端开发最讲究 分层架构。Controller 负责接收请求,Service 负责业务逻辑。
在 Vue2 时代,逻辑很难复用(Mixins 是噩梦)。
但在 Vue3 中,我们可以把复杂的逻辑抽离成 Hooks (Composables)

请大声跟我念:Composables 就是前端的 Service 类!

场景:我们需要在多个页面实现“获取用户信息”的功能。

1. 定义 Service (UserHook.js)

这就像你写了一个 UserService.java

// useUser.js
import { ref, onMounted } from 'vue';
import { fetchUserApi } from './api';

// 导出这个“Service”
export function useUser() {
    // State (DTO)
    const userInfo = ref(null);
    const loading = ref(false);

    // Method (Service Logic)
    const getUser = async (id) => {
        loading.value = true;
        try {
            userInfo.value = await fetchUserApi(id);
        } finally {
            loading.value = false;
        }
    };

    // 暴露给外部调用的接口 (Public Interface)
    return {
        userInfo,
        loading,
        getUser
    };
}

2. 注入 Service (UserProfile.vue)

这就像在 Controller 里 @Autowired 注入 Service。

<script setup>
// 引入 Service
import { useUser } from './hooks/useUser';

// 依赖注入 (Dependency Injection)
const { userInfo, loading, getUser } = useUser();

// 调用方法
onMounted(() => {
    getUser(1001);
});
</script>

<template>
   <div v-if="loading">加载中...</div>
   <div v-else>你好,{{ userInfo?.name }}</div>
</template>

架构图解:

Hook内部逻辑
调用
定义状态
定义行为
监听变化
返回
Ref / Reactive 数据
Composable / Service
Function 方法
Watch / Computed
Vue 组件 / Controller
暴露给组件的对象

⚠️ 后端转 Vue3 的两个“坑”

虽然思想互通,但语法细节上有两个坑,后端同学最容易踩:

1. ref 还是 reactive?(包装类 vs 原生对象)
  • ref:就像 Java 的 IntegerString 包装类。它能包装基本类型,也能包装对象。访问值必须加 .value
    • 建议:无脑用 ref,虽然多写个 .value,但更安全,不会丢失响应性。
  • reactive:就像 Java 的 POJO 对象。不需要 .value
    • :如果你解构它 (const { name } = person), 响应性就丢了(这就好比把对象里的字段复制给了个临时变量,改临时变量不影响原对象)。
2. 生命周期(Hook 方法)

别去背 beforeCreatecreated 了。
<script setup> 中:

  • 代码直接写在根作用域 = created (构造函数体)。
  • onMounted = @PostConstruct (DOM 渲染完后执行,类似 Bean 初始化完成)。
  • onUnmounted = @PreDestroy (组件销毁前,做清理工作)。

📝 总结

Vue3 Composition API 的本质,就是把前端开发从 “填空题” (Options API) 变成了 “写作文” (Script Setup)

对于后端开发者来说,你只需要转变一个观念:

  • 组件 (Component) = 类 (Class)
  • Ref 数据 = 私有字段 (Private Fields)
  • Function = 方法 (Methods)
  • Composable = Service 服务类

掌握了这个心法,你会发现 Vue3 的代码结构比 Spring Boot 还要清爽。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐