在之前的实战示例中,我们搭建了项目基础架构并实现了用户认证功能。接下来,我们将基于此构建一个商品管理系统,涵盖商品的添加、查询、更新和删除操作,进一步深入探索Vue、TS和MySQL的协同应用。
一、创建商品数据模型
- 定义商品模型
在项目的models
文件夹中创建product.model.ts
文件,用于定义商品的数据模型。示例代码如下:
import { Model, DataTypes, Optional } from'sequelize-typescript';
import sequelize from '../config/db.config';
interface ProductAttributes {
id: number;
name: string;
description: string;
price: number;
quantity: number;
}
interface ProductCreationAttributes extends Optional<ProductAttributes, 'id'> {}
class Product extends Model<ProductAttributes, ProductCreationAttributes> {
id!: number;
name!: string;
description!: string;
price!: number;
quantity!: number;
}
Product.init({
id: {
type: DataTypes.INTEGER.UNSIGNED,
autoIncrement: true,
primaryKey: true
},
name: {
type: DataTypes.STRING,
allowNull: false
},
description: {
type: DataTypes.TEXT,
allowNull: false
},
price: {
type: DataTypes.DECIMAL(10, 2),
allowNull: false
},
quantity: {
type: DataTypes.INTEGER.UNSIGNED,
allowNull: false,
defaultValue: 0
}
}, {
sequelize,
tableName: 'products'
});
export default Product;
这个模型定义了商品的基本属性,包括id
、name
(商品名称)、description
(商品描述)、price
(价格)和quantity
(库存数量),并指定了相应的数据类型和约束条件。
- 同步商品模型到数据库
在main.ts
文件中,确保添加以下代码来同步商品模型到数据库(与之前同步用户模型类似):
import Product from './models/product.model';
async function syncModels() {
await sequelize.sync({ force: false });
console.log('模型同步成功');
}
syncModels();
运行项目后,数据库中将创建名为products
的表,用于存储商品信息。
二、创建商品管理组件
- 生成商品管理组件
使用命令行工具生成一个名为ProductManagement.vue
的组件:
vue generate component ProductManagement
- 编写商品管理组件模板
在ProductManagement.vue
的<template>
标签内,构建商品管理的用户界面。以下是一个简单的示例,包含商品列表展示、添加商品表单和操作按钮:
<template>
<div class="product-management-container">
<h2>商品管理</h2>
<!-- 商品添加表单 -->
<form @submit.prevent="addProduct">
<label for="name">商品名称:</label>
<input type="text" id="name" v-model="newProduct.name" required />
<label for="description">商品描述:</label>
<textarea id="description" v-model="newProduct.description" required></textarea>
<label for="price">价格:</label>
<input type="number" step="0.01" id="price" v-model="newProduct.price" required />
<label for="quantity">库存数量:</label>
<input type="number" id="quantity" v-model="newProduct.quantity" required />
<button type="submit">添加商品</button>
</form>
<!-- 商品列表 -->
<ul>
<li v-for="product in products" :key="product.id">
{{ product.name }} - {{ product.price }}元 - 库存: {{ product.quantity }}
<button @click="editProduct(product)">编辑</button>
<button @click="deleteProduct(product.id)">删除</button>
</li>
</ul>
</div>
</template>
在这个模板中,我们使用v-for
指令循环展示商品列表,每个商品项显示名称、价格、库存数量以及编辑和删除按钮。同时,提供了一个添加商品的表单,用于输入新商品的信息。
- 编写商品管理组件逻辑
在<script lang="ts">
标签内,编写商品管理组件的逻辑代码。首先,导入必要的依赖,包括axios
和Product
模型:
import axios from 'axios';
import Product from '@/models/product.model';
export default {
name: 'ProductManagement',
data() {
return {
products: [] as Product[],
newProduct: {
name: '',
description: '',
price: 0,
quantity: 0
}
};
},
methods: {
// 获取商品列表
async getProducts() {
try {
const response = await axios.get('/api/products');
this.products = response.data;
} catch (error) {
console.error('获取商品列表失败:', error);
}
},
// 添加商品
async addProduct() {
try {
const productToAdd: Product = {
name: this.newProduct.name,
description: this.newProduct.description,
price: this.newProduct.price,
quantity: this.newProduct.quantity
};
await axios.post('/api/products', productToAdd);
this.newProduct = {
name: '',
description: '',
price: 0,
quantity: 0
};
this.getProducts();
} catch (error) {
console.error('添加商品失败:', error);
}
},
// 编辑商品(这里可以根据需求进一步实现编辑功能,目前只简单打印商品信息)
editProduct(product: Product) {
console.log('编辑商品:', product);
},
// 删除商品
async deleteProduct(productId: number) {
try {
await axios.delete(`/api/products/${productId}`);
this.getProducts();
} catch (error) {
console.error('删除商品失败:', error);
}
}
},
mounted() {
this.getProducts();
}
};
在mounted
生命周期钩子中,调用getProducts
方法获取初始的商品列表。getProducts
方法使用axios.get
请求后端的/api/products
接口获取商品数据,并将其赋值给products
数组,用于在前端展示。addProduct
方法用于添加新商品,将用户输入的商品信息组成Product
对象,发送axios.post
请求到后端添加商品,添加成功后清空表单并重新获取商品列表。editProduct
方法目前只是简单打印商品信息,后续可以根据需求完善编辑功能。deleteProduct
方法根据商品id
发送axios.delete
请求到后端删除商品,删除成功后重新获取商品列表。
三、后端API实现(商品相关操作)
创建商品API路由文件
在后端的routes
文件夹中创建product.routes.js
文件,用于定义商品相关的API路由。实现获取商品列表路由
在product.routes.js
文件中,编写获取商品列表路由的处理逻辑:
const express = require('express');
const router = express.Router();
const Product = require('../models/product.model');
router.get('/products', async (req, res) => {
try {
const products = await Product.findAll();
res.status(200).json(products);
} catch (error) {
console.error('获取商品列表失败:', error);
res.status(500).json({ message: '获取商品列表失败,请稍后重试' });
}
});
这个路由处理函数使用Product.findAll
方法从数据库中查询所有商品记录,并将结果以JSON格式返回给前端。
- 实现添加商品路由
继续在product.routes.js
文件中编写添加商品路由的处理逻辑:
router.post('/products', async (req, res) => {
try {
const { name, description, price, quantity } = req.body;
const newProduct = await Product.create({
name,
description,
price,
quantity
});
res.status(201).json(newProduct);
} catch (error) {
console.error('添加商品失败:', error);
res.status(500).json({ message: '添加商品失败,请稍后重试' });
}
});
从请求体中获取商品信息,使用Product.create
方法创建新的商品记录并保存到数据库中,然后将新创建的商品对象返回给前端。
- 实现删除商品路由
在product.routes.js
文件中添加删除商品路由的处理逻辑:
router.delete('/products/:id', async (req, res) => {
try {
const productId = req.params.id;
const result = await Product.destroy({ where: { id: productId } });
if (result === 0) {
return res.status(404).json({ message: '商品不存在' });
}
res.status(204).send();
} catch (error) {
console.error('删除商品失败:', error);
res.status(500).json({ message: '删除商品失败,请稍后重试' });
}
});
根据请求参数中的商品id
,使用Product.destroy
方法从数据库中删除对应的商品记录。如果删除的行数为0,表示商品不存在,返回相应的状态码和消息;否则,返回成功删除的状态码(204表示无内容返回)。
- 注册商品路由到应用程序
在后端应用程序的入口文件(如app.js
或index.js
)中,将product.routes.js
文件中定义的路由注册到应用程序中:
const productRoutes = require('./routes/product.routes');
app.use('/api', productRoutes);
通过以上步骤,我们实现了一个简单的商品管理系统,包括商品数据模型的定义、前端商品管理组件的创建以及后端API的实现。用户可以在前端添加、查看、编辑(部分功能待完善)和删除商品,数据通过与MySQL数据库的交互进行持久化存储。在后续的实战示例中,我们可以进一步优化这个系统,例如添加商品图片上传、搜索功能、权限控制等,使其更加完善和实用。希望本示例对你在Vue + TS + MySQL项目开发中的学习有所帮助,如果你有任何疑问或建议,欢迎在评论区留言。