商城后台管理系统 06 商品列表-动态数据

在 vue-ego 文件夹下创建 server/index.js 文件 用来写服务器接口,并且在 vue-ego 下安装如下依赖
复制代码
code\vue-ego>npm i express -S

code\vue-ego>npm i mysql -S
启动server服务 node index.js
复制代码
code\vue-ego\server> node index.js
8989
访问 http://localhost:8989/api 看到 'hello' 表示后端服务搭建成功
商品列表-动态数据 实现代码如下
复制代码
​

1, src/views/Goods/Goods.vue
<template>
	<div class="goods">
		<!-- 1,搜索区域 -->
		<div class="header">
			<el-input v-model="input" placeholder="请输入内容"></el-input>
			<el-button type="primary">查询</el-button>
			<el-button type="primary">添加</el-button>
		</div>
		<!-- 2, 表格区域 展示视图数据  @selection-change="handleSelectionChange"-->
		<div class="wrapper">
			<el-table :data="tableData" border>
				<el-table-column type="selection" width="55">
				</el-table-column>
				<el-table-column prop="id" label="商品ID" width="100">
				</el-table-column>
				<el-table-column prop="title" label="商品名称" width="100" show-overflow-tooltip>
				</el-table-column>
				<el-table-column prop="price" label="商品价格" width="100">
				</el-table-column>
				<el-table-column prop="num" label="商品数量" width="100">
				</el-table-column>
				<el-table-column prop="category" label="规格类目" width="100">
				</el-table-column>
				<el-table-column prop="image" label="商品图片" show-overflow-tooltip>
				</el-table-column>
				<el-table-column prop="sellPoint" label="商品卖点" show-overflow-tooltip>
				</el-table-column>
				<el-table-column prop="descs" label="商品描述" show-overflow-tooltip>
				</el-table-column>
				<el-table-column label="操作" width="180">
					<template slot-scope="scope">
						<el-button size="mini" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
						<el-button size="mini" type="danger"
							@click="handleDelete(scope.$index, scope.row)">删除</el-button>
					</template>
				</el-table-column>
			</el-table>
		</div>

		<!-- 3, 分页展示 -->
		<div class="pagination">
			<MyPagination :total="total" :page-size="pageSize" @changePage="changePage" />
		</div>
	</div>
</template>

<script>
	import MyPagination from '@/components/MyPagination.vue'
	export default {
		data() {
			return {
				// 声明变量
				input: '',
				tableData: [],
				total: 10,
				pageSize: 1

				// tableData: [{
				// 	date: '2016-05-02',
				// 	name: '王小虎',
				// 	address: '上海市普陀区金沙江路 1518 弄'
				// }]
			}
		},
		methods: {
			// 分页的页码
			changePage(num) {
				this.http(num);
			},
			// 编辑操作
			handleEdit(index, row) {
				console.log(index, row);
			},
			// 删除操作
			handleDelete(index, row) {
				console.log(index, row);
			},
			// // 选择数据
			// handleSelectionChange(val) {
			// 	// this.multipleSelection = val;
			// },
			// 商品列表的获取 结构赋值
			http(page) {
				this.$api.getGoodsList({
					page,
				}).then((res) => {
					console.log(res.data);
					if (res.data.status === 200) {
						// 数据列表
						this.tableData = res.data.data;
						this.total = res.data.total;
						this.pageSize = res.data.pageSize;
					}
				});
			},
		},
		// 生命周期函数
		created() {
			this.http(1)
		},
		components: {
			MyPagination
		},
	};
</script>

<style lang="less" scoped>
	.goods {
		margin: 20px;
	}

	.header {
		display: flex;

		button {
			margin-left: 20px;
		}
	}

	.wrapper {
		margin: 20px 0;
	}

	// .pagination {
	// 	text-align: center;
	// 	margin: 20px;
	// }
</style>






2, src/views/Layout/Mymenu.vue
<template>
	<div>
		<el-menu :default-active="$route.path" class="el-menu-vertical-demo" background-color="#545c64"
			text-color="#fff" active-text-color="#ffd04b" router :collapse="isCollapse">
			<el-menu-item>
				<i class="iconfont icon-icon_nav" style="color: skyblue;padding-right: 6px;font-size: 24px;"></i>
				<span slot="title">易购后台管理系统</span>
			</el-menu-item>
			<el-menu-item index="/">
				<i class="el-icon-menu"></i>
				<span slot="title">首页</span>
			</el-menu-item>
			<el-menu-item index="/goods">
				<i class="el-icon-document"></i>
				<span slot="title">商品管理</span>
			</el-menu-item>
			<el-menu-item index="/params">
				<i class="el-icon-setting"></i>
				<span slot="title">规格参数</span>
			</el-menu-item>
			<el-menu-item index="/advert">
				<i class="el-icon-setting"></i>
				<span slot="title">广告分类</span>
			</el-menu-item>
			<el-menu-item index="/my">
				<i class="el-icon-setting"></i>
				<span slot="title">个人中心</span>
			</el-menu-item>
			<el-menu-item index="/logistics">
				<i class="el-icon-setting"></i>
				<span slot="title">物流管理</span>
			</el-menu-item>
			<el-submenu index="/order">
				<template slot="title">
					<i class="el-icon-location"></i>
					<span>订单管理</span>
				</template>
				<el-menu-item-group>
					<template slot="title">订单</template>
					<el-menu-item index="/order/order-list">
						<i class="el-icon-document"></i>
						<span>订单列表</span>
					</el-menu-item>
					<el-menu-item index="/order/order-back">
						<i class="el-icon-setting"></i>
						<span>退货管理</span>
					</el-menu-item>
				</el-menu-item-group>
				<el-menu-item-group>
					<template slot="title">分组一</template>
					<el-menu-item index="5-3">选项1</el-menu-item>
					<el-menu-item index="5-4">选项2</el-menu-item>
				</el-menu-item-group>
				<el-menu-item-group title="分组2">
					<el-menu-item index="5-5">选项3</el-menu-item>
				</el-menu-item-group>
				<el-submenu index="1-4">
					<template slot="title">选项4</template>
					<el-menu-item index="1-4-1">选项1</el-menu-item>
				</el-submenu>
			</el-submenu>
		</el-menu>
	</div>
</template>

<script>
	export default {
		// 子组件Mymenu接收父组件(index)传递过来的数据
		props: ['isCollapse'],
		data() {
			return {
				// isCollapse: false
			}
		}
	}
</script>

<style lang="less" scoped>
	.el-menu {
		border-right: 0;

		.is-active {
			background: #054476 !important;
			color: #fff !important;
		}
	}

	.el-menu-vertical-demo:not(.el-menu--collapse) {
		width: 200px;
		min-height: 400px;
	}
</style>





3, src/components/MyPagination.vue
<template>
	<div style="text-align: center;margin: 20px;">
		<el-pagination background layout="total,prev, pager, next,jumper" :total="total" :page-size="pageSize"
			@current-change="changePage">
		</el-pagination>
	</div>
</template>

<script>
	export default {
		props: {
			// 接收
			total: {
				type: Number,
				default: 100
			},
			pageSize: {
				type: Number,
				default: 10
			}
		},
		methods: {
			changePage(page) {
				this.$emit('changePage', page)
			}
		}
	}
</script>

<style>
</style>






4, src/api/base.js
/**
 * 接口的路径配置:
 * 一般文件目录: base.js index.js
 * 	base.js : 放所有路径的配置
 *  index.js: 放所有请求的方法
 */

const base = {
	goodsList: '/api/api/projectList', // 商品列表
}

export default base;






5, src/api/index.js
/**
 * 所有请求的方法
 */

import axios from "axios";
import base from "./base";
const api = {
	/**
	 * 商品列表
	 */
	getGoodsList(params) { // {page:xx}
		return axios.get(base.goodsList, {
			params
		});
	}
}

export default api;






6, main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import '@/plugins/element.js'
import '@/assets/css/reset.css'
import '@/assets/css/iconfont.css'

// 挂载 api 
import api from './api/index.js'
Vue.prototype.$api = api;

Vue.config.productionTip = false

new Vue({
	router,
	store,
	render: function(h) {
		return h(App)
	}
}).$mount('#app')






7, vue.config.js
// 配置参数
/**
* devServer.proxy
* 如果你的前端和后端 API 服务器没有运行在同一个主机上,你需要在开发环境下降 API 请求* 做跨域处理
*/
module.exports = {
	devServer: {
		proxy: {
			'/api': {
				target: 'http://localhost:8989',
				ws: true,
				changeOrigin: true,
				pathRewrite: {	// 重写路径
					'^/api': ''
				}
			}
		}
	}
}





8, server/index.js
// 搭建 express 服务
const express = require('express')

const app = express()

// 导入路由
const router = require('./router.js')
app.use('/api', router)

app.listen(8989, () => {
	console.log(8989);
})






9, server/mysql.js
// 连接数据库 1,安装mysql 2, 创建连接
const mysql = require('mysql')

// 创建数据库连接
const client = mysql.createConnection({
	host: 'localhost', // 数据域名 地址
	user: 'zengguoqing', // 数据库用户名称
	password: 'zengguoqing', // 数据库密码 xampp 集成
	database: 'vue_ego'
})

// 封装数据库操作语句 sql语句 参数数组 arr callback 成功函数结果
function sqlFn(sql, arr, callback) {
	client.query(sql, arr, function(error, result) {
		if (error) {
			console.log('数据库语句错误');
			return;
		}
		callback(result);
	})
}

module.exports = sqlFn;





10, server/router.js
const express = require('express')
const router = express.Router()

// token 
// const jwt = require('jsonwebtoken')

// 秘钥
// const config = require('./secert.js')

// 导入数据库 sqlFn('sql',[],res=>{})
const sqlFn = require('./mysql.js')

// 图片上传支持的模块
// const multer = require('multer')
// const fs = require('fs')


// 测试接口
// router.get('/', (req, res) => {
// 	res.send('hello')
// })

// 路由接口

// 登录接口
/**
 * 语法
 * 如 60,'2 day','10h','7d',expiration time 过期时间
 * jwt.sign({},'秘钥','过期时间',{expiresIn: 20*1,'1 day','1h'})
 */
/**
 * 登录 login
 */
// router.post('/login', (req, res) => {
// 	//
// })

/**
 * 注册接口 /register
 */
// router.post('/register', (req, res) => {
// 	//
// })

/**
 * 商品列表:获取分页 {total: '',arr:[{},{},{}],pagesize:8,}
 * 参数:page 页码
 */
router.get('/projectList', (req, res) => {
	// 接收页码 可以不传 默认为1
	const page = req.query.page || 1;
	// 根据 id 去查 project 表
	const sqlLen = "select * from project where id";

	sqlFn(sqlLen, null, data => {
		let len = data.length;
		const sql = "select * from project order by id desc limit 8 offset" + (page - 1) * 8;
		sqlFn(sql, null, result => {
			if (result.length > 0) {
				// 返回数据
				res.send({
					status: 200,
					data: result,
					pageSize: 8,
					total: len
				})
			} else {
				// 返回数据
				res.send({
					status: 500,
					msg: "暂无数据"
				})
			}
		})
	})
})


/**
 * 商品查询接口 search
 * 参数: search
 */
router.get("/search", (req, res) => {
	var search = req.query.search;
	const sql = "select * from project where concat(`title`,`sellPoint`,`descs`) like '%'" + search
	sqlFn(sql, null, (result) => {
		if (result.length > 0) {
			res.send({
				status: 200,
				data: result
			})
		} else {
			res.send({
				status: 500,
				msg: '暂无数据'
			})
		}
	})
})


/**
 * 类目选择
 * 接口说明:接口不同的参数 cid 返回不同的类目数据后台接受变量 id
 */
router.get("/backend/itemCategory/selectItemCategoryByParentId", (req, res) => {
	//
	const id = req.query.id || 1;
	const sql = "select * from category where id = ?"
	var arr = [id];
	sqlFn(sql, arr, result => {
		if (result.length > 0) {
			res.send({
				status: 200,
			})
		}
	})
})


module.exports = router

[点击并拖拽以移动]
​

后台数据库返回数据

src/api/index.js

复制代码
/**
 * 所有请求的方法
 */

import axios from "axios";
import base from "./base";
const api = {
	/**
	 * 商品列表
	 */
	getGoodsList(params) { // {page:xx}
		return axios.get(base.goodsList, {
			params
		});
	}
}

export default api;
配置 vue.config.js 跨域
复制代码
// 配置参数
/**
* devServer.proxy
* 如果你的前端和后端 API 服务器没有运行在同一个主机上,你需要在开发环境下降 API 请求* 做跨域处理
*/
module.exports = {
	devServer: {
		proxy: {
			'/api': {
				target: 'http://localhost:8989',
				ws: true,
				changeOrigin: true,
				pathRewrite: {	// 重写路径
					'^/api': ''
				}
			}
		}
	}
}

商品列表:获取分页接口

复制代码
/**
 * 商品列表:获取分页 {total: '',arr:[{},{},{}],pagesize:8,}
 * 参数:page 页码
 */
router.get('/projectList', (req, res) => {
	const page = req.query.page || 1;
	const sqlLen = "select * from project where id";

	sqlFn(sqlLen, null, data => {
		let len = data.length;
		const sql = "select * from project order by id desc limit 8 offset" + (page - 1) * 8;
		sqlFn(sql, null, result => {
			if (result.length > 0) {
				// 返回数据
				res.send({
					status: 200,
					data: result,
					pageSize: 8,
					total: len
				})
			} else {
				// 返回数据
				res.send({
					status: 500,
					msg: "暂无数据"
				})
			}
		})
	})
})

商品查询接口

复制代码
/**
 * 商品查询接口 search
 * 参数: search
 */
router.get("/search", (req, res) => {
	var search = req.query.search;
	const sql = "select * from project where concat(`title`,`sellPoint`,`descs`) like '%'" + search
	sqlFn(sql, null, (result) => {
		if (result.length > 0) {
			res.send({
				status: 200,
				result
			})
		} else {
			res.send({
				status: 500,
				msg: '暂无数据'
			})
		}
	})
})
创建连接数据库操作数据库server/mysql.js文件
复制代码
// 连接数据库 1,安装mysql 2, 创建连接
const mysql = require('mysql')

// 创建数据库连接
const client = mysql.createConnection({
	host: 'localhost',	// 数据域名 地址
	user: 'zengguoqing', // 数据库用户名称
	password: 'zengguoqing', // 数据库密码 xampp 集成
	database: 'vue_ego'
})

// 封装数据库操作语句 sql语句 参数数组 arr callback 成功函数结果
function sqlFun(sql, arr, callback) {
	client.query(sql,err,function(error,result) {
		if (error) {
			console.log('数据库语句错误');
			return;
		}
		callback(result)
	})
}

module.exports = sqlFun

server/index.js 搭建后台服务器

复制代码
// 搭建 express 服务
const express = require('express')

const app = express()

// 导入路由
const router = require('./router.js')
app.use('/api', router)

app.listen(8989, () => {
	console.log(8989);
})

server/router.js

复制代码
const express = require('express')
const router = express.Router()

// 导入数据库 sqlFun('sql',[],res=>{})
const sqlFun = require('./mysql.js')

// 路由接口
router.get('/', (req, res) => {
	res.send('hello')
})

module.exports = router
相关推荐
前端西瓜哥5 小时前
平面几何:如何绘制一个星形?
前端
北辰alk5 小时前
Vue3 组件懒加载深度解析:从原理到极致优化的完整指南
vue.js
天天扭码5 小时前
解放双手!使用Cursor+Figma MCP 高效还原响应式设计稿
前端·mcp
今天不要写bug5 小时前
基于qrcode前端实现链接转二维码的生成与下载
前端·javascript·typescript·vue
JIngJaneIL6 小时前
基于Java + vue干洗店预约洗衣系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot
搬山境KL攻城狮6 小时前
记-SPA单页面应用Chrome自动翻译导致中文错别字问题
前端·chrome
HIT_Weston6 小时前
61、【Ubuntu】【Gitlab】拉出内网 Web 服务:Gitlab 配置审视(五)
前端·ubuntu·gitlab
剑小麟6 小时前
vue2项目中安装vant报错的解决办法
vue.js·java-ee·vue
旺仔Sec6 小时前
2026年度河北省职业院校技能竞赛“Web技术”(高职组)赛项竞赛任务
运维·服务器·前端
用户4099322502126 小时前
Vue的Class绑定对象语法如何让动态类名切换变得直观高效?
前端·ai编程·trae