后续来啦!

    • 2.10、潮品页
      • 2.10.1、获取所有商品的分类
      • 2.10.2、展示某类型的所有商品(瀑布流)
    • 2.11、我的页面
      • 2.11.1、展示某一类型的商品
      • 2.11.2、获取个人信息
    • 2.12、待付款页
    • 2.13、购物车页
      • 2.13.1、显示购物车
  • 三、项目中遇到的一些问题
  • 四、项目中一些技术的实现
    • 4.1、拦截器
    • 4.2、vueX
    • 4.3、路由
    • 4.4、路由守卫
    • 4.5、反向代理
    • 4.6、mock数据
  • 五、项目开发体会

2.10、潮品页

潮品页面也就是从首页跳转到的二级页面,通过点击首页商品分类的更多实现跳转,静态页面效果如下:


该页面实现了两个动态效果:获取所有商品的分类展示某类型的所有商品

2.10.1、获取所有商品的分类

实现思路:

//思路较简单,没有参数
1,连接口,发请求,获取数据;
2,渲染页面。

部分源码:

import axios from '../utils/request.js'
export default {name: "Centen4",data() {return {numZu: [],};},created() {axios({url: "/api/goods/findFashionType",// method:'get',  默认是get请求}).then((res) => {// console.log(res.data.data);this.numZu = res.data.data;// console.log(this.numZu);});},
};

实现效果参考上面这张图(新品首发)

2.10.2、展示某类型的所有商品(瀑布流)

就是获取某个类型的所有商品(该类型已经固定,已经存储在数据库),以瀑布流的形式展示。

实现思路:

1,该类型已经固定为3,故发起请求,并传参typeId为3;
2,获取数据,瀑布流展示。

源代码:

import axios from "axios";
export default {name: "Centen6",data() {return {shuZu: [],};},created() {axios({url: "api/goods/findGoodsByType/",params: {typeId: 3,//此处传参},}).then((res) => {console.log(res.data.data);this.shuZu = res.data.data;});},
};

效果图:


(数据库中只存储了少量图片,因为切图实在太麻烦了!瀑布流前面已经解释过,可以看我的上一篇博客。)

2.11、我的页面

相信这个大家都清楚,基本上所有APP都会有我的页面,类似于首页,用来展示APP的一些功能以及个人信息等。

静态页面在上一篇博客已经展示过,有兴趣的小伙伴可以先看完第一篇博客。

在本次项目中,我的页面实现的功能较少,因为功能太多啦,而且时间和水平上的原因,只实现少部分功能:展示某一类型的商品获取个人信息

2.11.1、展示某一类型的商品

这部分功能和首页的很像,只是数据不同,布局和接口完全一样,所以我会说的快一些。

首先,我的页面有以下四种分类,并且页面加载完毕默认显示第一种分类。


这里同样可以使用动态组件vueX等,在首页我选择了使用vueX

实现思路:(与首页一致)

1,默认获取下午茶相关的商品数据,渲染;
2,点击其他分类获取对应的商品信息,并渲染。

来看看相关代码:

import axios from "../utils/request"export default {name: "Classify",data() {return {arr:["9","10","11","12"],a: 0,teas:[]};},created () {this.gettea(0)
},methods: {reveal(index) {this.a = index;this.gettea(index);},gettea(idx){axios({url:'/api/goods/findGoodsByType',params:{typeId:this.arr[idx]}}).then(res=>{this.teas=res.data.data;// console.log(res.data.data);})},//动态路由传参的方式goDetail(id){this.$router.push("/info/"+id);},tochao(){this.$router.push('/Newsp')}}
};

这里使用了动态组件的思路来做的,效果也是同样完美,每个人都有自己的思路,挺不错的!

效果图:


很显然,在这里存储了更多的图片,效果也是很不错的,就是切图太麻烦。。。

2.11.2、获取个人信息

这里只是实现了简单的效果,通过事先在数据库中存储一些个人信息,再通过登录时的手机号查询出来,并保存在本地。

实现思路:

1,连接口,发请求,获取个人信息;
2,将数据都存储在cookie中,需要获取的时候再从本地获取。

部分源码:

//此处封装了模块,并引入
created() {axios({url: "http://1.117.52.63:8081/user/findByTel",}).then((res) => {// console.log("this.ming", res.data.data);console.log( creatCookie("id",res.data.data.id));creatCookie("id",res.data.data.id,7)creatCookie("sex",res.data.data.sex,7)creatCookie("tel",res.data.data.tel,7)creatCookie("username",res.data.data.username,7)});},

封装存储cookie模块:

function creatCookie(key,value,date){var t = new Date();t.setDate(t.getDate()+date)document.cookie = key+'='+value+';expires='+t;
}
export default creatCookie;

至于获取个人信息是在个人资料页从cookie里读取并渲染:

封装读取cookie模块:

function getCookie(value){var str = document.cookie;var arr = str.split('; ');var newarr = [];for (const key in arr) {newarr = arr[key].split('=');if (newarr[0] == value) {return newarr[1];}}return '';
}
export default getCookie;

cookie函数的封装也可以封装在一个模块并导出。

2.12、待付款页

待付款页是从确认订单页点击取消订单跳转到的页面,该页面实现了一个动态效果:查询订单信息

待付款页面是有一个5分钟倒计时的,倒计时结束,则自动取消订单,若倒计时结束前用户点击去支付,则重新跳转到确认订单页面。

静态页面先不看。

实现思路:

1,发请求,传参,获取数据;
2,渲染。(思路就是这么简单)

源码:

import axios from "../utils/request";
export default {data() {return {serv:[],arrlen:[],arrf1: ["14BC03EAA1BC4066AF476A6976B0BF32","72C35A1B4BF144F38580E7F38619EAEB","8666F9A626B44824B175C9F63B4BCABE","D7EDF5B1D23A4A6CB14C1FC2A10FBCF1",],f11: 0,};},axios.get("/api/order/selectOrderByOid/" +this.arrf1[this.f11]).then((ok) => {console.log(ok.data.data);this.serv=ok.data.datathis.arrlen =ok.data.data.orderDetailRespsconsole.log(this.arrlen);});},
};

效果图:

2.13、购物车页

购物车,这可能是每个电商APP不可缺少的环节了吧,商品加入购物车才能购买,并且在购物车可以调节购买数量,查看商品的基本信息等等。

购物车作为支付前的最后一个环节,自然是重中之重,遗憾的是,本次项目中在购物车环节实现的效果不全,当前也和我们自身的水平有关。以下我将对购物车已实现的部分功能加以概述。

首先,我们要知道商品从选择到支付完成的一整套流程是:
选中商品==》选择商品数量口味等==》加入购物车==》显示购物车==》去结算==》支付成功

加入购物车我们已经实现了,下面显示购物车:

2.13.1、显示购物车

其实就是一个查询操作,将加入购物车的商品查出来并渲染。

实现思路:

1,发请求,同时传参uid(用户id);
2,获取数据,渲染。

源码:

import axios from "../utils/request.js";
import Vue from "vue";
import { Toast } from "vant";
import { Popup } from "vant";Vue.use(Popup);
Vue.use(Toast);export default {name: "Centent1",data() {return {show: false,goodsList: [],};},created() {axios({url: "/api/cart/cartIterm",params: {uid: 8,},}).then((res) => {this.goodsList = res.data;});},methods: {removeGoods(idx) {if (confirm("亲,您真的要删除吗?")) {this.goodsList.splice(idx, 1);}},reducer(idx) {if (this.goodsList[idx].number <= 0) {this.show = true;return;}this.goodsList[idx].number--;},add(idx) {this.goodsList[idx].number++;},quxiao() {this.show = false;this.goodsList[0].number = 1;},que() {},totalMoney() {let sum = 0;this.goodsList.forEach((goods) => {if (goods.isChecked) {sum += parseInt(goods.number) * parseInt(goods.price);}});return sum;},},
};

效果图:

同时:当商品数量减到0,即删除该商品,会弹出提示框:

由于购物车实现效果较少,我在这里总结下购物车应有的效果:

购物车总结:

1,显示购物车(接口实现);
2,点击加减号对应商品数量加减对应数量(数据库中,接口实现),
同时总价也相应的变化;
3,当数量减到0,视为删除该商品(接口实现),会有提示框;
4,只有选中商品前面的复选框,该商品小计才会计算到总价中;
5,点击去结算,创建订单(接口),同时跳转到确认订单页面。

至此,实现的动态效果(接口)基本上介绍完了,其他的静态页面以及实现不完美的接口就不展示了,有兴趣可以下载源码(下载地址我会附在博客末尾),大家可以在评论区讨论交流,我会一一回复。(我可能是最良心的博主了!

三、项目中遇到的一些问题

本次项目持续近两个周,遇到的问题大大小小不计其数层出不穷,这也是每个程序员必经的过程。都说程序员容易秃顶,那也是有迹可循的。好了,话不多说,我将以我个人视角总结下本次项目中遇到的主要困难吧:

  1. 脚手架的使用

    最开始项目的时候,手足无措,因为第一次使用脚手架,和以往的开发流程不同,会有些生疏,不知道从何下手,特别是做的还是SPA(单页面应用),不知道怎么写第二个页面,以及组件之间是如何动态切换的。

  2. 组件的复用问题

    组件存在的意义不就是为了复用,然而在开发中却不那么顺利,因为有的组件结构大致相同,只是内容不同。如何只改变内容,而结构不变困扰了我很久,直到学习了vueX.。

  3. 请求错误问题

    由于是前后端联合,发请求势必少不了404和500,而这个问题也是让我一度肝肠寸断,前端通过后端提供的接口去发请求。
    一般来说404都是前端地址错误,而500是后端服务器错误,但事实不止于此。404也可能是后端提供的接口问题,而500也可能是前端网络问题。我:???
    一般遇到这种问题,我都会先在postman测试,再查看network,以此判断是谁的问题,也不能一味的甩锅。

  4. 跨域问题

    由于前后端分离,两边都有一个服务器,那跨域在所难免。跨域的问题可以是后端解决,当然也可以前端解决。前端解决:反向代理。
    由于刚开始后端服务器关闭频繁,接口地址随之变化,导致每次都需要修改地址并重启服务,这就导致莫名其妙的404或者500问题。

  5. 页面渲染导致样式混乱

    由于每个人在开发时的习惯不同,是按照不同的移动端模拟器开发的,这就导致同一个页面在不同电脑下运行样式出现混乱的问题,特别是刚开始合并项目的时候,文件名重名,路径不统一导致样式不显示或显示错误等,需要一点一点调试。

  6. token问题

    这个问题可真是杀伤力极大,因为token是后端返回给前端并且前端负责保存在本地的,由于沟通不及时,我们原本打算保存在localStorage里,但是后端在做token验证时是从cookie里获取。
    我们不得不重新修改代码,将token保存在cookie里,cookie数据操作需要自己封装函数,于是,封装呗。并且我们在做请求拦截器以及路由守卫时都需要修改为cookie获取。
    在小组内部也是因为token的获取方式导致项目调试久久不能完成。

  7. Gitee的使用

    git,多人协作必用的工具,我们是第一次使用,操作起来也是非常生疏,特别是通过git合并项目时,用了最笨的方法,一次次的git clone,然后手动复制粘贴,再一次次的git push。并且在复制粘贴的过程中,路径问题,静态资源文件夹重名问题,真的头大。
    后来才发现可以使用git branch,才彻底改变了我对git的看法。

  8. 开发依赖库下载及版本问题

    项目开发中,需要用到很多第三方库,如vant,axios等等,版本过高或过低都会导致形形色色的问题,特别是项目合并时,由于这些第三方库的不统一,需要统一下载并保持版本一致。

  9. 组件重名问题

    只能说,我们给组件起名字时太过语义化 ,如shop1,shop2,导致很多重名的组件,没办法,只能一个个对比着改,然后一一测试效果。

  10. 第三方组件的使用

    本次项目中,用到最多的第三方库就是vant,它提供了很多组件,可以直接拿来用。但是刚开始却不是那么顺利。有些组件可以直接全局引入,有的还需要按需引入。这就需要不断尝试,还有这些组件自定义样式的问题。

好了,以上就简单总结一下项目中遇到的问题,吃一堑长一智,及时的总结经验可以让你在未来避免这些错误。如果你也遇到过类似的问题,欢迎在评论区分享出你的解决方案。

四、项目中一些技术的实现

4.1、拦截器

在请求发出后,以及响应回来前要干的一些事情可以写在拦截器里,拦截器并不是真的拦截

在项目根目录下新建utils/request.js文件

import axios from "axios";
import store from '../store'// axios.defaults.baseURL="/api";// 请求拦截器
axios.interceptors.request.use(config => {store.commit('changeload', true)if (getCookie('token')) {config.headers.common["token"] = getCookie('token');}return config;
});// 响应拦截器
axios.interceptors.response.use(res => {store.commit('changeload', false);return res;
});//此处封装了获取cookie的函数
function getCookie(key) {var info = document.cookie;var arr = info.split("=");if (arr[0] == key) {return arr[1];}return "";
}//别忘了导出
export default axios;

4.2、vueX

用来保存全局数据,供整个项目使用。(前面提到过,首页使用了vueX技术实现商品类型切换)

在项目根目录新建store/index.js文件

import vueX from 'vuex'
import Vue from 'vue'
import axios from '../utils/request.js'
Vue.use(vueX)export default new vueX.Store({state: {shopinfo: [],tel: '',code: '',isshow: false,orderInfo: ["全部", "立等可取", "预约订单"],outerInfo: ["门店自提", "送货上门", "瑞即购"],isLoading: false,},mutations: {//state:store中的statechange(state, payload) {state.shopinfo = payload.data// console.log(state.shopinfo);},changeload(state, payload) {// console.log(payload);state.isshow = payload},changeIsLoading(state, payload) {state.isLoading = payload.isLoading;}},actions: {//context:store对象change1(context) {axios({url: "/api/goods/findGoodsByType",params: {typeId: 4,}}).then(res => {console.log(res.data.data);context.commit('change', { //将请求结果传给mutationsdata: res.data.data})})},change2(context, payload) {// console.log(payload);axios({url: "/api/goods/findGoodsByType",params: {typeId: payload,}}).then(res => {context.commit('change', { //将请求结果传给mutationsdata: res.data.data})})},}
})

4.3、路由

实现组件间的跳转。(相当于pc端里a标签的功能,路由的使用需要配置,可以参考我的博客路由是什么)

在根目录下新建router/index.js文件

import Vue from "vue";
import VueRouter from "vue-router";import Menu from "../pages/Menu.vue";
import Order from "../pages/Order.vue";
import Outering from "../pages/Outering.vue";
import Address from "../pages/Address.vue";
import Detail from "../pages/Detail.vue";
import Acontent from "../components/Acontent.vue";
import NotFound from "../pages/NotFound.vue";
import Item from "../components/Item.vue";
import index from '../pages/Index'
import info from '../pages/Info'
import addcomm from '../pages/addcomm'
import pay from '../pages/pay.vue'
import Newsp from "../pages/Newsp";
import Shop from "../pages/Shop";
import Login from "../pages/Login";
import Payment from "../pages/Payment";
import My from "../pages/My";
import PersonalData from "../pages/PersonalData";
import Profile from "../pages/Profile.vue"
import NewlyAdd from "../pages/NewlyAdd.vue"
import CardRedirect from "../pages/CardRedirect.vue"
import getmoney from '../pages/GetMoney.vue'Vue.use(VueRouter);// 路由配置
let router = new VueRouter({mode: 'history',routes: [{path: '/',redirect: '/index', //重定向},{path: '/index',name: index,component: resolve => require(['../pages/Index'], resolve)},{path: "/Menu",name: Menu,component: resolve => require(['../pages/Menu'], resolve)},{path: "/Order",name: Order,component: resolve => require(['../pages/Order'], resolve),meta: {requiresAuth: true}},{path: "/Shop",component: Shop,meta: {requiresAuth: true}},{path: '/info/:id',component: info,meta: {requiresAuth: true}},{path: '/addcomm/:id',component: addcomm,meta: {requiresAuth: true}},{path: '/pay',component: pay,meta: {requiresAuth: true}},{path: "/Outering",component: Outering},{path: "/Address",component: Address}, {path: "/Detail/:id",component: Detail,meta: {requiresAuth: true}},{path: "/Acontent",component: Acontent},{path: "/Item/:id",name: Item,component: resolve => require(['../components/Item'], resolve)},{path: "/Newsp",component: Newsp,meta: {requiresAuth: true}},{path: "/Login",component: Login},{path: "/Payment/:money",component: Payment,meta: {requiresAuth: true}},{path: "/My",component: My,meta: {requiresAuth: true}},{path: '/GetMoney',component: getmoney,meta: {requiresAuth: true}},{path: "/PersonalData",component: PersonalData,meta: {requiresAuth: true}},{path: "/CardRedirect",component: CardRedirect,meta: {requiresAuth: true}},{path: "/Profile",component: Profile},{path: "/NewlyAdd",component: NewlyAdd},{path: "*",component: NotFound},]
})// 导出路由实例
export default router;

4.4、路由守卫

可以用来验证用户是否登录以及是否可以访问页面。

同4.3,在一个文件里

//路由全局守卫(前置)
router.beforeEach((to, from, next) => {//to 到哪去(目标路由)//from 从哪来(当前路由)//next 去干吗if (to.meta.requiresAuth) {if (getCookie("token")) { //是否登录console.log('已经登陆');next();} else {console.log('没有登陆');next({ path: "/login", params: { toPath: to.path } });}}next()
})

4.5、反向代理

前端解决跨域问题的方法。

在项目根目录新建vue.config.js文件

module.exports = {devServer: {//设置代理proxy: { //代理是从指定的target后面开始匹配的,不是任意位置;配置pathRewrite可以做替换// 商品列表反向代理'/api': { //axios访问 /api ==  target + /apitarget: '此处为服务端真实ip地址',changeOrigin: true, //创建虚拟服务器 pathRewrite: {'^/api': '' //重写接口,去掉/api, 在代理过程中是否替换掉/api/路径 }},}}
}

4.6、mock数据

模拟后端数据。(没有后端接口时测试用)

在项目根目录新建db.json文件

{"books": [{ "id": "878911", "name": "三国", "author": "罗贯中" },{ "id": "878912", "name": "水浒", "author": "吴承恩" }],"readers": [{ "id": "007", "name": "张三疯", "age": 35 },{ "id": "008", "name": "张四疯", "age": 32 }]
}

注意:文件内容如上图所示,在本次项目中mock数据用的较少。具体的使用参考我之前的博客。

五、项目开发体会

项目做完了,但是总体来说效果不是特别好,该有的功能没有实现,比如购物车功能,支付功能。经过这次的项目开发经历,确实学到了很多,也有很多不足的地方。
总之,收获到的远远大于所经历的痛苦,因为,痛并快乐着。

写这篇博客也是抽出时间来写的,历时将近两天,能想到的都写了,思路不是很清晰,也不知道还需要写什么,以后有机会再补上吧!

最后的最后,附上项目完整的源代码下载地址:https://gitee.com/sandas/ruixing(无毒无害,放心下载),有什么问题评论区见哈!

Vue项目-手机app瑞幸咖啡详解(全网最细) 从脚手架搭建到前后端数据交互(二)相关推荐

  1. 详解 AJAX-SpringBoot 前后端数据交互

    详解 AJAX-SpringBoot 前后端数据交互 1. Ajax 概述 Ajax 的英文全称是 "Asynchronous JavaScript and XML",即 &quo ...

  2. vuejs出的手机app有哪些_详解Vue webapp项目通过HBulider打包原生APP

    Vue webapp项目通过HBulider打包原生APP 1.webapp项目已经通过vue-cli搭建的脚手架写好了,然后通过webpack打包成一个部署文件list,如下: 2.打开HBulid ...

  3. vue项目的目录结构图及目录详解

    简单介绍目录结构build目录是一些webpack的文件,配置参数什么的,一般不用动 config是vue项目的基本配置文件 node_modules是项目中安装的依赖模块 src源码文件夹,基本上文 ...

  4. 一、在vue项目中使用mock.js(详解)

    步骤1.搭建测试项目 步骤1.1创建项目 命令: vue create mock-demo 步骤1.2安装依赖 命令: #使用axios发送ajax cnpm install axios--save ...

  5. vue 项目引用static目录资源_详解vue中静态资源的路径问题(深度好文)

    前言: webpack中的require解析 首先明确一点,在项目中的webpack.config.js等项目配置文件中使用的require属于nodejs范畴,而进入index.js后,加载的组件中 ...

  6. 手机app端token的详解很详细了

    token是什么? token是服务端生成的一串字符串,以作客户端进行请求的一个令牌.当第一次登陆后,服务器生成一个token便将此token返回个客户端,以后客户端只需带上这个token前来请求数据 ...

  7. 使用SpringBoot编写电脑商城项目笔记(每一步都详细记录,前后端数据交互使用html+ajax+json)

    项目环境 JDK1.8 Maven3.8.3 Tomcat9.0.54 Mysql8.0 技术栈:springboot+mybatis+mysql+html+javascript+css+json+j ...

  8. 跌破发行价——瑞幸咖啡这个案例,小白可能会疑惑的几个问题

    作者 | 铺子店长 来源 | 茶水铺子 以下内容并非原创,均为搬运整理,用于解答当前我感到困惑或者好奇的问题.与你分享. 由于篇幅太长,所以先抛问题,便于自行思考或浏览: 1.瑞幸咖啡为什么这么惹眼? ...

  9. 多个迹象表明,瑞幸咖啡已进入新的发展阶段

    瑞幸咖啡正在引领新一轮的咖啡茶.饮产业进创新. 01 瑞幸咖啡:公司在重组计划和资本市场披露方面达到多项"里程碑式"进展 9月21日,瑞幸咖啡发布声明,公司今日发布三则公告,宣布公 ...

  10. 瑞幸咖啡的最终目标并不是做国内市场大哥

    出品 | 何玺 排版 | 叶媛 日前,瑞幸咖啡发布2022年第四季度及全年财报.数据显示,在刚刚过去的2022年,瑞幸咖啡首次实现了营收超百亿,门店规模也超越老对手星巴克,成为了国内第一连锁咖啡品牌. ...

最新文章

  1. Ubuntu 14.04 64bit上升级Intel官方集显更新驱动程序
  2. 微服务后如何做一次系统梳理
  3. oracle 前端ui框架,Layui(前端UI框架) 2.6.4 官方最新版
  4. Openstack 实现技术分解 (1) 开发环境 — Devstack 部署案例详解
  5. h5压缩图片上传 php_一键压缩,图片上传大小不得超过200K?
  6. 【2】HashMap
  7. IE10、IE11解决不能播放Flash的问题!
  8. 数据结构单链表的创建和遍历(后插法)
  9. haoi2018奇怪的背包题解
  10. vb和python语言的区别大吗_vb语言为什么被淘汰
  11. 面试官的窒息逼问:2021最全的接口测试面试题及参考答案
  12. 【场景化解决方案】ERP系统与钉钉实现数据互通
  13. 微信小游戏实战--cocos creator实现wordle游戏(七)
  14. 【科技文献检索】CNKI中国知网检索
  15. 实践者颜水成:在学术界「恋爱」 在工业界「结婚」
  16. 软件工程之制定计划①(可行性研究报告、项目开发计划)
  17. 云服务器上的项目无法连接数据库,云服务器中项目连接数据库
  18. JavaWeb企业级项目中接入顺丰官方API实现物流实时查询(亲测有效)
  19. 医学影像识别中的常用AI指标
  20. 二手MicroServer Gen8折腾记 - 配置 RouterOS 软路由

热门文章

  1. 苹果电脑拷贝文件到u盘很慢_给自己挑个好U盘,再也不想天天找同事借了
  2. 题目1365:贝多芬第九交响曲
  3. python怎么学比较快,怎样快速学会python
  4. 用javascript 判断IE窗口是否打开
  5. C语言中side的用法,side的用法总结大全
  6. 设置Chrome浏览器不加载图片的方法
  7. Python地理数据处理 三:矢量数据的读写(一)
  8. 成为一个好的PHP工程师需要掌握什么技能
  9. 【MATLAB】rem和mod函数的区别
  10. win11键盘失灵 windows11键盘失控 键盘没反应