• Vue项目流程7,交易页面,提交订单,支付页面,利用element UI 以及 QRCode 完成微信支付,弹出框按钮的相关工作,个人中心以及子路由我的订单


    交易页面

    1、静态组件及路由跳转
    2、获取交易页数据
    (1)接口

    //获取用户地址信息  地址:/api/user/userAddress/auth/findUserAddressList   请求方式:GET  参数:无
    export const reqAddressInfo = ()=> requests({url:'/user/userAddress/auth/findUserAddressList',method:'GET'})
    
    //获取商品清单  地址:/api/order/auth/trade   请求方式:GET   参数:无
    export const reqOrderInfo = ()=> requests({url:'/order/auth/trade',method:'GET'})
    
    • 1
    • 2
    • 3
    • 4
    • 5

    (2)新建小仓库trade.js书写vuex三连环

    import {reqAddressInfo,reqOrderInfo} from '@/api/index'
    const state ={
        adress:[],
        orderInfo:[]
    }
    const mutations ={
        GETUSERADDRESS(state,adress){
            state.adress == adress
        },
        GETORDERINFO(state,orderInfo){
            state.orderInfo = orderInfo
        }
    }
    const actions ={
        //获取用户地址信息
        async getUserAddress({commit}){
            let result = await reqAddressInfo()
            if(result.code == 200){
                commit('GETUSERADDRESS',result.data)
            }
        },
        //获取商品清单
        async getOrderInfo({commit}){
            let result = await reqOrderInfo()
            if(result.code == 200){
                commit('GETORDERINFO',result.data)
            }
        }
    }
    const getters ={}
    export default {
        state,
        mutations,
        actions,
        getters
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    (3)路由跳转时派发action,即交易页面挂载完毕

    mounted(){
      this.$store.dispatch('getUserAddress')
      this.$store.dispatch('getOrderInfo')
    }
    
    • 1
    • 2
    • 3
    • 4

    3、映射数据

      ...mapState({
        addressInfo:state => state.trade.address,
        orderInfo:state => state.trade.orderInfo
      }),
    
    • 1
    • 2
    • 3
    • 4

    4、展示数据

      //提交订单时的地址
      userDefaultAddress(){
        return this.addressInfo.find(item=> item.isDefault == 1) || {} 
      }
    
    • 1
    • 2
    • 3
    • 4

    5、给地址添加点击事件,点击时边框变红并设置为默认地址

    //修改默认地址
          changeDefault(address,addressInfo){
            //全部的isDefault为0
            addressInfo.forEach(item => item.isDefault = 0);
            address.isDefault = 1
          }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    find:查找数组中符合条件的元素返回作为最终结果

    提交订单

    1、路由跳转
    2、点击提交订单时,还需要向服务器发起一次请求并将支付的信息传递给服务器
    (1)接口

     //提交订单  地址:/api/order/auth/submitOrder?tradeNo={tradeNo}   请求方式:POST   参数:有
    export const reqSubmitOrder = (tradeNo,data)=> requests({url:`/order/auth/submitOrder?tradeNo=${tradeNo}`,data,method:'POST'})
    
    • 1
    • 2

    (2)组件内调用请求函数

    1. 将api文件夹里面全部请求函数统一引入在main.js文件中
    //统一引入api文件夹里的全部请求函数
    import * as API from '@/api'
    
    • 1
    • 2
    1. 全局事件总线所有API挂载到Vue原型上
    Vue.prototype.$API = API
    
    • 1

    支付页面

    1、静态组件
    2、使用编程式路由跳转
    3、在组件内调用请求函数

      //提交订单
      async submitOrder(){
        //需要带参
        let {tradeNo} = this.orderInfo
        let data = {
          consignee:this.userDefaultAddress.consignee,
          consigneeTel:this.userDefaultAddress.phoneNum,
          deliveryAddress:this.userDefaultAddress.fullAddress,
          paymentWay:'ONLINE',
          orderComment:this.msg,
          orderDetailList:this.orderInfo.detailArrayList
        }
        let result = await this.$API.reqSubmitOrder(tradeNo,data)
        if(result.code == 200){
          this.orderId = result.data
          //路由跳转+传参
          this.$router.push('/pay?orderId='+this.orderId)
        }else{
          alert(result.data)
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    4、数据展示orderId
    5、拿着orderId向服务器发请求获取订单信息
    (1)接口

    //获取支付信息  地址:/api/payment/weixin/createNative/{orderId}  请求方式:GET   参数:有
    export const reqPayInfo = (orderId)=> requests({url:`/payment/weixin/createNative/${orderId}`,method:'GET'})
    
    • 1
    • 2

    (2)在ThePay组件挂载完毕之后发请求

    mounted(){
      this.getPayInfo()
    },
    methods:{
      async getPayInfo(){
        let result = await this.$API.reqPayInfo(this.orderId)
        //如果成功在组件当中存储支付信息
        if(result.code == 200){
          this.payInfo = result.data
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    别在生命周期函数中async

    6、展示信息

    微信支付

    1、编程式导航
    2、elementUI使用
    安装:cnpm install --save element-ui
    按需加载:
    (1)借助babel-plugin-component,所以需要安装
    cnpm install babel-plugin-component -D
    (2)将babel.config.js文件修改一下,加入以下内容

      'plugins': [
        [
          'component',
          {
            'libraryName': 'element-ui',
            'styleLibraryName': 'theme-chalk'
          }
        ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在main.js文件中全局注册想要的组件
    重启项目
    引入注册:
    (1)main.js文件里引入import {MessageBox} from 'element-ui'
    (2)注册

    Vue.prototype.$msgbox = MessageBox
    Vue.prototype.$alert = MessageBox.alert
    
    • 1
    • 2

    使用:

      //弹出框
      open(){
        this.$alert('HTML',{
          dangerouslyUseHTMLString:true,
          center:true,
          //是否显示取消按钮
          showCancelButton:true,
          //取消按钮的文本内容
          cancelButtonText:'支付遇见问题',
          confirmButtonText:'已完成支付',
          //是否保留右上角取消按钮
          showClose:false
        })
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    React(Vue):antd[PC端]----antd-mobile[移动端]
    Vue:ElementUI[PC端]----vant[移动端]

    3、利用插件生成二维码
    安装:cnpm i qrcode --save
    引入: import QRCode from 'qrcode'
    使用:

       //生成二维码(地址)
        let url = await QRCode.toDataURL(this.payInfo.codeUrl)
        this.$alert(`${url} />`,'请你微信支付',{
    
    • 1
    • 2
    • 3

    4、二维码生成之后需要知道成功或失败,如果支付成功就路由跳转如果支付失败弹出提示信息,所以此时需要向服务器发请求。
    (1)接口

    //获取订单支付状态  地址:/api/payment/weixin/queryPayStatus/{orderId}  请求方式:GET   参数:有
    export const reqPayStatus = (orderId)=>requests({url:`/payment/weixin/queryPayStatus/${orderId}`,method:'GET'})
    
    • 1
    • 2

    (2)支付成功页面的静态组件已经路由配置
    (3)发请求

    if(!this.timer){
      this.timer = setInterval( async ()=>{
        //发请求获取用户状态
        let result = await this.$API.reqPayStatus(this.orderId)
        console.log(result);
        if(result.code==200){
          //第一步:清除定时器
          clearInterval(this.timer)
          this.timer = null
          //第二步:保存支付成功返回的code
          this.code = result.code
          //第三步:关闭弹出框
          this.$msgbox.close()
          //第四步:跳转到下一个路由
          this.$router.push('/paysuccess')
        }
      },1000)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    (4)弹出框按钮的相关工作,在element UI 方法里添加beforeClose属性

      //关闭弹出框的配置 第一参数:取消或完成  第二参数:当前组件实例  第三参数:关闭弹出框的方法
      beforeClose:(type,instance,done)=>{
        if(type=='cancel'){
          alert('请联系qq账号 3165281613')
          //清除定时器
          clearInterval(this.timer)
          this.timer = null
          //关闭弹出框
          done()
        }else{
          //判断是否真的支付了
          if(this.code == 200){
            //清除定时器
            clearInterval(this.timer)
            this.timer = null
            done()
            //路由跳转
            this.$router.push('/paysuccess')
          }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    此时需要使用到定时器,当用户没有支付即服务器返回的是未支付成功,此时需要一直向服务器发送请求,直到支付完成或是取消支付

    个人中心

    1、静态展示以及路由跳转,即从支付成功页面点击查看订单跳转到个人中心页面
    2、将个人中心右侧展示拆分成两个子路由,在center文件夹内新建myOrder和groupOrder文件夹
    3、注册子路由并且设置访问center时自动访问myorder

    //二级路由
    children:[
        {
            path:'myorder',
            component:MyOrder,
        },
        {
            path:'grouporder',
            component:GroupOrder,
        },
        {
            path:'/center',
            redirect:'/center/myorder'
        }
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    4、声名式导航

    <dd>
      <router-link to="/center/myorder">我的订单router-link>
    dd>
    <dd>
      <router-link to="/center/grouporder">团购订单router-link>
    dd>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    我的订单

    1、接口,获取我的订单列表

    //获取个人中心的数据  地址:/api/order/auth/{page}/{limit}  请求方式:GET   参数:有
    export const reqMyOrderList = (page,limit)=>requests({url:`/order/auth/${page}/${limit}`,method:'GET'})
    
    • 1
    • 2

    2、在MyOrder组件挂载完毕或是点击页码后发送请求

      data(){
        return{
        //当前第几页
        page:1,
        //每一页展示个数
        limit:3,
        //存储我的订单的数据
        myOrder:{}
        }
      },
      mounted(){
        //获取我的订单的数据的方法
        this.getData()
      },
      methods:{
        //获取我的订单的数据
        async getData(){
          //结构参数
          const{page,limit} = this
          let result = await this.$API.reqMyOrderList(page,limit)
          if(result.code == 200){
            this.myOrder = result.data
          }
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    3、数据展示

      <div class="orders">
        <table class="order-item" v-for="order in myOrder.records" :key="order.id">
          <thead>
            <tr>
              <th colspan="5">
                <span class="ordertitle"
                  >{{order.createTime}} 订单编号:{{order.outTradeNo}}
                  <span class="pull-right delete"
                    ><img src="../images/delete.png" />span
                >span>
              th>
            tr>
          thead>
          <tbody>
            <tr v-for="(cart,index) in order.orderDetailList" :key="cart.id">
              <td width="60%">
                <div class="typographic">
                  <img :src="cart.imgUrl" style="width:100px;height:100px;"/>
                  <a href="#" class="block-text">{{cart.skuName}}a
                  >
                  <span>x1span>
                  <a href="#" class="service">售后申请a>
                div>
              td>
              <td :rowspan="order.orderDetailList.length" v-if="index == 0" width="8%" class="center">{{order.consignee}}td>
              <td :rowspan="order.orderDetailList.length" v-if="index == 0" width="13%" class="center">
                <ul class="unstyled">
                  <li>总金额¥{{order.totalAmount}}li>
                  <li>在线支付li>
                ul>
              td>
              <td :rowspan="order.orderDetailList.length" v-if="index == 0" width="8%" class="center">
                <a href="#" class="btn">{{order.orderStatusName}}a>
              td>
              <td :rowspan="order.orderDetailList.length" v-if="index == 0" width="13%" class="center">
                <ul class="unstyled">
                  <li>
                    <a href="mycomment.html" target="_blank">评价|晒单a>
                  li>
                ul>
              td>
            tr>
          tbody>
        table>
      div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    4、设置分页器

      <div class="choose-order">
        
        <PagiNation
        :pageNo="page"
        :pageSize="limit"
        :total="myOrder.total"
        :continues="5"
        @getPageNo="getPageNo"
        />
      div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    //获取点击哪一页
    getPageNo(page){
      //修改组件响应式数据
      this.page = page
      this.getData()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    面试题:是否封装过组件?即可回答封装过如分页器、日历

  • 相关阅读:
    遥居前列!华为云GaussDB再获行业权威验证
    C# 看懂这100+行代码,你就真正入门了(经典)
    CleanMyMac X的免费版电脑系统瘦身工具
    用于设计和分析具有恒定近心点半径的低推力螺旋轨迹研究(Matlab代码实现)
    在Azure上使用Portal查出造成SQL注入攻击的语句
    动漫制作技术专业主要学什么?
    vue内置组件Transition的详解
    SCI如何审稿和修稿
    弹性资源组件elastic-resource设计(一)-架构
    ffmpeg视频编解码 demo初探(一)(包含下载指定windows版本ffmpeg)分离视频文件中的视频流每一帧YUV图片
  • 原文地址:https://blog.csdn.net/qq_49080239/article/details/126587887