vue3+ts封装的一个uniapp的物流信息追踪

一、组件LogisticsTracker

<template>
  <view class="logistics-tracker">
    <view class="logistics-header">
      <view class="logistics-title">物流追踪</view>
      <view class="logistics-number">运单号:{{ trackingNumber }}</view>
    </view>

    <view class="logistics-timeline">
      <view
        v-for="(item, index) in logisticsInfo"
        :key="index"
        class="logistics-item"
        :class="{ 'logistics-item-active': index === 0 }"
      >
        <view class="logistics-item-left">
          <view class="logistics-dot"></view>
          <view
            v-if="index !== logisticsInfo.length - 1"
            class="logistics-line"
          ></view>
        </view>

        <view class="logistics-item-right">
          <view class="logistics-status">{{ item.status }}</view>
          <view class="logistics-desc">{{ item.description }}</view>
          <view class="logistics-info">
            <text class="logistics-time">{{ item.time }}</text>
            <text class="logistics-location">{{ item.location }}</text>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>

<script lang="ts" setup>
import { ref, defineProps } from "vue";

// 物流信息接口定义
interface LogisticsItem {
  status: string; // 物流状态
  description: string; // 物流描述
  time: string; // 时间
  location: string; // 地点
}

// 组件属性定义
const props = defineProps({
  trackingNumber: {
    type: String,
    required: true,
  },
  logisticsInfo: {
    type: Array as () => LogisticsItem[],
    required: true,
  },
});
</script>

<style lang="scss">
.logistics-tracker {
  background-color: #fff;
  border-radius: 12rpx;
  padding: 30rpx;
  margin: 20rpx;
  box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);

  .logistics-header {
    padding-bottom: 30rpx;
    border-bottom: 1rpx solid #f5f5f5;
    margin-bottom: 30rpx;

    .logistics-title {
      font-size: 32rpx;
      font-weight: bold;
      color: #333;
      margin-bottom: 10rpx;
    }

    .logistics-number {
      font-size: 26rpx;
      color: #666;
    }
  }

  .logistics-timeline {
    .logistics-item {
      display: flex;
      position: relative;

      &:last-child {
        .logistics-line {
          display: none;
        }
      }

      .logistics-item-left {
        width: 40rpx;
        position: relative;
        display: flex;
        flex-direction: column;
        align-items: center;

        .logistics-dot {
          width: 20rpx;
          height: 20rpx;
          border-radius: 50%;
          background-color: #ddd;
          z-index: 2;
        }

        .logistics-line {
          width: 2rpx;
          flex: 1;
          background-color: #ddd;
          margin-top: 4rpx;
          z-index: 1;
        }
      }

      .logistics-item-right {
        flex: 1;
        padding: 0 0 40rpx 20rpx;

        .logistics-status {
          font-size: 28rpx;
          font-weight: 500;
          color: #333;
          margin-bottom: 10rpx;
          line-height: 1.2;
        }

        .logistics-desc {
          font-size: 26rpx;
          color: #666;
          margin-bottom: 10rpx;
          line-height: 1.4;
        }

        .logistics-info {
          font-size: 24rpx;
          color: #999;
          display: flex;
          justify-content: space-between;

          .logistics-time {
            margin-right: 20rpx;
          }
        }
      }

      &-active {
        .logistics-item-left {
          .logistics-dot {
            width: 24rpx;
            height: 24rpx;
            background-color: #2979ff;
          }
        }

        .logistics-item-right {
          .logistics-status {
            color: #2979ff;
            font-weight: bold;
          }
        }
      }
    }
  }
}
</style>

二、使用logistics

<template>
  <view class="logistics-page">
    <logistics-tracker
      :tracking-number="trackingNumber"
      :logistics-info="logisticsData"
    />
  </view>
</template>

<script lang="ts" setup>
import { ref } from "vue";
// 组件路径根据自己实际项目引入
import LogisticsTracker from "../../components/LogisticsTracker.vue";

// 物流单号
const trackingNumber = ref("SF123xxxxxxxx23");

// 物流信息数据
const logisticsData = ref([
  {
    status: "已签收",
    description: "您的快递已由前台代签收,感谢您使用顺丰快递,期待再次为您服务",
    time: "2023-07-15 14:23:05",
    location: "北京市朝阳区",
  },
  {
    status: "派送中",
    description: "快递员 张xx (电话: 138xxxx5678) 正在为您派送",
    time: "2023-07-15 09:10:25",
    location: "北京市朝阳区",
  },
  {
    status: "运输中",
    description: "快件已到达 北京朝阳集散中心",
    time: "2023-07-14 20:15:37",
    location: "北京市朝阳区",
  },
  {
    status: "运输中",
    description: "快件已从 上海浦东集散中心 发出",
    time: "2023-07-13 18:30:42",
    location: "上海市浦东新区",
  },
  {
    status: "已揽收",
    description: "顺丰快递员已揽收",
    time: "2023-07-13 14:20:16",
    location: "上海市浦东新区",
  },
]);
</script>

<style lang="scss">
.logistics-page {
  min-height: 100vh;
  background-color: #f5f5f5;
  padding: 20rpx 0;
}
</style>

最终样式

11.png

样式根据设计稿可做调整

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容