基于Vue2、vant、vue-cookiesaxios技术实现瑞幸咖啡项目
目录
一、项目介绍
i、基本描述
ii、页面功能的实现
1、静态页面的实现
首页
搜索页
菜单页
购物袋页
我的页面
2、后端接口的请求
3、该项目使用到的技术栈
二、项目的业务实现流程
i、登录
ii、首页
iii、菜单页
iv、购物袋页面
v、我的
一、项目介绍
i、基本描述
本次项目以Vue2来进行开发,主要是后端为前端提供接口从而实现页面的数据渲染,该瑞幸咖啡应用APP由多个模块组成,包括商品展示、购物车、订单管理等,商品顾名思义是以咖啡类为主,满足了用户多种咖啡需求。
ii、页面功能的实现
1、静态页面的实现
首页
搜索页

商品详情页

菜单页

购物袋页

我的页面

还有个人资料、我的订单、我的收藏~等页面太多了,就没一一展示,下面详细简介会有相关截图进行展示。
2、后端接口的请求
本次项目所用的全部后端接口:后端接口
3、该项目使用到的技术栈
i、配置vant:npm i vant -S
安装按需引入vant组件插件:npm i babel-plugin-import --save-dev
在babel.config.js文件添加以下代码
module.exports = {presets: ['@vue/cli-plugin-babel/preset'],plugins: [['import', {libraryName: 'vant',libraryDirectory: 'es',style: true}, 'vant']]
}
在main.js写入以下代码
//导入vant框架的组件import { Button } from 'vant'//全局注册Vue.use(Button)//测试Button组件信息按钮
ii、配置axios:npm i axios vue-axios --save
在main.js引入一下代码
import axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, axios)
//将请求的路径和appkey存放在原型属性里
Vue.prototype.baseURL="http://www.kangliuyong.com:10002"
Vue.prototype.appkey="U2FsdGVkX19WSQ59Cg+Fj9jNZPxRC5y0xB1iV06BeNA="//请求拦截器axios.interceptors.request.use(config => {if (config.method === "post") {// 序列化 post 请求参数let paramsString = "";for (let key in config.data) {paramsString += `${key}=${config.data[key]}&`;}config.data = paramsString.slice(0, -1);}return config;});
iii、配置vue-cookies:https://www.jianshu.com/p/60c13168cc8f
安装:npm i vue-cookies --save
在main.js引入一下代码
import VueCookies from 'vue-cookies'
Vue.use(VueCookies)//设置cookie
//过期时间以秒为单位
//this.$cookies.set(键名, 值, 过期时间)
二、项目的业务实现流程
i、登录
在登录页面点击注册按钮会弹出注册框进行注册操作,注册手机号必须为唯一才并且密码必须为字母开头才能注册成功。
// 注册接口postRegister() {let self = this;let data = {appkey: self.appkey,nickName: self.registerInfo.name,password: self.registerInfo.password,phone: self.registerInfo.phone};postRegister(data).then(res => {this.$toast({message: res.data.msg,forbidClick: true,duration: 1000});}).catch(err => {console.log(err);});},
实现效果图如下:

登录怎么实现的?
前后端分离, 使用token验证登录
前端后端混合,服务器生成一个session(会话), 服务器返回一个sessionId给前端,前端使用cookie将sessionId保存,后面每次访问有关于用户信息的页面,都必须携带sessionId到后台验证,如果验证通过,则允许访问,否则直接拦截。
token是一个加密字符串
前端使用一个正确的账号和密码跟服务器换取一个合法token,服务器将token返回给前端,前端将token保存在cookie或者本地存储,后面每次访问有关于用户信息的页面,都必须携带token到后台验证,如果验证通过,则允许访问,否则直接拦截。
postLogin(data).then((res) => {if (res.data.code === 200) {this.$cookies.set("tokenString", res.data.token, "1d");this.$router.push("/");}this.$toast({message: res.data.msg,forbidClick: true,duration: 1000,});})
登录后怎么存储数据的?(如何保持登录状态)
keep-alive: 保持失活的路由组件状态, 如果访问过的路由组件,则再次访问时,不会触发组件的生命周期钩子。
ii、首页
通过静态页面可以看到首页分为搜索栏、轮播图、热卖推荐列表
搜索栏又分为左边显示的时间、用户名,右边显示搜索框组件
时间使用以下代码进行实现
computed: {// 当前时间ourTime() {let currentHour = new Date().getHours();return currentHour >= 6 && currentHour <= 12? "早上好": 12 < currentHour && currentHour < 18? "下午好": currentHour >= 18 && currentHour <= 24? "晚上好": "深夜好";},},
用户名使用三元运算符进行判断渲染,如下代码:
{{ myList.nickName === "" ? "Allen" : myList.nickName }}
在data(){return}中定义一个存储用户名的myList空数组,然后在methods中的初始化init(){}中定义let self =this;其中postFindMy是我的接口,如下代码:
// 我的接口let my = {tokenString: this.$cookies.get("tokenString"),};postFindMy(my).then((res) => {if (res.data.code === "A001") {self.myList = res.data.result[0];}});
搜索框通过引入了组件Search,点击搜索框通过路由跳转到搜索展示页面,如下代码:
components: {Search,},
效果图如下图:

在搜索框设置一个v-mode=”searchValue”,然后对其进行绑定监听事件,如下代码:
再然后对搜索内容进行布局,进行数据渲染。具体代码如下:
0">
{{ item.name }}{{ item.enname | enName }}¥{{ item.price }}
当我们点击商品通过路由名以及对应的pid值进行跳转查看该商品详情。因为商品详情接口在参数中有对应的pid。
// 前往商品详情toProductDetails(item) {this.$router.push({ name: "productDetails", query: { pid: item.pid } });},

来到商品详情页面中,通过静态图知道商品详情页中有顶部标题栏、商品图片、商品卡片(商品名称、选项、选择数量、商品描述)、底部商品导航。
商品图片和商品卡片中的商品名称、选项、商品描述都是通过向后端请求回来的数据进行页面渲染。
商品卡片中的选项在渲染之前还有进行v-if判断是否存在,这里在data(){return}中设置了空数组接收后端返回的数据,通过v-if=*[].length>1判断数组的长度是否大于1来确保该商品是否带有该选项进行渲染。具体代码如下图:
{{ productData.name }}
{{ productData.enname }}
¥{{ productData.price }}
1">{{ productData.tem_desc }}{{ item }}
(选项中的糖、奶油和温度的渲染代码基本一样,上面这里就放温度的渲染代码)
商品数量通过v-model=”num”,在data(){return}中定义num=1进行数据双向绑定来选择商品的数量的多少,如下代码:
选择数量
商品描述直接通过获取后端数据进行渲染,如下代码:
商品描述{{ index + 1 }}、{{ item }}
底部导航栏的购物袋和未收藏均用vant组件库中的UI图标,两者均用了三目运算符来为图标是否选中时的颜色进行替换,购物袋数量默认为0,默认未收藏,如下代码:
当点击购物袋,则跳转到购物袋页面,购物袋结构看见上面的静态页面。
iii、菜单页
通过静态图知道菜单页有搜索商品栏、商品类别、商品列表。
搜索商品栏和首页的搜索商品栏的功能是一样的,点击搜索框时跳转到搜索界面。
商品类别点击相关类别时会在商品列表里分类号从而渲染出来。如下代码:
{{ item.typeDesc }}
{{ item.name }}{{ item.enname | enName }}¥{{ item.price }}
item.typeDesc的值从后端接口获取商品类型获取,如下代码:
getType().then((res) => {let result = res.data.result;console.log(result);// 对数组对象进行增加键值对result.forEach((item, index) => {typeProducts[index].type = item.type;typeProducts[index].typeDesc = item.typeDesc;});});// 发起初次请求获取商品self.getTypeProducts(self.typeValue);},
可以通过控制台打印result结果,如下图:

点击商品类别进行改变商品类型,如下代码:
changeType(item) {this.iconSelect = item.typeDesc;this.typeValue = item.type;this.getTypeProducts(this.typeValue);},
然后根据商品类型获取商品,如下代码:
getTypeProducts(value) {let self = this;self.commodityList = [];getTypeProducts({key: "type",value: value,}).then((res) => {self.commodityList = res.data.result;});},
iv、购物袋页面
购物袋页面在本项目中需要用到的后端接口有:查询购物车商品总数数量接口、查询用户所有购物车数据接口、修改购物车商品数量接口、删除一个或多个购物车商品接口(该接口为:逻辑删除:假数据,数据仍在数据库中,但不能查询,以便后续客服手动恢复)
findAllShopcart(data).then((res) => {if (res.data.code === 5000) {self.shopCartData = res.data.result;} else {self.$toast.fail("登录状态异常,请重新登录!");self.$router.push("/login");}});
通过向后端查询用户所有购物车数据接口得到shortCarData数据进行商品渲染:
渲染代码如下:
{{ item.name }}{{ item.rule }}{{ item.enname | enName }}{{ item.price }}
渲染出来的效果图如下:

点击提交订单时,需要用if语句判断是否有订单,若没有订单,则弹选框this.$toast(“请选择商品”),若有订单则用路由跳转到订单结算页面。
点击进行判断if条件代码如下:
onSubmit() {if (this.result.length === 0) {this.$toast("请选择商品!");} else {this.$router.push({name: "orderSettlement",query: { sids: JSON.stringify(this.result) },});}},
订单结算页面效果图如下:

订单结算页面也是要向后端查询购买商品接口请求回来的数据进行渲染,渲染内容有商品卡片中的内容、时间、共计多少件以及合计价格,如上图:
同时点击选择地址会弹出如下效果图:

这里的数据是根据地址aid查询地址接口请求回来进行渲染的,如下代码:
{{ defaultAddress.name }}{{ defaultAddress.tel }}{{ defaultAddress.isDefault === 1 ? '默认' : '' }} {{ defaultAddress.addressDetail }}
findAddress(data).then(res => {if (res.data.code === 20000) {self.addressAll = res.data.result;res.data.result.forEach(item => {if (item.isDefault === 1) {self.defaultAddress = itemself.chosenAddressId = item.aid}item.address = item.addressDetailitem.id = item.aid})} else {self.$toast.fail('登录状态异常,请重新登录!')self.$router.push('/login');}})
点击新增地址可以跳转到如下页面:

在订单结算页面当点击立即结算时,会跳转到我的订单页面,如下代码:
pay(data).then(res => {if (res.data.code === 60000) {self.$toast.success({message: res.data.msg, duration: 1500})this.$router.push('/myOrder')} else {self.$toast.fail(res.data.msg)}})
我的订单效果图如下:

我的订单页面显示全部订单和进行中的订单以及已完成的订单,已完成的订单可以点击右上角删除图标进行删除,进行中的订单点击确认收货后就会显示已完成。
我的订单页面通过使用查询订单接口请求回来的数据进行页面渲染,同时用到删除订单接口以及确认收货接口。
v、我的
我的页面使用后端的我的接口、修改头像接口、修改用户背景接口
页面很好渲染出来的一种方法,如下代码:
由于个人资料到安全中心的操作基本都一样是从后端请求相对应的数据进行渲染的方法基本上是相似的,下面就简单进行展示及讲解一下各个页面了。
个人资料页面资料:

点击头像可直接进行在本地成功上传图片更换
点击昵称弹出框成功进行更换昵称,如下效果图:
点击简历弹出框成功进行编辑简历,如下效果图:

我的订单页面:

我的收藏页面:

点击右下角删除图标可进行移除收藏
地址管理页面:

点击编辑按钮可进行编辑地址,亦可新增地址,效果图如下:

个人安全页面:

点击修改密码弹出框可成功修改密码,效果图如下:
点击注销账号弹出框确认后可成功注销账号,效果图如下:

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
