Vue 3 的响应式依然是底座;Zova 希望解决的,是复杂业务中状态、行为、依赖与生命周期如何拥有清晰归属的事项。 科技新闻。
你一眼就能知道:
所以,Zova 并不是在说:
不必背景与起因
Zova 并不要求一起步就拆出很多类。一个小页面完全可以只有一个 Controller:
这正是 Cabloy/Zova 想解决的事情。
Vue 3 响应式 + TSX 渲染 + Angular 风格依赖注入
不必事件经过
Vue 3 给我们的核心能力,是一套出色的响应式系统。你可以用函数组织代码,也可以用对象组织代码;可以使用 ref、reactive,也可以把它们封装在 composable、store 或其他抽象中。
这里有一个很重要的阅读体验:
它们都很有价值,也都适合特定场景。
不必各方回应
先澄清一个容易引发争论的观点:
它做的是另一件事:
注意,这不是把 Angular 或 React 简单搬进 Vue,而是让三者各自擅长的部分结合起来:
不必影响分析
在这里:
例如,待办页面需要一个“待办数据模型”。在传统 Vue 项目里,它可能是:
例如,一个待办事项页面通常有:
在大量 Vue 3 项目中,我反复看到一种熟悉的写法:
然后,在页面 Controller 中注入它:
我们经常问:
但从初学者的角度看,它们容易形成一个困惑:
Zova 使用 TSX 作为主要渲染表达方式。
当一个真实业务逐渐复杂时,我们究竟应该如何组织状态、行为,以及它们之间的关系?
Vue 并不是一个“必须面向对象”的框架;Vue 3 的组合式 API 也不是错误的架构方式。
答案取决于我们怎么使用它。
刚开端看,这很简洁。但页面大一点、业务复杂一点,状况就会慢慢浮现:
这也是 Cabloy/Zova 想带来的体验:
很多复杂页面的真正难点,不在 UI,而在多个业务能力之间的协作。
而变量一旦散开,状态的归属、行为的边界、生命周期和依赖关系,也就容易跟着散开。
这些事项当然重大,但它们背后其实是同一个更根本的问题:
这些问题不是语法问题,而是状态与行为的架构问题。
在 Zova 中,可以这样写:
我认为,一个值得关注的方向并不只是继续讨论“状态管理库该选哪个”,而是回到一个更基础的问题:
一个好的架构不应该要求开发者一开始就设计出一棵完美的类图;它应该允许开发者从简单开始,并在复杂度真正出现时,有一条清晰的演进路径。
前端开发这些年一直在讨论状态管理。
于是,原来分散在多个生态工具中的概念,可以逐渐被统一到一个心智模型中:
在 Vue 3 响应式之上,引入 Controller、Bean、Model 与依赖注入,让状态、行为、生命周期和依赖关系重新以“对象协作”的方式组织起来。
问题不在于“函数式还是面向对象”谁更先进,而在于:
Vue 3 很成功。它足够轻、足够灵活,响应式也足够优雅;React、Angular 也都在持续演进。于是很多开发者会问:Vue 未来还会凭什么保持竞争力?
这个 ModelTodo 不只是“请求 API 的工具类”。
当然,count 能响应式更新,并不是因为“类字段天然响应式”。
它拥有一组完整而内聚的职责:
“Vue 3 的组合式 API 不够好。”
你不需要先创建 ref(0),不需要再返回一组值,也不需要在使用处解构:
但在业务 UI 逐渐复杂时,TSX 有一个很实际的优势:渲染逻辑与 TypeScript 逻辑使用同一种语言表达。
只有当职责真的开始增长时,再逐步拆分:
不要让业务代码变成一堆被解构、被搬运、被拼装的变量。 让状态回到对象,让行为回到职责,让依赖回到结构。
状态不是先决定放进哪个库,而是先决定它属于哪个对象、活多久、被谁依赖。
Zova 提供的思路是:先不急着从工具名称出发,而是先从状态归属与生命周期出发。
真正的情况是:当业务复杂度上升时,代码容易从“按对象协作”滑向“按变量拼装”。
这并不是说解构语法不能用,更不是说 Vue 3 的组合式 API 有问题。恰恰相反,它非常强大。
这并不意味着模板语法不好。Vue 模板对简单页面非常友好,也有很成熟的生态。
这份状态属于谁? 谁应该修改它? 谁依赖它? 它应该活多久? 当它变化时,谁负责维护一致性?
如果只看表面,Zova 像是在 Vue 3 上增加了 class、装饰器、IoC 容器和 Model。
它更像是在说:
例如条件、循环、局部变量、事件处理、组件组合,都可以自然地写在同一段代码中:
当这些问题有了明确答案,技术工具的选择往往就不再困难。
换句话说:
你的业务状态和业务行为,是否有清晰、稳定、可理解的归属?
这不是为了“面向对象而面向对象”,而是让代码随着业务自然生长。
我到底该在什么时候用 composable,什么时候用 Pinia,什么时候 provide/inject,什么时候又该把状态放在组件里?
而是直接使用:
但更准确地说,它提供的是一套更统一的前端工程语言:
“当项目从一个组件走向一套业务系统时,我们需要的不只是组合函数,还需要清晰的对象边界、依赖关系和状态归属。”
每一行单独看都没问题;但放在一起时,页面真正的结构已经不明显了。
这是一种很朴素、却很重要的差异:状态不再漂浮在函数返回值中,而是明确地属于一个对象。
面向对象负责组织代码,Vue 3 负责让对象中的状态具备响应式。
假设我们做一个最简单的计数器页面。
这会让架构讨论从“技术选型”回到“业务建模”。
这会不会变成过度设计? 会不会写成传统 Java 项目那种层层包装?
Vue 社区里常见的状态组织方式包括:
这份状态和行为,到底属于谁?
在 Zova 中,可以把它明确为一个 Model:
但很多时候,我们问错了事项。
这就是依赖注入带来的价值:它不仅仅是“少写一个 import”,而是让对象之间的依赖关系变得显式、稳定、可追踪。
真实机制是:Zova 会把 Controller 作为容器管理的 Bean 创建,并在底层接入 Vue 的响应式能力。因此,当 this.count++ 执行后,依赖它的渲染会像普通 Vue 响应式代码一样更新。
Zova 并不试图替换 Vue 3 的响应式能力。
对于习惯了业务逻辑复杂、组件组合较多的开发者来说,这种“逻辑—状态—渲染”在同一对象中的连续性,会带来很强的掌控感。
如果这些内容只是不断从各个 composable 中解构出来,最终页面很容易变成这样:
这样,开发者不需要先问“我要把这段逻辑写进哪个 composable”,而可以先问一个更自然的问题:
看到 class、@Controller()、@Model()、@Use(),有些开发者会立刻担心:
可以把它概括为三个核心特性:
这段代码的关键不在于“用了 class”,而在于它非常直接地表达了业务含义:
如果你已经熟悉 Vue 3,不妨尝试用 Zova 写一个小业务页面:一个 Controller、一个 Model、几段 TSX。你可能会发现,Vue 3 的响应式依然熟悉,但组织复杂业务时,代码突然不再像“麻花”了。