01 从项目结构开始认识 Vue 3

从项目结构开始认识 Vue 3

一、为什么先看项目结构

很多初学者学习 Vue 时,会直接从 v-ifv-forref() 开始背语法。这样可以写出简单示例,却经常无法回答下面的问题:

  • Vue 项目从哪个文件启动?
  • URL 为什么能够打开一个 .vue 页面?
  • viewscomponentsapirouter 分别放什么?
  • .vue 文件是不是全部都要配置路由?
  • .ts 文件是不是只保存工具函数?

阅读真实项目时,第一步不是逐行理解代码,而是先找到项目的入口和主要目录。

二、Vue 在前端系统中的位置

一个典型前后端分离系统可以简化为:

text 复制代码
用户操作浏览器
      ↓
Vue 负责页面结构、状态和交互
      ↓
API 模块向后端发送请求
      ↓
后端返回 JSON 数据
      ↓
Vue 根据新数据自动更新页面

Vue 主要解决的是浏览器端的问题。它不会替代数据库,也不会直接完成后端业务计算。

在大型数字孪生页面中,Vue 通常负责:

  • 展示炉次、设备、风险和预测数据;
  • 管理实时模式与历史回放模式;
  • 响应按钮、滑块和开关操作;
  • 调用后端接口;
  • 将数据传递给 Three.js 等第三方模块;
  • 在页面退出时停止定时器并释放资源。

三、一个常见的 Vue 3 项目目录

text 复制代码
project
├─ index.html
├─ package.json
├─ vite.config.ts
└─ src
   ├─ main.ts
   ├─ App.vue
   ├─ router
   │  └─ index.ts
   ├─ views
   │  └─ heat
   │     └─ twin.vue
   ├─ components
   ├─ api
   │  ├─ heat.ts
   │  └─ types.ts
   ├─ stores
   ├─ utils
   ├─ assets
   └─ styles

1. main.ts:应用启动入口

main.ts 通常完成三件事:

ts 复制代码
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';

const app = createApp(App);
app.use(router);
app.mount('#app');

这段代码可以理解为:

text 复制代码
创建 Vue 应用
    ↓
安装路由系统
    ↓
把 App.vue 挂载到 index.html 中的 #app

2. App.vue:根组件

App.vue 是整个组件树的根。一个使用 Vue Router 的项目,根组件中经常只有布局和 router-view

vue 复制代码
<template>
  <router-view />
</template>

router-view 可以理解为一个"页面插槽"。当前 URL 匹配到哪个路由,就把对应页面组件显示在这里。

3. router/index.ts:URL 与页面的映射表

ts 复制代码
const routes = [
  {
    path: '/heat/twin',
    name: 'HeatTwin',
    component: () => import('@/views/heat/twin.vue')
  }
];

这表示访问 /heat/twin 时,Router 会加载 twin.vue

4. views:路由页面

views 通常保存能够对应完整 URL 的页面,例如:

text 复制代码
views/heat/index.vue
views/heat/detail.vue
views/heat/twin.vue

但这只是一种项目约定,不是 Vue 的强制规则。

5. components:可复用子组件

例如:

text 复制代码
components/StatusCard.vue
components/WarningList.vue
components/PlaybackToolbar.vue

这些组件一般不会单独对应 URL,而是被页面组件导入和使用。

6. api:接口请求封装

页面中不建议反复编写完整请求地址。通常先在 API 模块中封装:

ts 复制代码
export function getHeatDetail(heatId: string) {
  return request({
    url: `/heat/${heatId}`,
    method: 'get'
  });
}

页面只需要调用:

ts 复制代码
const { data } = await getHeatDetail(heatId.value);

7. types.ts:接口数据类型

ts 复制代码
export interface HeatHeaderVO {
  heat_id: string;
  converter_no: string;
  steel_grade: string;
  status: string;
}

这类文件帮助 TypeScript 判断接口字段是否正确。

四、.vue.ts 文件分别负责什么

.vue 文件

一个 .vue 文件可能是:

  • 路由页面;
  • 可复用业务组件;
  • 布局组件;
  • 图表或三维视口组件。

所以,不是所有 .vue 文件都必须注册到 Router

.ts 文件

.ts 文件可能保存:

  • API 请求函数;
  • TypeScript 类型;
  • 数据转换函数;
  • 业务规则;
  • 常量和配置;
  • 状态管理;
  • Three.js 模型或渲染逻辑。

所以,不能简单地把 .ts 全部理解成"被 Vue 调用的功能文件"。它的职责取决于所在目录和导出内容。

五、大型 Vue 页面应该怎样阅读

面对一个数千行的页面,不建议从第一行一直读到最后一行。可以按照下面的顺序:

第一步:看 <template>

先回答:

  • 页面分成哪些区域?
  • 有哪些按钮、列表、面板和子组件?
  • 哪些内容通过 v-if 切换?
  • 哪些内容通过 v-for 生成?

第二步:看 import

根据导入路径判断依赖:

text 复制代码
@/api/...          后端接口
./twin/...         当前业务模块
three              Three.js
vue-router         路由
Element Plus       UI 组件

第三步:看 ref 状态

把状态分类:

text 复制代码
页面状态:loading、sectionError
业务数据:heatMeta、playback、snapshot
交互状态:playbackIndex、displayMode
资源引用:twinCanvasRef、timer

第四步:看 computed

计算属性通常说明"原始数据如何变成页面需要的数据"。

第五步:找数据入口

重点寻找:

ts 复制代码
loadData()
loadTwinData()
loadSnapshotData()

理解页面从哪里获取数据。

第六步:找生命周期

ts 复制代码
onMounted(...)
onBeforeUnmount(...)

它们分别说明页面如何启动和如何退出。

第七步:最后看 watch 和辅助函数

这些代码通常负责状态同步、格式化、错误处理和第三方模块更新。

六、把大型页面理解为"总协调器"

真实项目中的大型页面通常不是亲自完成所有算法,而是组合多个模块:

text 复制代码
twin.vue
├─ 读取路由参数
├─ 调用 API
├─ 保存响应式状态
├─ 计算显示数据
├─ 渲染模板
├─ 调用三维模块
├─ 管理实时轮询
└─ 退出时释放资源

这类文件更接近"页面总控制器"或"页面协调器"。

七、常见误区

误区 1:所有 .vue 都是页面

错误。很多 .vue 是子组件,不会配置独立路由。

误区 2:所有跳转都使用 router.push()

错误。还可以使用:

ts 复制代码
router.replace();
router.back();

模板中也可以使用:

vue 复制代码
<router-link to="/heat">炉次中心</router-link>

误区 3:应该先读所有工具函数

大型页面中的辅助函数数量可能很多。先建立页面主链,再按调用关系深入阅读,更有效率。

八、本章小结

阅读 Vue 项目时,先找到:

text 复制代码
main.ts → App.vue → router → views 页面

阅读大型页面时,先建立:

text 复制代码
模板结构 → 状态 → 计算属性 → 数据入口 → 生命周期

下一章将进入 .vue 文件内部,系统学习单文件组件和模板语法。

相关推荐
sugar__salt1 小时前
前端路由技术详解:从传统多页到 React SPA 的完整进化之路
前端·javascript·react.js·前端框架
用户84298142418101 小时前
JS代码压缩实测:可减小体积、提高执行效率!
前端·javascript·后端
snow@li1 小时前
Vue Axios封装与SpringBoot Payload封装全景关联分析(前后端数据交互底层闭环)
前端·vue.js·spring boot
用户83134859306982 小时前
Vue3+Cesium实现阴天乌云+下雨天气特效
vue.js·webgl·cesium
无人生还2 小时前
从 Vue3 到 React · 快速上手系列第 13 篇:工程化与综合实战(Vite + Todo 应用)
前端·vue.js·react.js
Synmbrf2 小时前
ECharts 饼图鼠标悬浮后标签 title 消失的问题
前端·javascript
breeze jiang3 小时前
React useRef 实战:从 input 聚焦到 Web Worker 引用
前端·javascript·react.js
90后的晨仔3 小时前
uni-app 项目目录结构全解:每个文件、每个文件夹的作用与配置详解
vue.js·uni-app
苏灿烤鱼3 小时前
GitHub #2 拆解|把工程经验装进 Agent,为什么仍会“静默失效”?
javascript·人工智能·agent