Vue3电商项目实战-个人中心模块7【16-订单详情-steps组件、17-订单详情-物流信息】


16-订单详情-steps组件

目的:封装一个高可用的步骤条组件

在这里插入图片描述

大致步骤:

  • xtx-steps 封装一个静态步骤条
  • xtx-steps-item 封装步骤条-条目
  • xtx-steps 组织组件结构
  • xtx-steps 设置激活步骤
  • 使用steps组件显示订单进度

落的代码:

1.xtx-steps 封装一个静态步骤条

<template>
  <div class="xtx-steps">
    <div class="xtx-steps-item active" v-for="i in 5" :key="i">
      <div class="step"><span>{{i}}</span></div>
      <div class="title">提交订单</div>
      <div class="desc">2021-03-18 02:11:47</div>
    </div>
  </div>
</template>
<script>
export default {
  name: 'XtxSteps'
}
</script>
<style lang="less">
.xtx-steps {
  display: flex;
  text-align: center;
  &-item {
    flex: 1;
    &:first-child {
      .step {
        &::before {
          display: none;
        }
      }
    }
    &:last-child {
      .step {
        &::after {
          display: none;
        }
      }
    }
    &.active {
      .step {
        > span {
          border-color: @xtxColor;
          background: @xtxColor;
          color: #fff
        }
        &::before,&::after {
          background: @xtxColor;
        }
      }
      .title {
        color: @xtxColor;
      }
    }
    .step {
      position: relative;
      > span {
        width: 48px;
        height: 48px;
        font-size: 28px;
        border: 2px solid #e4e4e4;
        background: #fff;
        border-radius: 50%;
        line-height: 44px;
        color: #ccc;
        display: inline-block;
        position: relative;
        z-index: 1;
      }
      &::after,&::before{
        content: "";
        position: absolute;
        top: 23px;
        width: 50%;
        height: 2px;
        background: #e4e4e4;
      }
      &::before {
         left: 0;
      }
      &::after {
         right: 0;
       }
    }
    .title {
      color: #999;
      padding-top: 12px;
    }
    .desc {
      font-size: 12px;
      color: #999;
      padding-top: 6px;
    }
  }
}
</style>

2.xtx-steps-item 封装步骤条-条目
xtx-steps-item.vue

<script>
export default {
  name: 'XtxStepsItem',
  props: {
    title: {
      type: String,
      default: ''
    },
    desc: {
      type: String,
      default: ''
    }
  }
}
</script>

3.xtx-steps 组织组件结构
xtx-steps.vue

<script>
import { getCurrentInstance } from 'vue'
export default {
  name: 'XtxSteps',
  render () {
    const { ctx } = getCurrentInstance()
    const items = ctx.$slots.default()
    const dynamicItems = []
    items.forEach(item => {
      if (item.type.name === 'XtxStepsItem') {
        dynamicItems.push(item)
      } else {
        item.children.forEach(c => {
          dynamicItems.push(c)
        })
      }
    })
    const itemsJsx = dynamicItems.map((item, i) => {
      return <div class="xtx-steps-item">
        <div class="step"><span>{i + 1}</span></div>
        <div class="title">{item.props.title}</div>
        <div class="desc">{item.props.desc}</div>
      </div>
    })
    return <div class="xtx-steps">{itemsJsx}</div>
  }
}
</script>

使用

    <!-- 步骤条-->
    <XtxSteps>
      <XtxStepsItem title="提交订单" desc="2021-03-18 02:11:47" />
      <XtxStepsItem title="付款成功" desc="2021-03-18 02:11:47" />
      <XtxStepsItem title="商品发货" desc="2021-03-18 02:11:47" />
      <XtxStepsItem title="确认收货" />
      <XtxStepsItem title="订单完成" />
    </XtxSteps>

4.xtx-steps 设置激活步骤

  props: {
    active: {
      type: Number,
      default: 1
    }
  },
    const itemsJsx = dynamicItems.map((item, i) => {
+      return <div class="xtx-steps-item" class={{ active: i < props.active }}>
        <div class="step"><span>{i + 1}</span></div>
        <div class="title">{item.props.title}</div>
        <div class="desc">{item.props.desc}</div>
      </div>
    })

使用

<XtxSteps :active="3">

5.使用steps组件显示订单进度
src/views/member/order/components/detail-steps.vue

<template>
  <div class="detail-steps" style="padding:20px">
    <XtxSteps :active="order.orderState===6?1:order.orderState">
      <XtxStepsItem title="提交订单" :desc="order.createTime" />
      <XtxStepsItem title="付款成功" :desc="order.payTime" />
      <XtxStepsItem title="商品发货" :desc="order.consignTime" />
      <XtxStepsItem title="确认收货" :desc="order.evaluationTime" />
      <XtxStepsItem title="订单完成" :desc="order.endTime" />
    </XtxSteps>
  </div>
</template>
<script>
export default {
  props: {
    order: {
      type: Object,
      default: () => ({})
    }
  },
  name: 'DetailSteps'
}
</script>
<style scoped lang="less"></style>

src/views/member/order/index.vue

    <!-- 步骤条-->
    <DetailSteps :order="order" />
import DetailSteps from './components/detail-steps'
export default {
  name: 'OrderDetailPage',
  components: { DetailAction, DetailSteps },

17-订单详情-物流信息

大致步骤:

  • 基础布局
  • 获取数据,渲染
  • 使用 suspense 渲染 async setup 的组件
  • 复用订单列表的查看物流逻辑

落的代码:

1.基础布局

<template>
  <div class="detail-logistics">
    <p>
      <span>2016-09-14 15:00:32</span>
      <span>浦东转运中心公司 已收入</span>
    </p>
    <a href="javascript:;">查看物流</a>
  </div>
</template>
<script>
export default {
  name: 'DetailLogistics'
}
</script>
<style scoped lang="less">
.detail-logistics {
  height: 50px;
  display: flex;
  align-items: center;
  padding: 0 30px;
  background-color: #f5f5f5;
  margin: 30px 50px 0;
  > p {
    flex: 1;
    span {
      color: #999;
      &:first-child {
        margin-right: 30px;
      }
    }
  }
  > a {
    color: @xtxColor;
    text-align: center;
  }
}
</style>

2.获取数据,渲染

<template>
  <div class="detail-logistics" v-if="logistics">
    <p>
      <span>{{logistics.list[0].time}}</span>
      <span>{{logistics.list[0].text}}</span>
    </p>
    <a href="javascript:;">查看物流</a>
  </div>
  <!-- 查看物流组件 -->
  <Teleport to="#dailog">
    <OrderLogistics ref="logisticsOrderCom" />
  </Teleport>
</template>
<script>
import { ref } from 'vue'
import { logisticsOrder } from '@/api/order'
export default {
  name: 'DetailLogistics',
  props: {
    order: {
      type: Object,
      default: () => ({})
    }
  },
  async setup (props) {
    const logistics = ref(null)
    // 模拟加载时间
    const $sleep = () => new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve()
      }, 2000)
    })
    await $sleep()
    const data = await logisticsOrder(props.order.id)
    logistics.value = data.result
    return { logistics }
  }
}
</script>
<style scoped lang="less">
.detail-logistics {
  height: 50px;
  display: flex;
  align-items: center;
  padding: 0 30px;
  background-color: #f5f5f5;
  margin: 30px 50px 0;
  > p {
    flex: 1;
    span {
      color: #999;
      &:first-child {
        margin-right: 30px;
      }
    }
  }
  > a {
    color: @xtxColor;
    text-align: center;
  }
}
</style>

3.使用

    <!-- 物流区块 -->
+    <Suspense  v-if="[3,4,5].includes(order.orderState)">
+      <!-- 组件加载完毕 -->
+      <template #default>
+        <DetailLogistics :order="order" />
+      </template>
+      <!-- 组件加载中显示 -->
+      <template #fallback>
+        <div class="loading">loading</div>
+      </template>
+    </Suspense>
    <!-- 订单商品信息 -->
  </div>
</template>
<script>
+import DetailLogistics from './components/detail-logistics'
export default {
  name: 'OrderDetailPage',
+  components: { DetailAction, DetailSteps, DetailLogistics },

4.使用订单列表的查看物理逻辑
src/views/memner/order/index.vue

// 封装逻辑-查看物流
export const useLogisticsOrder = () => {

src/views/memner/order/components/detail-logistics.vue

import OrderLogistics from './order-logistics'
import { useLogisticsOrder } from '../index'
export default {
  name: 'DetailLogistics',
+  components: { OrderLogistics },
    const data = await logisticsOrder(props.order.id)
    logistics.value = data.result
+    return { logistics, ...useLogisticsOrder() }
+    <a href="javascript:;" @click="onLogisticsOrder(order)">查看物流</a>
  </div>
  <!-- 查看物流组件 -->
+  <Teleport to="#dailog">
+    <OrderLogistics ref="logisticsOrderCom" />
+  </Teleport>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值