PC端网上购物商城
前言
本人前端爱好者 ,因为项目需要用到前端的技术(主要是vue),自己自学了一段时间,在空闲之余的时间终于自己完完整整写下来一整个前后端商城项目
项目采用的技术栈是基于:vue + node + mySQL,用vue-cli写的前端,用node-express搭建的后端应用服务器,数据库用的是MySQL。
一、项目整体效果预览
1. web端-项目部分效果演示
商城前台部分
(1)首页
(2)商品倒计时模块
(3)右侧隐藏小购物车(未登录时的情况)(4)登录注册模块 (支持验证码登录)
![](https://img-blog.csdnimg.cn/88a5f1363f4f46edb2299ec4156fe9e9.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5rWp6aKc,size_20,color_FFFFFF,t_70,g_se,x_16)![](https://img-blog.csdnimg.cn/0402db485bbb465781a3ebf6c6fc1fa4.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5rWp6aKc,size_20,color_FFFFFF,t_70,g_se,x_16)
(5)商品详情页
这里做了放大镜效果
(6)商品分类
(7)客服系统前后台界面
初次之外对商城背景音乐,搜索,优惠卷等功能进行二次改进添加
其他前台功能尚未展示完全(包括商品评论,购物车,订单模块等等)(具体见项目源码)
商城后台部分(完整版)
本商城项目中加入了站内搜索功能(闲着无聊)
2. 服务器端
服务器端我主要用的是Node的express框架搭建的应用服务器, 自己定义了项目中需要的接口, 主要基于post/get。服务器端没有进行深度的开发,主要实现了对数据流的增删改查,为客户端进行动态数据支撑。
二、功能
普通用户
- 注册、登录(图形验证码)
- 定位 (腾讯地图定位功能)、自主选择所在城市
- 在线搜索引擎
- 客服聊天
- 商品分类
- 简单展示商品
- 查看商品详情
- 商品评论
- 分页功能
- 购物车功能
- 加入购物车
- 购物车商品数量增减
- 清空购物车
- 商品结算
- 多关键词模糊搜索商品 (关键词需为商品名称)
- 用户个人中心
- 修改用户信息 (头像、昵称、简介…)
- 修改手机号
- 修改密码
管理员
- 登录(固定账号密码)
- 查看数据库商品信息
- 商品上架(添加商品)
- 删除/修改商品
- 分页功能
三、项目开发中坑点记录
虽然是跟着视频一步步学习的,但是自己在动手做的时候还是遇到了各种奇葩问题,在写完项目后总结记录下,一方面方便自己回顾,另一方面其他朋友遇到类似的问题可以参考借鉴。
1.1 二级路由界面底部Tabbar隐藏
通过vue-router配置完全局路由后, 在项目中一级路由界面是需要有底部tabbar的, 但是由一级界面过渡到二级界面是不需要的
解决方案: 在路由选中有个meta属性, 可以在该属性中传一个字面量对象记录是否显示底部的tabbar, 然后在页面中做判断即可!
1.2 坑坑坑的跨域
问题描述: 主要是前端请求图形验证码引发的血案,因为我服务器的地址是localhost:3000,
但是问题在于:我在服务器端是用session保存了该验证码,用于前端请求时来做前后端比对的,但是每次请求都不能从session中获取,始终的undefined。此刻,我第一反应是跨域,检查前端页面没有问题,于是检查后端的跨域配置:
也没有问题,百思不得其解后只能灰溜溜的去问老师,最终的问题在于:我客户端的其他请求都是统一配置好的路径:http://localhost:3000, 但在请求图形验证码出使用了:http://127.0.0.1:3000/api/captcha ,在后端验证是localhost:3000和127.0.0.1:3000代表的不是同一个客户端,所以始终拿不到值,改了之后瞬间好了。非常小的一个细节,粗心、粗心!
1.3 配置vuex中的细节点分析
一开始不是很理解为什么要绕这一圈来使用vuex进行状态和数据的管理,当使用了之后才发现中大型项目中使用vuex进行数据管理是十分有必要的,当你理解了它的运作机制,流程就显得异常简单了
使用vuex进行状态管理要注意的一些细节点:
如果项目比较大,一定要把state,action,mutation划分成独立的文件夹,这样以后在进行状
action向mutation直接commit数据的时候,要注意参数保持一致,否则会出错,如下图所示:
在请求网络数据时,一定要在action中处理,主要是通过async和await进行异步和同步,mutation中因为是唯一修改state的地方,所以始终得是同步的
vuex中大致要注意的细节差不多就这些,其它的都是按照固定流程处理即可。
1.4 node连接MySQL数据丢失
问题描述:第一次发起请求的时候,连接数据库都是正常的;但是第二个接口发起请求时,数据库就连接不上了,会报错说连接丢失。
原因分析:因为每操作完一次数据库就关闭了数据库连接,再次访问的时候就找不到连接了,但是连接又不能不关闭,问题在于我把连接数据库的代码没有放到db.query的函数中,而是放在外面,这样就导致连接只生成一次,关闭了以后,第二请求时得不到连接。
解决方案:直接写好一个数据库连接文件,用 module.exports = conn;输出,这样每次访问都是一个新的请求。
1.5 node连接mysql数据池一定要释放
使用node连接mysql进行数据交互一定要释放数据池,不然请求几次之后会出现“一直请求中”的状态导致无法完成交互
1.6 页面刷新后vuex中状态被清空
- 解决方案1:localStorage 使用localStorage进行数据本地化,但电商类型的项目我感觉并不是太适合,因为localStorage是长时间缓存,有可能导致数据不同步。
- 解决方案二:判断数据是否存在,不存在重新从服务器端获取,或者可以进行路由懒加载保持数据在内存中也是可以的。
1.8 nextTick的使用
问题描述:在使用自定义组件的时候,或者使用第三方的组件(轮播图等),因为数据是异步获取的,所以组件初始化会在数据获取之前完成,此时可能导致组件无法正常工作,就拿轮播图举例子,正确的写法是在watch中进行深度监视,当数据请求完成后进行组件的初始化:
当然也可以通过回调来处理,主要目的是延迟初始化,这样组件就能正常运转了。
nextTick主要作用在于将回调延迟到下次 DOM 更新循环之后执行;
在修改数据之后立即使用它,然后等待 DOM 更新;
它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。
运行 项目后端服务器是基于node、MySQL开发,运行前请确认系统已安装相关应用
服务器端
cd web-server
将web-server文件夹下的shop.sql导入MySQL数据库中
npm install 安装依赖
修改web-server/src/config.js文件,此文件记录项目的全局变量,在文件中找到password、database、user属性,根据你的数据库信息修改它们的值
npm run dev 在本地运行,启动服务器
客户端
cd web-client
npm install 安装依赖
npm run dev 在本地运行
接着就可以在http://localhost:8080下访问到该项目
三、目录结构
web-client 前端部分:
├── build // 构建相关
├── config // 配置相关
├── src // 源代码
│ ├── api
│ | ├── ajax.js // 使用axios,封装ajax
│ | ├── index.js // 后端接口,封装请求接口
│ ├── common // 字体、图片等静态资源
│ ├── components // 全局公用组件
│ ├── config // 全局配置
│ | ├── filters.js // 全局过滤器
│ | ├── utils.js // 全局方法
│ | ├── area.js // 全国城市区域,配合element-ui级联选择器
│ ├── pages // 项目视图页面
│ ├── router // 路由配置
│ ├── store // Vuex数据存储器
│ ├── App.vue // 入口页面
│ ├── main.js // 入口文件
├── static // 静态资源
├── .babelrc // babel-loader 配置
├── .gitignore // git 忽略
├── index.html // 项目html
└── package.json // 包依赖配置
web-server 后端部分:
├── db // MySQL数据连接
├── public // 静态资源
├── routes // 后端路由,项目接口
├── static // 静态资源
├── src // 源代码
│ ├── app.js // 项目入口文件,配置,初始化
│ ├── config.js // 全局公用参数记录
├── utils // 全局公用方法
├── views // 视图页面
├── .babelrc // babel-loader 配置
├── main.js // 入口文件
├── package.json // 包依赖配置
├── README.md // 项目说明文件
└── shop.sql // 注入MySQL的sql语句
四、开发中的一些细节
跨域问题
后端部分使用cors来解决跨域
cd web-server
npm i -S cors
// 在 web-server/src/app.js 中引入
import cors from 'cors'
app.use(cors());
前端部分进行跨域配置
// 在 web-client/config/index.js 中进行配置
proxyTable: {
'/api': { //使'api'代替服务器地址
target: 'http://127.0.0.1:3000/', //源地址
changeOrigin: true, //改变源
pathRewrite: {
'^/api': '' //路径重写
}
},
},
按需加载组件(优化首屏加载速度)
路由懒加载
// web-client/src/router/index.js 示例
const Home = ()=> import('./../pages/Home/Home');
routes: [
{
path: '/home',
component: Home
},
]
前台页面顶部搜索区的显示和隐藏
通常在购物商城中,会发现页面顶部会实现搜索框,考虑到它在多个页面都会出现,于是封装成全局组件,即 src\components\HeaderSearch\HeaderSearch.vue 并在App.vue中引入
然后问题出现了,有些页面其实并不需要出现搜索框,比如商品详情页、登录/注册…于是决定在router内动态设置meta,来控制全局组件的显示和隐藏
// 在 router\index.js 中设置mate 示例
routes: [
{
path: '/home',
component: Home,
// true 代表该路由页面显示相关的全局组件
meta: {showHeaderTop: true, showHeaderSearch: true}
},
]
// 在 App.vue 中根据 mate 控制组件显示与隐藏
<template>
<HeaderTop v-show="$route.meta.showHeaderTop"/>
<HeaderSearch v-show="$route.meta.showHeaderSearch"/>
<keep-alive>
<router-view></router-view>
</keep-alive>
</template>
插值表达式
在Vue中,我们通常使用{undefined{data}}插值表达式来页面取值,但是遇到需要异步请求获取数据后,再渲染到页面上时,实际上,页面渲染时会先显示数据的初始值,请求得到数据后,才会正常显示。所以有些三级表达式刚开始加载,得不到数据会报错。此时,可以结合v-if解决,在明确得到数据后,再渲染元素
封装Node与MySQL连接
可以新建一个db\db.js文件,里面放数据库连接的代码,最后用export default conn;输出conn,这样在项目中操作数据库时,只需要连接一次即可,提升效率
import mysql from 'mysql'
import config from '../src/config'
const conn = mysql.createConnection({
host: config.host, // 数据库的地址
user: config.user, // 账号
password: config.password, // 密码
database: config.database, // 数据库名称
multipleStatements: true, // 允许多条sql同时查询
});
conn.connect();
export default conn;
四、结束语
- 还有很多后端服务器开发的坑,项目的深层次优化,放到下篇来写。
- 较少写技术文章,不足之处请多多指教! ---## 对本文章及项目完整项目源码感兴趣的小伙伴可以点赞+收藏,留下你们的鼓励支持!后续我也会把项目上线到github.
- 需要项目的可以私聊博主,谢谢支持
版权归原作者 技术原猴 所有, 如有侵权,请联系我们删除。