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>