【Vue】仿小米商城系统(四)

编程入门 行业动态 更新时间:2024-10-27 03:26:59

【Vue】仿<a href=https://www.elefans.com/category/jswz/34/1768634.html style=小米商城系统(四)"/>

【Vue】仿小米商城系统(四)

【Vue】仿小米商城系统(四)

文章目录

  • 【Vue】仿小米商城系统(四)
    • 前言
    • 🐶项目地址:
    • 八、Element-UI使用
      • 1.按需引入
        • 一个🌰
      • 2.插件引用
      • 3.对于 babelrc文件 和 babel.config.js文件
        • 方案一:
        • 方案二:
      • 在该项目中引入 --> 方法一,用import
      • 在该项目中引入 --> 方法二,将该方法扩展到vue实例身上
    • 九、订单支付页面
      • 支付宝
      • 微信支付
    • 十、订单列表页 --> 分页功能
      • elementUI: 分页器
      • 加载更多按钮
      • 滚动加载 --> 插件实现
      • 原生实现加载更多
    • 十一、项目优化
    • 十二、总结

前言

本项目是基于Vue全家桶的仿小米商城系统,系列笔记(已完结)如下👇🏻

【Vue】仿小米商城系统(一)

【Vue】仿小米商城系统(二)

【Vue】仿小米商城系统(三)

【Vue】仿小米商城系统(四)


🐶项目地址:

点击这里👉仿小米商城系统mimall开发笔记及源码

这里是小飞侠Pan🥳,立志成为一名优秀的前端程序媛!!!

本篇博客收录于我的github前端笔记仓库中,持续更新中,欢迎star~

👉




八、Element-UI使用

1.按需引入

  1. 安装 babel-plugin-component
npm install babel-plugin-component -D
  1. 修改 babel.config.js:

官方文档是修改 .babelrc (现在已经找不到 .babelrc文件,而是 babel.config.js),

并且里面的"es2015"好像有问题,这样好像会有bug

所以我们向babel.config.js文件追加,注意不是覆盖,最终代码如下图所示:

module.exports = {presets: ['@vue/cli-plugin-babel/preset',["@babel/preset-env", { "modules": false }]],"plugins": [["component",{"libraryName": "element-ui","styleLibraryName": "theme-chalk"}]]
}
//官方给的完整修改
{"presets": [["es2015", { "modules": false }]],"plugins": [["component",{"libraryName": "element-ui","styleLibraryName": "theme-chalk"}]]
}//尚硅谷的视频中的完整的修改:
{"presets": [["@babel/preset-env", { "modules": false }]],"plugins": [["component",{"libraryName": "element-ui","styleLibraryName": "theme-chalk"}]]
}

3.引入部分组件

import Vue from 'vue';
import { Button, Select } from 'element-ui';
import App from './App.vue';Vueponent(Button.name, Button);
Vueponent(Select.name, Select);
/* 或写为* Vue.use(Button)* Vue.use(Select)*/new Vue({el: '#app',render: h => h(App)
});

Vueponent(Button.name, Button);中,前面的参数是指自己给要用的组件起一个名字,如果不传,默认使用el-


一个🌰
<el-row><el-button>默认按钮</el-button><el-button type="primary">主要按钮</el-button><el-button type="success">成功按钮</el-button><el-button type="info">信息按钮</el-button><el-button type="warning">警告按钮</el-button><el-button type="danger">危险按钮</el-button>
</el-row>

2.插件引用

可以通过 element 插件快速集成 element-ui,在命令行中执行

vue add element

(对于一个新的项目,推荐使用插件引入)


3.对于 babelrc文件 和 babel.config.js文件

方案一:

官方文档是修改babelrc文件,那么我们可以建立一个babelrc文件

并在里面写入:

{//   "presets": [["es2015", { "modules": false }]], 这个好像是有bug,改成下面那个"presets": [["@babel/preset-env", { "modules": false }]],"plugins": [["component",{"libraryName": "element-ui","styleLibraryName": "theme-chalk"}]]
}

方案二:

我们直接更改babel.config.js文件,

注意:这里是向babel.config.js文件中追加,而不是完全覆盖

我们打开babel.config.js,如下面的代码所示

module.exports = {presets: ['@vue/cli-plugin-babel/preset']
}

然后和presets平级进行追加,

module.exports = {presets: ['@vue/cli-plugin-babel/preset',["@babel/preset-env", { "modules": false }]],"plugins": [["component",{"libraryName": "element-ui","styleLibraryName": "theme-chalk"}]]
}

在该项目中引入 --> 方法一,用import

//main.js
import { Message } from 'element-ui'Vue.use(Message)//注册//使用    
Message.error(res.msg);
Message.success('注册成功');

注意:这里如果要在别的组件中使用,还需要再引入一遍,

import { Message } from 'element-ui'


在该项目中引入 --> 方法二,将该方法扩展到vue实例身上

//main.js
import { Message } from 'element-ui'Vue.prototype.$message = Message;//将该方法扩展到vue实例身上//使用
this.$message.success("删除成功");

此时在别的组件中使用,并不需要再次引入


九、订单支付页面

微信支付:接口返回内容是支付链接,转换为二维码结扫码支付

支付宝支付:返回内容为form表单,我们将form表单提交后自动跳转到支付页面。

自己定义一个payType属性,来保存用户选择的是哪种支付方式,并且触发支付事件,

        <div class="item-pay"><h3>选择以下支付方式付款</h3><div class="pay-way"><p>支付平台</p><div class="pay pay-ali" :class="{'checked':payType==1}"  @click="paySubmit(1)"></div><div class="pay pay-wechat" :class="{'checked':payType==2}"  @click="paySubmit(2)"></div></div></div>

在data中定义payType属性

  data(){return {payType:''}}

实现支付:

    paySubmit(payType){// @click="payType=1"if(payType==1){this.payType=1;window.open('/#/order/alipay?orderId=' + this.orderId,'_blank');}else{this.payType=2;this.axios.post('/pay',{orderId:this.orderId,orderName:'Vue高仿小米商城',amount:0.01,payType:2 //1.支付宝  2.微信}).then((res)=>{QRCode.toDataURL(res.content).then(url => {this.showPay = true;this.payImg = url;this.loopOrderState();}).catch(()=>{Message.error('微信二维码生成失败,请稍后重试');})})}}

支付宝

后端返回一个隐藏的form表单,然后我们插入前端,通过提交表单拉起支付宝支付

支付宝支付的逻辑比较简单。首先,请求之后,跳转至一个新的页面(alipay.vue),然后在这个页面上拿到返回的form表单,然后通过v-html="content",将表单嵌入到alipay页面上。在这里其实,alipay相当于一个中间页。

当我们点击支付宝支付按钮后,可以清楚的看到:页面跳转后,先进入的是我们自己定义的alipay页面,然后等待一会儿,才会进入支付宝的支付页面。

1.我们这里使用window.open来实现空白页面的打开,点击支付宝支付后,触发下面的方法:

window.open('/#/order/alipay?orderId='+this.orderId,'_blank')

跳转到的新的页面(alipay页面):

<template><div class="ali-pay"><loading></loading><div class="form" v-html="content"></div></div>
</template>

进入该页面后之后,触发提交的请求,后台会返回一个content,这是包含支付的一个支付宝支付表单的form表单,提交这段代码就会跳转到支付宝的支付页面。这里我们使用document.forms[0].submit()来触发这个表单的提交:

alipay.vue

data() {return {orderId:this.$route.query.orderId,//获取我们的订单IDcontent:'' //用来将返回的form表单嵌入页面};},
  methods: {paySubmit(){this.axios.post('/pay',{orderId:this.orderId,orderName:'Vue高仿小米商城',amount:0.01,payType:1 //1.支付宝  2.微信}).then((res)=>{this.content = res.content;//拿到form表单,将它嵌入页面setTimeout(() => {document.forms[0].submit();//提交表单,实现页面跳转}, 100);})}},mounted() {this.paySubmit();}

这里还使用了一个loading组件来作为从支付页面到支付宝的页面的过渡。

这两步完成之后,就可以跳到了支付宝支付页面,然后就可以进行支付操作了。


微信支付

微信支付相关文档 👉开发文档

该项目使用的是 Native支付,用户打开“微信扫一扫”,扫描商户的二维码后完成支付。

后端会返回一个生成二维码的链接code_url,对应链接格式:weixin://wxpay/bizpayurl?sr=123456

当用户点击了微信支付的模块时,会将数据提交到后台,然后后台返回一个二维码链接,我们需要将这个链接转换成用户可以识别的二维码.

而想要将链接转化为二维码,需要使用一个插件:qrcode,

  • 安装:npm install --save qrcode
  • 引入:import QRCode from 'qrcode'
<template><!-- 这里是我们引入的一个组件,这个组件在页面上显示的是一个模态框,当微信二维码返回后,会插入到这个组件中 --><scan-pay-code v-if="showPay" @close="closePayModal" :img="payImg"></scan-pay-code>
</template>paySubmit(payType){// @click="payType=1"if(payType==1){this.payType=1;window.open('/#/order/alipay?orderId=' + this.orderId,'_blank');}else{ //!!!微信支付this.payType=2;this.axios.post('/pay',{orderId:this.orderId,orderName:'Vue高仿小米商城',amount:0.01,payType:2 //1.支付宝  2.微信}).then((res)=>{QRCode.toDataURL(res.content)//转化成base64位的图片.then(url => {this.showPay = true;//展示图片this.payImg = url;//图片的URLthis.loopOrderState();}).catch(()=>{Message.error('微信二维码生成失败,请稍后重试');})})}}

另外我们需要定时轮询订单的支付状态,如果完成支付,自动跳转到订单列表页面。

接口文档中,对于订单状态的返回值:

0-已取消,10-未付款,20-已付款,40-已发货,50-交易成功,60-交易关闭

所以我们在这里判断当status===20时,表示已付款,跳转到订单列表页面。

//轮询当前订单支付状态    
loopOrderState(){this.T = setInterval(()=>{this.axios.get(`/order/${this.orderId}`).then((res)=>{if(res.status == 20){clearInterval(this.T);//清除定时器this.goOrderList();//跳转到订单列表页面}})},1000);
},
goOrderList(){this.$router.push('/order/list');
}

十、订单列表页 --> 分页功能

elementUI: 分页器

在页面按需引入,并注册:

  import {Pagination} from 'element-ui'// 由于我们引入的是Pagination,而使用时前面有一个el-,所以使用这种方式加载components:{[Pagination.name]: Pagination,}
          <el-paginationclass="pagination"layout="prev, pager, next":pageSize="pageSize" :total="total"@current-change="handleChange"></el-pagination>

在handleChange事件中,我们要重新获取新的一页的数据进行渲染,

      handleChange(pageNum){this.pageNum = pageNum;this.getOrderList();}

加载更多按钮

在最底部放一个“加载更多”的按钮,这里也使用element uI的button:

import { Button } from 'element-ui'components:{[Button.name]: Button,}
  • 定义结构
    这里定义一个数据showNextPage,默认为true,就是可以显示下一页
<div class="load-more" v-if="showNextPage"><el-button type="primary" :loading="loading" @click="loadMore">加载更多</el-button></div>

  • 数据交互
    这里需要注意,我们想要的是加载更多之后与前面加载的数据进行拼接,所以需要对订单的List进行改造:
   getOrderList(){this.loading = truethis.axios.get('orders', {params:{pageNum: this.pageNum}}).then((res) => {this.loading = false;// 将数据与前一页进行拼接this.list = this.list.concat(res.list)this.total = res.total// 判断是否还有下一页,如果没有就会隐藏加载按钮this.showNextPage = res.hasNextPagethis.busy = false}).catch(() => {this.loading = false})}loadMore(){// 页数加一this.pageNum++// 重新刷新订单列表this.getOrderList()}

滚动加载 --> 插件实现

  • 滚动加载需要使用到一个插件:vue-infinite-scroll,首先要安装并引入、注册插件:
// 安装
npm install vue-infinite-scroll --save
// 引入
import infiniteScroll from 'vue-infinite-scroll'
// 注册(与data同级)
directives:{infiniteScroll
}
  • 定义结构
<div class="scroll-more"v-infinite-scroll="scrollMore"  // 触发滚动infinite-scroll-disabled="busy"    // 是否禁用infinite-scroll-distance="410">    // 距离底部多少像素的时候,进行加载<img src="/imgs/loading-svg/loading-spinning-bubbles.svg" alt="" v-show="loading"></div>
  • 数据交互
      //第三种方法:滚动加载,插件实现scrollMore(){this.busy = true;setTimeout(()=>{this.pageNum++;this.getOrderList();},500)},//专门给scrollMore使用getList(){this.loading = true;this.axios.get('/orders',{params:{pageSize:10,pageNum:this.pageNum}}).then((res)=>{this.loading = false;this.list = this.list.concat(res.list);if(res.hasNextPage){this.busy = false;}else{this.busy = true;}})}

busy:false; 滚动加载是否触发(true表示不触发)


原生实现加载更多

需要三个高度:scrollHeight(文档内容实际高度,包括超出视窗的溢出部分)、

​ scrollTop(滚动条滚动距离)、

​ clientHeight(窗口可视范围高度)。

当 clientHeight + scrollTop >= scrollHeight 时,表示已经抵达内容的底部了,可以加载更多内容。

// Js代码
window.onscroll= function(){//文档内容实际高度(包括超出视窗的溢出部分)var scrollHeight = Math.max(document.documentElement.scrollHeight, document.body.scrollHeight);//滚动条滚动距离var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;//窗口可视范围高度var clientHeight = window.innerHeight || Math.min(document.documentElement.clientHeight,document.body.clientHeight);if(clientHeight + scrollTop >= scrollHeight){console.log("===加载更多内容……===");}
}

十一、项目优化

懒加载使用import的方式,由于import方式是ES7的语法,所以我们需要引入一个插件,来解析ES7的语法:@babel/plugin-syntax-dynamic-import

安装:npm install --save-dev @babel/plugin-syntax-dynamic-import

然后将路由改成按需加载的形式:

 {path: 'confirm',name: 'order-confirm',component: () => import('./pages/orderConfirm.vue')}

十二、总结

  • 对开发时请求后台数据设置跨域

  • 对sessionStorage进行封装

  • 对axios进行封装,设置拦截器,根据后端返回的不同状态码来进行不同响应设置

  • 使用cookie管理

  • 使用Vuex管理用户信息和购物车状态

  • 封装Modal弹框组件

  • 使用swiper轮播图组件

  • 使用elementUI美化页面,如何按需引入

  • 使用路由懒加载提高性能

  • 使用Scss的mixin对公共样式抽离

  • 使用图片懒加载

  • 使用微信、支付宝支付

更多推荐

【Vue】仿小米商城系统(四)

本文发布于:2024-03-23 20:53:12,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1742704.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:小米   商城   系统   Vue

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!