【纯干货】Vue仿蘑菇街商城项目(vue+koa+mongodb)
(给前端大学加星标,提升前端技能.)
https://juejin.im/post/5e6e088ff265da57434bd2b1
1背景介绍
大家好,我是六六。学习了很长时间,为此想做一个项目来锻炼一下自己,于是便看上了蘑菇街(有很多漂亮的衣服和美女哈哈哈)。所以打算从零仿照蘑菇街官网来做一个项目,现在项目终于上线了。对于项目有任何问题或者建议都可以评论,我欢迎大家来提意见。
2项目介绍
登录,登出功能
注册功能
商品展示功能
用户搜索功能
用户收藏功能
购物车功能
订单功能
个人中心
更换头像
商家聊天
开发问题
部署问题
项目优化
3.登录注册模块
需求分析:
完成用户登录,用户注册,注册信息保存于数据库。
前端vue页面绘制,使用axios完成数据请求,使用koa搭建服务器,采用token验证机制,采用mongodb数据库,使用bcryptjs对密码加密
性能分析:
使用慢网速测试,检查一处问题,已解决。在10.2处
4.商品展示功能
需求分析:
展示推荐商品,以及具体的每个商品。
技术分析:
通过动态路由进行传参。商品列表下拉加载更多,借助了插件。
展示图:
5.用户搜索模块
需求分析:
完成用户搜索商品功能,并可以对搜索物品按需求展示。并保存搜索记录。
技术分析:
通过路由传参到组件,组件在通过参数进行网络请求加载处对应的商品。
6.用户收藏功能
需求分析:
完成对商品收藏与取消收藏功能。
技术分析:
在每个用户中有一个user_collect属性保存着一个数组,收藏时需要将商品id添加到这个数组中即可。每次进入商品时,遍历这个数组判断是否有这个id,有就添加样式。取消收藏从数组中删除即可。
7.购物车功能
需求分析:
添加商品进入购物车,在购物车中进行选择并加入订单。
技术分析:
添加商品保存到数据库中,购物车页面在通过网络请求获取购物车数据。
9.订单功能
需求分析:
展示:
10.个人中心
需求分析:
可以从个人中心中查到我们订单的情况。
展示:
11.更换头像
需求分析:
实现用户的上传头像,和自定义裁剪
技术分析:
采用canvas技术进行裁剪,并通过FormData上传图片到服务器。
效果图:
问题:
实现了裁剪,但是大小不是自定义的,在以后逐渐改善。
12.商家聊天
需求分析:
实现用户与商家的沟通,商家有一个列表记录所有聊天用户。
技术分析:
采用socket.io实现通信。vue组件采用bus总线通信。
效果图:
问题:
组件内的数据保存在组件内,一刷新就没有了。应该在每次组件销毁保存到服务器里
input输入框的高度应该随输入文字的增多而变高,列表中的聊天记录同理。
没有消息提醒功能
13. 开发遇到的问题
13.1:
使用koa写中间件的时候,一定要使用异步。
13.2 网速过慢error:
当网速过慢时,无法进行注册,点击注册无任何反应:
分析:由于网速过慢,在进行账号重复验证时,没有通过验证则已经点击注册了,而此时账号通过判定变量仍为false,即使已满足却因为条件不够无法注册。
if (this.isAccount && this.isPassword) {......} //通过条件,进行网络请求
解决:声明一个变量isClick,判断符合这种情况下,为true,在账号重复性网络请求成功后,重新发送一次注册。
13.3:重新刷新error:
当遇到页面刷新时,页面加载报错
分析:有些数据是通过其他组件传入的,重新刷新导致无数据加载报错。
解决:
通过对数据判断,如果没有数据通过路由直接返回首页。
特定的数据可以通过网络请求解决。
13.4:重新刷新error
判断一个空对象 分析:聊天组件刷新时,由于数据时通过组件传参进入,如果刷新导致数据丢失,数据和视图会报错,判断this.$route.params是否为空对象即可 解决:
isEmptyObj (obj) {
return (Object.prototype.toString.call(obj) === '[object Object]')
&& (Object.getOwnPropertyNames(obj).length === 0)
&& (Object.getOwnPropertySymbols(obj).length === 0)
}
13.5:vue渲染问题:
我用一个对象存储聊天记录,对象名为用户名,对象值为一个数组,数组每一项为每一句聊天的记录.
chatUsers: {
'小李': [{ 'msg': 'obj' }, { 'msg': '你好啊' }],
'小张': [{ 'msg': 'obj' }, { 'msg': '你好啊' }]
}
需求是:要获取每个用户的最后一句聊天记录,并显示。所以很容易用到v-for。
<!-- 聊天列表 -->
<ul>
<li v-for='(item,index) in chatUsers'
:key='index'>{{item[item.length-1]['msg']}}</li>
</ul>
报错:
分析:根据报错原因大概是render渲染出错,但是逻辑是没有问题的啊,就是拿不到msg这个属性。
解决:所以我换了一个思路,设置一个对象,用来存储最后一句聊天记录就可以了。
// 最后聊天信息
chatLastMsg: {
}
// 将这个对象的属性设为响应式
handleMsg (msg) {
if (!this.chatUsers[msg.name]) {
this.$set(this.chatUsers, msg.name, [])
this.$set(this.chatLastMsg, msg.name, '')
}
//每次传入消息都赋值给这个对象,也就是最后一次消息了
this.chatLastMsg[msg.name] = msg.msg
13.6数据请求报错:
找到问题代码:
this.shop = Object.keys(this.cartList)
分析:在打开购物车页面时,需要进行请求,但是当购物车为空时,请求回来的数据使this.cartList
为undefined,导致报错。
解决:
this.cartList? this.shop = Object.keys(this.cartList):this.shop=[]
14.部署问题
14.1上传图片路径:
分析:在本地开发时,保存图片路劲和上传服务端是不一样的,需要改为真实路径。
14.2本地数据库导入服务器数据库:
问题:导入成功后,服务器端会重新创建一个集合,并不会使用我导入的集合。我导入的数据就无法使用。
解决:从服务器端重新创建集合,并将本地数据导入集合内就可以使用了。
15.性能优化
优化前:大概加载出来需要7秒左右,可谓是相当可怕的。核心资源为600kb左右。
1.引入cdn
单文件从600kb压缩到300kb了
2.启用gzip压缩。
单文件从300kb压缩到90kb了,加载时间也减少到1.5s左右了。(有缓存因素影响)
3.路由懒加载
资源懒加载,被访问时才会被加载对应的js模块,而不是第一次加载所有资源
第一次加载核心资源从90kb变成48kb了。
4.属性不再响应式:待完成
5.图片压缩
在检验项目的时候发现了一个大问题,看图:
在进行登录验证的时候发现加载这些图片要8s左右,所以必须进行压缩,进行适当的分辨率调整。
进行压缩之后图片加载都能稳定在100ms之内,大大提升了用户体验。
16.总结
这是我学习以来,第一次从0搭建一个,从vue框架到服务器端,再到数据库。在过程中,遇到了很多问题,不过最终都克服了他们。遇到问题不可怕,因为问题都是要被解决的。
分享前端好文,点亮 在看