电商项目app开发

  • 2020 年 7 月 11 日
  • 筆記

购物app的开发

首先我们本次要写的是一个电商的项目,项目主要功能有登录、注册、商品展示、轮播图、加入购物车、购物车管理、支付管理、地址管理、个人信息的修改、商品的分类展示、微信支付等等。主要使用vue框架来实现,电商项目的话我们使用vant放入ui库会比较方便,使用vue脚手架来实现项目的主题架构。

安装脚手架

首先我们安装vue脚手架,并对脚手架进行相应的配置。

cnpm i @vue/cli -g

创建项目

创建项目我们有两种方法

命令行创建项目

vue create myapp

image-20200711092431533

image-20200711092451448

image-20200711092514780

可视化创建项目

vue ui

image-20200711092616536

其他步骤一之前相同

项目目录

image-20200711092735924

image-20200711092755331

项目生成好之后我们要对项目进行改造

项目运行指令

cnpm run serve / npm run serve / yarn serve

拿到创建好的项目之后我们要先找到项目的入口文件。

image-20200711093034749

单文件组件

我们的项目主要通过单文件组件来实现。每一个vue的文件就是一个 组件,内部包含 结构 表现 行为如果一个组件不需要设置 样式 以及不需要编写业务逻辑,可以省略,但是不能缺少 结构代码

image-20200711093321079

为了避免 多个组件之间的 样式冲突,可以选择考虑给。style标签 添加 scoped 属性,那么当前设置的样式就只针对当前组件有效

image-20200711093342717

注:一般不在App.vue组件中添加scoped

避免屏幕双击变大

 

下面我image-20200711114507755们对App.vue主页面进行改造

image-20200711093523485

确定页面结构,主要分为头部和底部两个部分

image-20200711093601163

对样式进行初始化操作、编写样式 – flex + vw + rem

image-20200711093620570

image-20200711093812577

对pc端效果进行优化、进行宽高自适应

image-20200711094023915

抽离底部组件

由于我们页面底部基本没什么变化、主要是上面的页面进行切换。所以我们可以把页面进行抽离,将页面分为上下两个视图,分别单独进行页面的操作。

image-20200711094338759

由于底部样式基本不变,所以我们先对底部样式进行编写。

image-20200711094655666

在编写的时候我们发现我们需要使用图标

我们可以使用iconfont阿里巴巴矢量图标库来同意使字体图标

大致的使用过程是、选择图标 – 加入购物车 – 点击购物车 – 添加至项目 – 新建项目 – 生成在线链接 – 复制链接将此链接通过 link 添加至 public/index.html

image-20200711094923331

使用

image-20200711094950775

image-20200711095003800

然后把图标大下调试到合适的大小就可以啦

构建各个页面

头和内容在一起,每一个组件只能有一个根标签

views/home/index.vue

image-20200711095144491

views/kind/index.vue

views/cart/index.vue

views/user/index.vue

vue的路由系统

有了页面我们就想要吧也爱你 显示出来吧,此时我们就要使用vue的路由系统啦。

 

什么是vue的路由系统呢?Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。

包含的功能有:嵌套的路由/视图表 模块化的、基于组件的路由配置 路由参数、查询、通配符 基于 Vue.js 过渡系统的视图过渡效果 细粒度的导航控制 带有自动激活的 CSS class 的链接 HTML5 历史模式或 hash 模式,在 IE9 中自动降级 自定义的滚动条行为用 Vue.js + Vue Router 创建单页应用,是非常简单的。使用 Vue.js ,我们已经可以通过组合组件来组成应用程序,当你要把 Vue Router 添加进来,我们需要做的是,将组件 (components) 映射到路由 (routes),然后告诉 Vue Router 在哪里渲染它们

将页面组件映射到路由表

image-20200711095609768

此时我们就要告诉Vue Router 在哪里渲染它们

image-20200711095658569

点击底部切换路由

路由配饰好之后我们可以通过路由来访问我们之前的页面啦,不过总不能让用户也这么访问吧,所以我们现在需要使用<router-link to=””>来进行页面的切换

image-20200711100053325

点击高亮显示

到这里我们的底部样式已经编写的差不多啦,此时当我们点击选项卡的时候能够高亮显示就更好啦,

审查元素得知,选中的元素会自动添加一个选中的样式,只需要实现该样式即可

image-20200711100313158

image-20200711100332651

命名视图

我们的底部其实不需要每个页面都需要,这时就有了新的问题,我们的理由视图就有了两个,这个时候呢我们可以使用命名视图实现上下互不影响的切换

image-20200711112018394

image-20200711112030026

image-20200711112038409

重定向

为了增加用户体验,当我们直接访问端口号的时候也想能够显示首页的页面,此时我们就需要对“/”这个路由进行重定向。

image-20200711100633175

使用UI库

到这里我们页面的基本架构 已经完成啦,下面我们就要对页面进行编写啦。

在页面编写的过程中我们要使用UI库来写会更加高效的完成工作。在本项目中我们会使用vant UI库来实现页面的编写

安装依赖

cnpm i vant -S

引入Vant库

我们可以直接使用自动引入组件的方式会比较方便

cnpm i babel-plugin-import -D

babel.config.js 配置 UI库

image-20200711101214456

页面布局

首页

轮播图

直接在want库中找到自己喜欢的样式并进行应用就可以啦

下面示范一线UI库的使用

image-20200711101629958

当~当当当

image-20200711101656842

此时轮播如就ok啦

请求轮播图数据

有了轮播图的结构我们现在需要数据进行渲染

在这里我们要用axios来请求数据,使用个相较于ajax会好用些

首先我们要安装axios这个组件

cnpm i axios -S

对数据请求进行封装,方便使用

  • 封装axios Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。从浏览器中创建 XMLHttpRequests 从 node.js 创建 http 请求 支持 Promise API 拦截请求和响应 转换请求数据和响应数据 取消请求 自动转换 JSON 数据 客户端支持防御 XSRF

image-20200711102252054

image-20200711102301614

image-20200711102319896

为了能够请求到后端数据,我们需要使用代理解决跨域问题

image-20200711102439331

同上图 同时修改了 utils/request.js的baseurl服务器运行时 先走的是代理的服务器(客户端和服务器端会引起跨域问题,服务器与服务器不存在跨域问题,npm run serve 会开启 开发者服务器,代码运行在开发者服务器上(前端代码就在服务器上,不存在跨域),)

重启服务器之后就能够请求到数据啦

我们拿到数据后就可以对页面进行渲染啦

下面的nav导航和之前步骤基本相同,在这里 就不多赘述啦

 

产品页面

显示产品使用UI库的步骤与之前差不了多少,我们可以用Card栏实现数据的显示,

在产品页面的编写过程中,我们如果使用了上拉加载和上拉刷线就比较好看啦

上拉加载

List 组件通过loading和finished两个变量控制加载状态,当组件滚动到底部时,会触发load事件并将loading设置成true。此时可以发起异步操作并更新数据,数据更新完毕后,将loading设置成false即可。若数据已全部加载完毕,则直接将finished设置成true即可。

image-20200711104935163

image-20200711104946063

编写业务逻辑

image-20200711105003697

每次加载一页的内容,并把内容添加到之前的数据后面,让数据能够渲染出来

下拉刷新

下拉刷新时会触发 refresh 事件,在事件的回调函数中可以进行同步或异步操作,操作完成后将 v-model 设置为 false,表示加载完成。

image-20200711105337202

image-20200711105345322

实现刷新函数 请求的第一页的默认的数据,—重置页码和finished的值

image-20200711105357623

回到顶部

此功能的实现需要对页面距离顶端的距离进行监听通过scroTop的设置来实现回到顶部。

image-20200711105706988

是谁引起了滚动条的滚动,滚动的到底是谁

image-20200711105726469

image-20200711105735720

image-20200711105748011

image-20200711105800416

首页的头部

image-20200711110632043

image-20200711110639770

image-20200711110650118

点击左侧列表符号进入分类页面,发现之前的 销毁之前的时候,解除时间监听出现问题

image-20200711110704729

详情页面

我们在点击某条商品的时候显示此商品的详情页面,那我们的详情页面就需要知道我们应该显示那个商品的详情。所以我们可以使用动态路由,商品的id传给详情页面,这样详情页面就能够根据id来显示商品详情啦。

image-20200711112223219

下面是详情页面的构建

使用编程式跳转,来进入详情页面

image-20200711112353863

使用动态路由传值

image-20200711112417178

详情页面渲染

获取产品id

首先肯定是要先获取传过来的内容的

image-20200711112620131

封装数据请求

image-20200711112726842

对数据进行请求并渲染

image-20200711112811210

详情页面的地步应该是有加入购物车设么的,与之前的页面有所不同所以我们要单独写出来

image-20200711112931304

在UI库中找到自己中意的,并对样式进行合理的修改就算基本完成啊

点击加入购物车

当用户看了详情之后感觉有了购买意愿就会点击加入购物车,下面我们来实现加入购物车的操作。

点击加入购物车,判断用户有无登录,如果未登录,跳转至登录页面;如果已登录,获取用户信息,用户id,产品id,数量

要加入购物车,此时我们必须要做的工作是要确定用户身份,所以我们的登录更能必须实现

 

实现登录功能

构建登录页面

后端写好的情况下,登录页面就比较简单了。

新建页面–>配饰路由–>页面编写

有了登录那么也要有注册吧,登录页面中放上注册的入口(就是一个连接)

添加注册页面以及注册路由 -优先复用 登录 页面的元素 router/index.js

  • 当我们在登录注册中都写了各自的页面入口时,频繁点击的情况下,我们回退的话无法直接回到进入登录注册之前的页面,可能会陷入之前你点击次数的循环

    image-20200711114113415

就相当于你每点击一次页面都会往栈里面添加一个页面,回退的时候回一一出栈,这样的话会感觉肥肠麻烦。

所以我们可以在跳转的路由中添加 replace 让每次的页面相互替换不进行存储就可以啦

image-20200711114347751

注:在登录时我们可以将以后要用的信息存到状态管理器中以便以后续验证用户的操作。

点击加入购物车

如果用户为登录,跳转至登录页面,登录成功之后返回详情页 如果用户登录,调用后端加入购物车接口,传入用户id,产品id,数量(如果当前用户存在该产品,数量要加1,如果不存在该产品,插入该产品)

前端实现

image-20200711115129609

image-20200711115138186

image-20200711115148104

当没有数据的时候为了美观我们也可也加一个图显示空的状态。。。空状态 – 没有数据

image-20200711115258501

image-20200711115318464

购物车底部

底部的话就该有结算、购买物品件数、价格一些基本信息。可以在UI库中找到相应的组件。

image-20200711115741773

这个样子差不多就可以

计算总价及总数量

在计算属性中通过哪来的数据进行计算,

image-20200711120025641

image-20200711120032767

总价知道怎么获得了,可我们要让用户选中的产品我们才能进行总价的计算啊

添加选中效果

在每个商品前我们可以添加一个复选框总有备选中的才进行计算

image-20200711140512735

给个样式

image-20200711140526883

计算属性的更改

image-20200711140546491

到这里其实我们的功能就已经做的额差不多了

为了增加用户体验,我们可以增加一个全选的功能。

只要路是,对于商品而言当所有商品被选中的时候全选框行给是选中状态,当有一个或多个没被选中的时候全选框都应给是未选中状态。对于全选框而言,当点击全选的时候应当遍历所有选项将自身以及所有商品的复选框设置成选中状态,当点击取消全选的时候应当将所有复选框设置成为未选中状态。

为了实现上述功能,我们可以给每个选项设置一个状态为0,当被选中时的状态为1 ,在需要判断的时候把所有的复选框的额值相与,此时就可以判断是否需要全选啦,根基这个就能正确的设置选择框的状态

image-20200711141532830

image-20200711141540275

删除

删除数据就比较简单啦,只需要调用删除的接口就可以啦

image-20200711141650949

image-20200711141703961

增减数量

数量的加减其实也就是是数据库的增减,对数据库中数量的修改,因为我们是前端,调用下接口就可以啦。

image-20200711141940803

image-20200711141949844

减法其实和加法并没有多少区别,这里就不多说了

终于来到了我们的订单页面啦

我们在购物车页面点击去付款的时候我们就可以生成订单啦,此时后台肯定要生成一个订单列表

里面存储这个订单对应的价格商品种类和个数等等的信息。当我们来到订单页面的时候我们再通过接口吧订单信息获取过来。然后在对数据进行渲染,就能把用户要买的商品显示出来了。但是单单显示出来还是不够的,既然是订单页面我们肯定是要有地址选择、和确认订单两个业务逻辑的。点击地址选择的时候可以选择,或者新添加有个地址。点击确认的时候就可以显示支付页面了。

地址

点击选择地址地时候我们先是跳转到地址页面我们可以用动态路由来传递用户信息,此时如果后端服务器已经存有地址信息就可以直接选择了 ,要是没有,或者是地址都不是正确的,我们就需要添加新的地址。所以我们还需要构建添加地址要页面,添加地址页面当点击确定时对服务器端数据库中地址信息进行添加。并返回地址选择页面,当我们选中某个地址的时候将此地址存放的状态管理器中,点击回到订单页面时直接从状态管理器中获取选中的地址并进行渲染(还有一种思路:一开始用户就有一个默认选中状态,当点击选择地址的时候更改为当前的选中状态,这样确认订单页面就能够直接从数据库中拿到你选中的地址啦)

 

 

 

(…..图就不放啦,到了这里图已经没什么意义了)

支付

当我们点击支付的时候,我们应该有一个提示页面,用来提示用户选择支付方式,微信,支付宝,还是其他什么方式。(这里只以微信支付为例子)

当我们在确认订单页面点击去支付时,应该删除购物车中选中的数据,便是此商品已经购买了。(不管是成功就是失败但都要删除购物车信息,失败就放到未支付里面就行了)

下面是实现微信支付的流程

两种模式

使用的微信扫码支付的模式二,

模式二与模式一相比,流程更为简单,不依赖设置的回调支付URL。商户后台系统先调用微信支付的统一下单接口,微信后台系统返回链接参数code_url,商户后台系统将code_url值生成二维码图片,用户使用微信客户端扫码后发起支付。

生成订单 (订单编号,交易金额,描述[, 交易时间])

调用后端编写的支付接口,传入参数,等待微信支付之后调用后端编写的回调接口,后端回调接口通过 socket 通讯 通知前端页面支付结果,前端收到消息,进行下一步业务逻辑(支付交易取消 – 跳转未支付页面,支付成功 – 跳转查看订单页面)

个人对于支付感兴趣,经常和后端沟通,发现 要完成成支付,不容易,闲暇时间自己就使用express练习了一下在nodejs中如何完成支付

比如说 32位的随机数保障订单的唯一性 签名 的复杂性,需要除了签名之外的参数,按照 ASCII 字典排序(Object.keys().sort, 遍历生成数组,组合对象),转成字符串(querystirng),拼接商户的密钥key,MD5形式加密,转换为大写

组合所有的参数 ,形成对象 — 向微信平台发起支付 传输的是xml格式的数据,需要把 对象对象形式的参数转换为 xml 格式(xml-js模块),

调用微信的统一下单接口,传入xml格式参数,

微信支付平台返回此笔订单的状态,如果是未支付的订单,返回一个xml文件,其中包含支付的链接地址

将此xml文件转换为json格式,提取支付的code_url地址

使用二维码生成模块(qrcode)生成二维码返回给前端

前端负责展示二维码

后端配置支付结果的回调地址,利用socket通讯通知前端页面支付结果

如果是H5支付(手机浏览器直接唤起微信进行支付),调用统一下单接口,交易类型trade_type=MWEB,支付的链接为mweb_url

如果是小程序支付,需要使用wx.requestPayment()方法唤起支付

jsAPI支付,其实就是在微信的浏览器内完成的微信支付,现在微信后台配置网页授权域名,支付授权的目录 WeixinJSBridge.invoke()

搜索功能

老套路,我们先构建页面。然后调用后端接口。

当我们点击都多的时候我们应该先跳转到一个新的页面,把搜索页面单独拿出来这样可以增加用户体验,在搜索页面中输入要搜索的关键词时点击搜索,将关键词提交到后,后那数据库中的数据进行检索,给前端返回对应的搜索结果,前端拿到数据以后,吧结果渲染到新的页面上(这个页面其实和商品;列表页面时差不多的)

我们只是用过输入关键词来筛选未免显得太过单一,为此我们可以添加一个价格区间筛选,给后端提交一个价格范围,后端通过数据库的条件查询来返回所需要的结果。。根据销量思路与价格基本相同。

分类

分类的实现其实是比较简单的

我们找好合适的UI库之后直接套用就可以啦,(这里通过品牌来分类),构建好页面时候我们就需要数据的支持啦,我们在设计数据的时候已经给每个商品添加了品牌字段,我们只需要从后端拿到所有的品牌,并将品牌渲染到分类页面的nav导航中就行了,根据你当前选中的选项卡去展示所对应的数据。点击那个选项卡就把当前选项卡记录下来,这样当你点到其他页面在回来,仍然可以看到你之前点击的选显卡。

个人中心

先是页面布局,可以仿照京东那种来进行布局 ,调用获取个人信息的接口,并将信息渲染到页面上。由于我们做的是前端渲染数据的时候可以有趣一点,就比如说我们获取到会员信息的时候我们可以根据会员等级显示不同的标志,根基性别显示不同的提示语句,等等。在个人中心页面中我们应该有更改头像,更改个人信息等功能,点击头像应该进入图片选择页面当点击提交的额时候更改后台数据,将头像进行更改,当点击个人信息的时候应把当前用户的信息默认显示在输入框中等待用户更改。点击确定后可以回到个人中心页面并将新的数据渲染出来。最后我们还可以再作一个查看个人中心订单的功能,调用订单接口将订单数据逐一渲染出啦,供用户查看就可以啦。