【vue3.0】22.0 某东到家( 廿二)——订单商品列表代码拆分和确认订单弹窗

目前src\views\orderConfirmation\OrderConfirmation.vue已有超过250行代码。这里将此组件进行拆分。
src\views\orderConfirmation\TopArea.vue

<template>
  <div class="top">
    <div class="top__bgcolor" />
    <div class="top__header">
      <div class="top__header__back" @click="handleBackClick">
        <i class="custom-icon custom-icon-back"></i>
      </div>
      <span>确认订单</span>
    </div>
    <div class="top__receiver">
      <div class="top__receiver__title">收货地址</div>
      <div class="top__receiver__address">
        西安一二三大学四五六科技园2号楼
      </div>
      <div class="top__receiver__info">
        <span class="top__receiver__info__name">张三(先生)</span>
        <span class="top__receiver__info__phone">18012341234</span>
      </div>
      <div class="top__receiver__icon">
        <i class="custom-icon custom-icon-back"></i>
      </div>
    </div>
  </div>
</template>
<script>
import { useRouter } from 'vue-router' // 路由跳转方法
export default {
  name: 'TopArea',
  setup() {
    const router = useRouter()
    const handleBackClick = () => {
      router.back()
    }

    return {
      handleBackClick
    }
  }
}
</script>
<style lang="scss" scoped>
@import '@/style/viriables.scss';
.top {
  position: relative;
  height: 1.96rem;
  background-size: 100% 1.59rem;
  /* 渐变轴为0度,相当于从下到上,
   高度4%位置从rgba(0, 145, 255, 0) 开始渐变
   到高度50%位置的蓝色(#0091ff)结束 */
  background-image: linear-gradient(
    0deg,
    rgba(0, 145, 255, 0) 4%,
    $btn-bg-color 50%
  );
  background-repeat: no-repeat;

  &__header {
    position: relative;
    padding-top: 0.26rem;
    line-height: 0.24rem;
    color: $bg-color;
    text-align: center;
    font-size: 0.16rem;
    &__back {
      position: absolute;
      font-size: 0.22rem;
      left: 0.18rem;
    }
  }
  &__receiver {
    position: absolute;
    left: 0.18rem;
    right: 0.18rem;
    bottom: 0rem;
    height: 1.11rem;
    background: $bg-color;
    border-radius: 0.04rem;
    &__title {
      line-height: 0.22rem;
      padding: 0.16rem 0 0.14rem 0.16rem;
      font-size: 0.16rem;
      color: $content-font-color;
    }
    &__address {
      line-height: 0.2rem;
      padding: 0 0.4rem 0 0.16rem;
      font-size: 0.16rem;
      color: $content-font-color;
    }
    &__info {
      padding: 0.06rem 0 0 0.16rem;
      &__name &__phone {
        margin-right: 0.1rem;
        line-height: 0.18rem;
        font-size: 0.12rem;
        color: $content-font-color;
      }
    }
    &__icon {
      //旋转180度
      transform: rotate(180deg);
      position: absolute;
      right: 0.16rem;
      top: 0.53rem;
      font-size: 0.16rem;
      color: $medium-font-color;
    }
  }
}
</style>

新建src\views\orderConfirmation\ProductList.vue

<template>
  <div class="products">
    <div class="products__title">{{ shopName }}</div>
    <div class="products__wrapper">
      <div class="products__list">
        <template v-for="item in productList" :key="item._id">
          <div class="products__item" v-if="item.count > 0">
            <img class="products__item__img" :src="item.imgUrl" />
            <div class="products__item__detail">
              <h4 class="products__item__title">{{ item.name }}</h4>
              <p class="products__item__price">
                <span>
                  <span class="products__item__yen"> &yen; </span>
                  {{ item.price }}×{{ item.count }}
                </span>
                <span class="products__item__total">
                  <span class="products__item__yen"> &yen; </span>
                  {{ (item.price * item.count).toFixed(2) }}
                </span>
              </p>
            </div>
          </div>
        </template>
      </div>
    </div>
  </div>
</template>
<script>
import { useCommonCartEffect } from '@/effects/cartEffects'
import { useRoute } from 'vue-router' // 路由跳转方法
export default {
  name: 'ProductList',
  setup() {
    const route = useRoute()
    const shopId = route.params.shopId // 店铺id
    const { shopName, productList } = useCommonCartEffect(shopId)

    return {
      shopName,
      productList,
    }
  },
}
</script>
<style lang="scss" scoped>
@import '@/style/viriables.scss';
@import '@/style/mixins.scss';
.products {
  margin: 0.16rem 0.18rem 0.2rem 0.18rem;
  background: $bg-color;
  &__title {
    padding: 0.16rem;
    font-size: 0.16rem;
    color: $content-font-color;
  }
  // list外层的wrapper容器
  &__wrapper {
    overflow-y: scroll;
    position: absolute;
    margin: 0 0.18rem;
    left: 0;
    right: 0;
    bottom: 0.6rem;
    top: 2.6rem;
  }
  &__list {
    background: $bg-color;
  }
  &__item {
    position: relative;
    display: flex;
    padding: 0 0.16rem 0.16rem 0.16rem;
    &__img {
      width: 0.46rem;
      height: 0.46rem;
      margin-right: 0.16rem;
    }
    // 配合解决超出长度以省略号显示而不会出现换行
    &__detail {
      overflow: hidden;
      flex: 1;
    }

    &__title {
      margin: 0;
      line-height: 0.2rem;
      font-size: 0.14rem;
      color: $content-font-color;
      // 超出长度以省略号显示而不会出现换行
      @include ellipsis;
    }
    &__price {
      display: flex;
      margin: 0.06rem 0 0 0;
      line-height: 0.2rem;
      font-size: 0.14rem;
      color: $height-light-font-color;
    }
    &__total {
      text-align: right;
      color: $dark-font-color;
      flex: 1;
    }
    &__yen {
      font-size: 0.12rem;
    }
  }
}
</style>

新增src\views\orderConfirmation\Order.vue

<template>
  <div class="order">
    <div class="order__price">
      实付金额 &yen;<b>{{ calculations.totalPrice }}</b>
    </div>
    <div class="order__btn">
      <!-- <router-link :to="{ path: `/orderConfirmation/${shopId}` }"> -->
      提交订单
      <!-- </router-link> -->
    </div>
  </div>
</template>
<script>
// import { ref } from 'vue'
import { useCommonCartEffect } from '@/effects/cartEffects'
import { useRoute } from 'vue-router' // 路由跳转方法

export default {
  name: 'Order',
  setup() {
    const route = useRoute()
    const shopId = route.params.shopId // 店铺id
    const { calculations } = useCommonCartEffect(shopId)

    return { calculations }
  },
}
</script>
<style lang="scss" scoped>
@import '@/style/viriables.scss';
.order {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  box-sizing: border-box; //往内塞入border
  line-height: 0.49rem;
  height: 0.49rem;
  border-top: 0.01rem solid $content-bg-color;
  background: $bg-color;
  &__price {
    flex: 1;
    text-indent: 0.24rem;
    font-size: 0.14rem;
    color: $content-font-color;
  }
  &__btn {
    width: 0.98rem;
    background-color: #4fb0f9;
    text-align: center;
    color: $bg-color;
    font-size: 0.14rem;
    // 去掉a标签的下划线
    a {
      color: $bg-color;
      text-decoration: none; //去掉文本修饰
    }
  }
}
</style>

修改src\views\orderConfirmation\OrderConfirmation.vue

<template>
  <div class="wrapper">
    <top-area />
    <product-list />
    <order />
  </div>
</template>

<script>
// import { ref } from 'vue'
import TopArea from '@/views/orderConfirmation/TopArea'
import ProductList from '@/views/orderConfirmation/ProductList'
import Order from '@/views/orderConfirmation/Order'
export default {
  name: 'OrderConfirmation',
  components: { TopArea, ProductList, Order },
}
</script>
<style lang="scss" scoped>
.wrapper {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  background-color: #eee;
  overflow-y: scroll; //防止超出屏幕
}
</style>

最终效果一致。

增加一个确认支付的弹窗

修改src\views\orderConfirmation\Order.vue

<template>
  <div class="order">
......
  </div>
  <div class="mask">
    <div class="mask__content">
      <div class="mask__content__title">确认离开收银台</div>
      <p>请尽快完成支付,否则将被取消</p>
      <div>
        <div class="mask__content__btn">取消订单</div>
        <div class="mask__content__btn">确认支付</div>
      </div>
    </div>
  </div>
</template>
<script>
......
</script>
<style lang="scss" scoped>
@import '@/style/viriables.scss';
.order {
......
}
.mask {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  z-index: 1;
  background: rgba(0, 0, 0, 0.5);
  &__content {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 3rem;
    height: 1.56rem;
    transform: translate(-50%, -50%);
    background: #fff;
    border-radius: 0.04rem;
    &__title {
      margin: 0.24rem 0 0 0;
      font-size: 0.18rem;
      color: #333;
      text-align: center;
    }
  }
}
</style>

image.png

进一步完善样式:

<template>
  <div class="order">
......
  </div>
  <div class="mask">
    <div class="mask__content">
      <div class="mask__content__title">确认离开收银台</div>
      <p>请尽快完成支付,否则将被取消</p>
      <div class="mask__content__btns">
        <div class="mask__content__btn mask__content__btn--first">取消订单</div>
        <div class="mask__content__btn mask__content__btn--second">
          确认支付
        </div>
      </div>
    </div>
  </div>
</template>
<script>
......
</script>
<style lang="scss" scoped>
@import '@/style/viriables.scss';
.order {
......
}
.mask {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: 0;
  z-index: 1;
  background: rgba(0, 0, 0, 0.5);
  &__content {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 3rem;
    height: 1.56rem;
    transform: translate(-50%, -50%);
    background: #fff;
    border-radius: 0.04rem;
    text-align: center;
    &__title {
      margin: 0.24rem 0 0 0;
      font-size: 0.18rem;
      color: #333;
    }
    &__desc {
      margin: 0.08rem 0 0 0;
      font-size: 0.14rem;
      color: #666;
    }
    &__btns {
      display: flex;
      margin: 0.24rem 0.58rem;
    }
    &__btn {
      flex: 1;
      width: 0.8rem;
      line-height: 0.32rem;
      border: 0.01rem solid #4fb0f9;
      border-radius: 0.16rem;
      font-size: 0.14rem;
      &--first {
        margin-right: 0.12rem;
        color: #4fb0f9;
      }
      &--second {
        margin-left: 0.12rem;
        color: #fff;
        background: #4fb0f9;
      }
    }
  }
}
</style>

image.png

完善按钮逻辑,进入fastmock增加一个post接口/api/createOrder

    /**
     * 输入
     * conten-type:json
     * body:{
       addressId:“xxx”//收货地址 id
       shopId:""//商店id
       shopName:"某什么码1",
       isCanceled:false,//订单是否被取消了
       products:[
       {
         id:"xxx",//商品id
         num:6//商品数量
       }, 
       {
         id:"xxx",//商品id
         num:6//商品数量
       },
       ]
     }
     **/
    {
      "code": 200,
      "data": {   _id: '1',},
      "desc": "成功"
    }

修改src\views\orderConfirmation\Order.vue

<template>
  <div class="order">
......
  </div>
  <div class="mask">
    <div class="mask__content">
      <div class="mask__content__title">确认离开收银台</div>
      <p>请尽快完成支付,否则将被取消</p>
      <div class="mask__content__btns">
        <div
          class="mask__content__btn mask__content__btn--first"
          @click="handleCancelOrder"
        >
          取消订单
        </div>
        <div
          class="mask__content__btn mask__content__btn--second"
          @click="handleConfirmOrder"
        >
          确认支付
        </div>
      </div>
    </div>
    <Toast v-if="show" :message="message" />
  </div>
</template>
<script>
// import { ref } from 'vue'
import { useCommonCartEffect } from '@/effects/cartEffects'
import { useRoute, useRouter } from 'vue-router' // 路由跳转方法
import { post } from '@/utils/request'
import Toast, { useToastEffect } from '@/components/Toast/Toast'
export default {
  name: 'Order',
  components: {
    Toast,
  },
  setup() {
    const route = useRoute()
    // 获取路由实例
    const router = useRouter()
    const shopId = route.params.shopId // 店铺id
    const { shopName, calculations, productList } = useCommonCartEffect(shopId)
    const handleCancelOrder = () => {}

    const { show, message, toastMsg } = useToastEffect()
    const handleConfirmOrder = async () => {
      try {
        console.log('productList:')
        console.log(productList)
        const products = []
        for (const i in productList.value) {
          const product = productList.value[i]
          products.push({ id: product._id, num: product.count })
        }
        console.log('products:')
        console.log(products)
        const resultData = await post('/api/createOrder', {
          addressId: 'xxx', // 收货地址 id
          shopId: shopId, // 商店id
          shopName: shopName.value,
          isCanceled: false, // 订单是否被取消了
          products: products,
        })
        console.log('post /api/createOrder:')
        console.log(resultData)
        if (resultData?.code === 200) {
          router.push({ name: 'Home' })
        } else {
          toastMsg('订单提交失败!')
        }
      } catch (e) {
        toastMsg('请求失败!')
      }
    }
    return {
      show,
      message,
      calculations,
      handleCancelOrder,
      handleConfirmOrder,
    }
  },
}
</script>
<style lang="scss" scoped>
......
</style>

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容