目前我们已经搭建了TDesign的前端和express的后端,目前是两个独立的应用。通常我们需要把前后端集成在一起,TDesign已经配置了相关的信息,只需要修改后端服务地址及端口就能实现先后端互通。
1 修改后端服务地址
vs code打开我们创建的前端工程,找到.env.development文件
将配置文件的URL修改为我们的后端地址
VITE_BASE_URL = / VITE_IS_REQUEST_PROXY = true VITE_API_URL = http://localhost:3000 VITE_API_URL_PREFIX = /api
2 解决跨域问题
如果是使用默认的express启动代码搭建服务,会遇到跨域问题,我们需要引入cors中间件来解决跨域的问题
打开后端工程,安装cors包
npm install cors --save
修改index.js文件,增加跨域支持的代码
const express = require('express'); const app = express(); const cors = require('cors'); // 定义路由 app.get('/', (req, res) => { res.send('Hello, World!'); }); app.use(cors({ origin: 'http://localhost:3002', credentials: true })); // 启动服务器 app.listen(3000, () => { console.log('Server is running on port 3000'); });
这里的origin是你的前端的工程的地址
3 动态获取菜单
我们目前的菜单是需要从服务接口获取数据的,要想开发后端接口,需要先创建数据库表,数据库我们选择mysql,以下是建表语句
CREATE TABLE `menu` ( `id` int(0) NOT NULL AUTO_INCREMENT, `path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `component` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `redirect` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL, `icon` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, `parent_id` int(0) NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE, INDEX `parent_id`(`parent_id`) USING BTREE, CONSTRAINT `menu_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `menu` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
表建好之后,需要先创建一个菜单的路由,在工程的根目录创建一个menu.js文件
我们后端服务需要访问数据库,需要将数据库的连接拆分到一个文件中,再创建一个database.js文件
访问数据库需要用到mysql库,安装一下
npm install mysql --save
在database.js里输入数据库连接代码
const mysql = require('mysql'); // 创建数据库连接池 const pool = mysql.createPool({ host: 'localhost', user: 'root', password: '******', database: 'diancan', }); module.exports = pool;
在配置文件中输入数据库的名称、用户名、密码和访问地址
然后在menu.js中输入获取菜单的方法
const express = require('express'); const router = express.Router(); const pool = require('./database'); function fetchMenuItems(parentId = null) { console.log('parentid', parentId) return new Promise((resolve, reject) => { if (parentId == null) { pool.query('SELECT * FROM menu WHERE parent_id is null ', [parentId], (error, results) => { if (error) { reject(error); } else { resolve(results); } }); } else { pool.query('SELECT * FROM menu WHERE parent_id = ?', [parentId], (error, results) => { if (error) { reject(error); } else { resolve(results); } }); } }); } async function buildMenuTree(parentId = null) { const menuItems = await fetchMenuItems(parentId); console.log('menuItems', menuItems) const menuTree = []; for (const item of menuItems) { const children = await buildMenuTree(item.id); const menuItem = { id: item.id, path: item.path, name: item.name, component: item.component, redirect: item.redirect, title: item.title, icon: item.icon, }; if (children.length > 0) { menuItem.children = children; } menuTree.push(menuItem); } console.log("menuTree", menuTree) return menuTree; } router.get('/', async (req, res) => { try { const menuTree = await buildMenuTree(); res.json({code:0,data:{list:menuTree}}); } catch (error) { console.error('Database query error:', error); res.status(500).json({ error: 'Internal server error' }); } }); module.exports = router;
然后将menu的路由注册到启动文件里,修改index.js
const express = require('express'); const app = express(); const cors = require('cors'); const menuROuter = require('./menu') // 定义路由 app.get('/', (req, res) => { res.send('Hello, World!'); }); app.use(cors({ origin: 'http://localhost:3002', credentials: true })); app.use('/api/get-menu-list',menuROuter); // 启动服务器 app.listen(3000, () => { console.log('Server is running on port 3000'); });
4 测试后端接口
我们接口写好之后,需要进行测试,可以使用Postman,输入我们的接口地址进行测试
如果看到正常返回说明我们的接口已经写好了
5 前后端联调
后端调试好了之后,启动我们的前端工程,从登录页进行测试,看是否可以正常登录,并且菜单可以正常渲染出来
总结
前后端集成,需要后端先写好接口,并且前端能够正常访问,我们需要解决跨域的问题,数据库访问的问题以及动态构造菜单的接口。总体上只要熟悉开发流程,就可以按照自己的需要完成功能的开发。