本地还没有安装 Node.js,
1️⃣ 下载 Node.js
-
打开官网:https://nodejs.org/
-
点击 LTS(长期支持版) 下载 Windows 安装包(.msi 文件)
- LTS 比较稳定,推荐用来做项目开发
2️⃣ 安装 Node.js
- 双击下载的
.msi文件 - 勾选 “Add to PATH” 选项(默认勾选即可)
- 点击下一步,保持默认选项安装完成
3️⃣ 验证安装
打开新的 CMD 或 PowerShell,输入:
node -v
npm -v
- 如果显示版本号,比如
v20.5.0和9.8.0,说明安装成功
4️⃣ 安装 Vue CLI(全局)
npm install -g @vue/cli
验证:
vue --version
- 输出版本号,例如
@vue/cli 5.0.8就说明 Vue CLI 安装成功
✅ 安装完成后,你就可以创建 Vue3 项目
一、创建 Vue3 项目
首先确保你安装了 Node.js 和 Vue CLI。然后执行:
# 安装 Vue CLI(如果没安装)
npm install -g @vue/cli
# 创建 Vue3 项目
vue create stats-frontend
- 选择 Vue 3(默认配置即可)
- 进入项目目录:
cd stats-frontend
- 启动项目:
npm run serve
默认访问地址:http://localhost:8080
二、项目目录结构(关键部分)
假设你项目名是 stats-frontend,目录结构大致如下:
stats-frontend/
├── node_modules/ # npm 安装的依赖
├── public/
│ └── index.html # 静态页面入口(浏览器直接加载的 HTML)
├── src/
│ ├── main.js # Vue 项目入口文件,创建 Vue app
│ ├── App.vue # 根组件,所有组件挂载在这里
│ ├── components/ # Vue 组件目录
│ │ └── StatForm.vue # 我们写的统计表单组件
│ └── api/ # 与后端通信封装目录
│ └── api.js # 封装 axios 调用 FastAPI API
├── package.json # 项目信息及依赖
├── package-lock.json # npm 锁文件
└── babel.config.js # Babel 配置
三、主要文件作用说明
| 文件 | 作用 | 开发重点 |
|---|---|---|
public/index.html | 静态 HTML 模板,Vue 会替换 #app div 内容 | 一般不用修改,只修改 <title> 或 favicon |
src/main.js | Vue 应用入口,创建 Vue app、挂载根组件 | 可以在这里引入全局插件,比如 router、store、axios |
src/App.vue | 根组件,所有子组件挂载在这里 | 放置主要页面结构,或者嵌套不同组件 |
src/components/StatForm.vue | Vue 组件,写你的表单 | 主要开发文件:编写表单、绑定数据、提交事件 |
src/api/api.js | 封装与后端 FastAPI 的接口调用 | 主要开发文件:提交表单数据、获取数据列表 |
package.json | 项目依赖、脚本管理 | 安装依赖、运行项目命令 |
总结:前端主要写 components 下的 Vue 组件 和 api 下的接口调用。
四、实现 HTML 表单的 Vue3 版本
1️⃣ 封装接口
src/api/api.js:
import axios from "axios";
const apiClient = axios.create({
baseURL: "http://127.0.0.1:8000/api/v1", // FastAPI 后端地址
headers: { "Content-Type": "application/json" },
});
export default {
createStat(data) {
return apiClient.post("/stats", data); // 对应 FastAPI 的 POST /stats
},
};
2️⃣ 创建表单组件
src/components/StatForm.vue:
<template>
<div>
<h1>Create Stat Record</h1>
<form @submit.prevent="submitForm">
<label>Category:</label><br>
<input v-model="category" type="text" required /><br>
<label>Value:</label><br>
<input v-model.number="value" type="number" required /><br><br>
<button type="submit">Submit</button>
</form>
<p v-if="msg">{{ msg }}</p>
</div>
</template>
<script>
import api from "../api/api";
export default {
data() {
return {
category: "",
value: null,
msg: ""
};
},
methods: {
async submitForm() {
try {
await api.createStat({ category: this.category, value: this.value });
this.msg = "Record created successfully!";
this.category = "";
this.value = null;
} catch (err) {
this.msg = "Error submitting data!";
}
}
}
};
</script>
v-model双向绑定表单数据@submit.prevent阻止默认提交,调用 Vue 方法- 调用
api.createStat()发送 POST 请求到 FastAPI
3️⃣ 根组件引入
src/App.vue:
<template>
<div id="app">
<StatForm />
</div>
</template>
<script>
import StatForm from "./components/StatForm.vue";
export default {
components: { StatForm }
};
</script>
- 根组件只负责挂载子组件
- 所有前端交互都在
StatForm.vue完成
4️⃣ FastAPI 配置 CORS(允许跨域)
app/main.py:
from fastapi.middleware.cors import CORSMiddleware
origins = [
"http://localhost:8080", # Vue 开发服务器
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
- 这样 Vue 能直接调用 FastAPI API
五、运行项目
- 启动 FastAPI:
uvicorn app.main:app --reload
- 启动 Vue:
npm run serve
- 访问
http://localhost:8080,你会看到 Vue3 表单页面,提交数据会写入 PostgreSQL 数据库。
六、总结
-
Vue 前端开发主要在:
components/下的组件写界面和逻辑api/下封装接口调用 FastAPIApp.vue负责挂载组件
-
public/index.html只作为入口模板 -
FastAPI 后端提供 API 服务,前端通过 Axios 调用
项目实战
- 提交表单(新增统计记录)
- 数据列表(实时显示数据库里的记录)
- 完整目录结构和文件说明
假设 FastAPI 后端已经提供 /api/v1/stats 的 GET 和 POST 接口。
一、项目目录结构(前端部分)
stats-frontend/
├── public/
│ └── index.html # Vue 入口模板
├── src/
│ ├── main.js # Vue 项目入口
│ ├── App.vue # 根组件
│ ├── api/
│ │ └── api.js # 封装 Axios 调用 FastAPI API
│ └── components/
│ ├── StatForm.vue # 提交表单组件
│ └── StatList.vue # 数据列表组件
├── package.json
└── package-lock.json
二、封装 API 调用
src/api/api.js:
import axios from "axios";
const apiClient = axios.create({
baseURL: "http://127.0.0.1:8000/api/v1", // FastAPI 地址
headers: { "Content-Type": "application/json" },
});
export default {
getStats() {
return apiClient.get("/stats");
},
createStat(data) {
return apiClient.post("/stats", data);
},
};
三、提交表单组件
src/components/StatForm.vue:
<template>
<div>
<h2>Create Stat Record</h2>
<form @submit.prevent="submitForm">
<label>Category:</label><br>
<input v-model="category" type="text" required /><br>
<label>Value:</label><br>
<input v-model.number="value" type="number" required /><br><br>
<button type="submit">Submit</button>
</form>
<p v-if="msg">{{ msg }}</p>
</div>
</template>
<script>
import api from "../api/api";
export default {
props: {
onSubmitted: Function, // 父组件传递的刷新列表方法
},
data() {
return {
category: "",
value: null,
msg: "",
};
},
methods: {
async submitForm() {
try {
await api.createStat({ category: this.category, value: this.value });
this.msg = "Record created successfully!";
this.category = "";
this.value = null;
if (this.onSubmitted) this.onSubmitted(); // 提交后刷新列表
} catch (err) {
this.msg = "Error submitting data!";
}
},
},
};
</script>
四、数据列表组件
src/components/StatList.vue:
<template>
<div>
<h2>Stat Records</h2>
<table border="1">
<thead>
<tr>
<th>ID</th>
<th>Category</th>
<th>Value</th>
<th>Created At</th>
</tr>
</thead>
<tbody>
<tr v-for="stat in stats" :key="stat.id">
<td>{{ stat.id }}</td>
<td>{{ stat.category }}</td>
<td>{{ stat.value }}</td>
<td>{{ stat.created_at }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import api from "../api/api";
export default {
data() {
return {
stats: [],
};
},
methods: {
async fetchStats() {
const res = await api.getStats();
this.stats = res.data;
},
},
mounted() {
this.fetchStats();
},
};
</script>
五、根组件挂载
src/App.vue:
<template>
<div id="app">
<StatForm :onSubmitted="refreshList" />
<StatList ref="statList" />
</div>
</template>
<script>
import StatForm from "./components/StatForm.vue";
import StatList from "./components/StatList.vue";
export default {
components: { StatForm, StatList },
methods: {
refreshList() {
this.$refs.statList.fetchStats();
},
},
};
</script>
- StatForm 提交数据
- StatList 显示列表
refreshList()提交成功后刷新列表
六、FastAPI 后端 CORS 配置
app/main.py:
from fastapi.middleware.cors import CORSMiddleware
origins = ["http://localhost:8080"] # Vue 开发服务器
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
七、运行项目
- 启动 FastAPI:
uvicorn app.main:app --reload
- 启动 Vue:
npm run serve
访问 http://localhost:8080,即可看到 表单 + 数据列表,提交表单会立即写入 PostgreSQL 数据库,并更新列表。
这套前端架构的特点:
- 组件化:
StatForm.vue、StatList.vue分离 - 易于扩展:后续可以加分页、过滤、图表
- 与 FastAPI 对接干净:通过
api.js封装接口
1万+

被折叠的 条评论
为什么被折叠?



