uni-app 途径站点组件开发与实现分享

发布于:2025-07-11 ⋅ 阅读:(18) ⋅ 点赞:(0)

在移动应用开发中,涉及到出行、物流等场景时,途径站点的展示是一个常见的需求。本文将为大家分享一个基于 uni-app 开发的途径站点组件,该组件能够清晰展示路线中的各个站点信息,包括站点名称、到达时间、是否已到达等状态,希望能为有类似需求的开发者提供一些参考。

效果图

组件功能与设计思路

组件功能

这个途径站点组件主要实现了以下功能:

  • 按顺序展示路线中的所有途径站点;
  • 显示每个站点的名称、到达时间;
  • 通过不同的样式区分已到达站点、当前所在站点和未到达站点;
  • 支持点击站点查看详细信息。

设计思路

为了实现上述功能,我们采用了以下设计思路:

  • 采用垂直列表的形式展示站点,通过连接线将各个站点串联起来,直观体现路线的连贯性;
  • 使用不同的颜色和图标来区分站点的不同状态,已到达站点采用绿色图标和灰色文字,当前所在站点采用蓝色图标和黑色文字,未到达站点采用灰色图标和浅灰色文字;
  • 将组件拆分为站点列表和站点项两个部分,提高代码的复用性和可维护性;
  • 通过 props 接收外部传入的站点数据和相关配置,使组件具有更好的通用性。

组件实现步骤

1. 页面结构设计(template)

首先,我们来设计组件的页面结构。组件主要由站点列表容器和每个站点项组成,站点项中包含站点图标、站点信息和连接线。

<template>
	<view class="route-point">
		<view class="bus-itinerary">
			<view class="title">巴士行程</view>
			<text class="iconfont icon-guanbi" @click="onClose"></text>
			<view class="station-list">
				<block v-for="(item, index) in stationList" :key="index">
					<view v-if="index == startIndex" class="station-item start-station">
						<view class="station-name">
							<view class="text">北京丰台站</view>
							<view class="tips">您在该点上车</view>
						</view>
						<view class="time">预计08:00出发</view>
					</view>
					<view v-else-if="index == destIndex" class="station-item  dest-station">
						<view class="station-name">
							<view class="text">上海虹桥站</view>
							<view class="tips">您在该点下车</view>
						</view>
						<view class="time">预计08:00到达</view>
					</view>
					<view v-else-if="index == startIndex + 1" class="station-item">
						<view class="station-name" @click="onFlod">
							<view style="color: #333333;" class="text">途径5个站点<text class="iconfont icon-xiala"></text>
							</view>
						</view>
					</view>
					<view v-else class="station-item" :style="{color:index > startIndex ? '#333333' : '#999999'}">
						<view class="station-name">苏州北站</view>
						<view class="time">预计08:00{{ index > destIndex ? '到达' : '出发' }}</view>
					</view>
				</block>
				<view class="point-list">
					<block v-for="(item, index) in stationList" :key="index">
						<view class="point">
							<view class="dot"></view>
							<view v-if="index != stationList.length - 1" class="line"></view>
						</view>
					</block>
				</view>
			</view>
		</view>
	</view>
</template>

2. 样式设计(style)

接下来,我们为组件设计样式,使其具有良好的视觉效果。

<style lang="less" scoped>
	.route-point {
		width: 100%;
		height: 100%;
		background-color: rgba(0, 0, 0, .3);
		overflow: hidden;
		position: fixed;
		top: 0;
		left: 0;

		.bus-itinerary {
			position: absolute;
			left: 0;
			bottom: 0;
			width: 100%;
			background-color: #ffffff;
			overflow: hidden;
			padding: 40rpx;
			border-radius: 30rpx 30rpx 0 0;

			.title {
				font-weight: bold;
				font-size: 32rpx;
				margin-bottom: 20rpx;
			}

			.icon-guanbi {
				font-size: 40rpx;
				font-weight: bold;
				position: absolute;
				top: 30rpx;
				right: 40rpx;
			}

			.station-list {
				max-height: 50vh;
				overflow-y: scroll;
				padding-left: 40rpx;
				position: relative;

				.station-item {
					height: 100rpx;
					display: flex;
					align-items: center;
					font-size: 30rpx;
					color: #999999;

					.station-name {
						flex: 1;
						white-space: nowrap;
						overflow: hidden;
						text-overflow: ellipsis;

						.text {
							white-space: nowrap;
							overflow: hidden;
							text-overflow: ellipsis;

							.icon-xia {
								margin-left: 10rpx;
								font-weight: bold;
							}
						}
					}

					.time {
						flex-shrink: 0;
					}

					.tips {
						font-size: 26rpx;
						font-weight: 400;
					}
				}

				.start-station {
					font-weight: bold;
					color: #40ABDE;
				}

				.dest-station {
					font-weight: bold;
					color: #F7A22A;
				}

				.point-list {
					position: absolute;
					top: 42rpx;
					left: 10rpx;
					display: flex;
					flex-direction: column;
					align-items: center;

					.point {
						flex-shrink: 0;
						height: 100rpx;
						display: flex;
						flex-direction: column;
						align-items: center;

						.dot {
							flex-shrink: 0;
							width: 14rpx;
							height: 14rpx;
							background-color: #D7D7D7;
							border-radius: 50%;
						}

						.line {
							flex-shrink: 0;
							width: 2rpx;
							height: 70rpx;
							background-color: #999999;
							opacity: 0.2;
						}
					}
				}
			}
		}
	}
</style>

3. 逻辑实现(script)

最后,我们实现组件的逻辑部分,包括接收外部数据、处理点击事件等。

<script>
	export default {
		name: "route-point",
		data() {
			return {
				stationList: [1, 2, 3, 4, 5, 6],
				startIndex: 2,
				destIndex: 4,
				isFold: true,
			};
		},
		methods: {
			onFlod() {
				this.isFold = !this.isFold;
				console.log("是否折叠站点:", this.isFold)
				if (this.isFold) {
					this.stationList = [1, 2, 3, 4, 5, 6];
					this.destIndex = 4;
				} else {
					this.stationList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
					this.destIndex = 8;
				}
			},
			onClose() {
				this.$emit('onClose')
			}
		}
	}
</script>

组件使用示例

在页面中使用该组件时,只需引入组件并传入站点数据即可。

<template>
	<view class="container">
        <view @click="showRoutePoint = true">显示组件</view>
		<RoutePoint v-if="showRoutePoint" @onClose="onClosePoint"></RoutePoint>
	</view>
</template>

<script>
	import RoutePoint from '../../components/route-point.vue';
	export default {
		components: {
			RoutePoint
		},
		data() {
			return {
				showRoutePoint: true,
			}
		},
		onLoad() {

		},
		methods: {
			onClosePoint() {
				this.showRoutePoint = false;
			},
		}
	}
</script>

<style lang="scss" scoped>
	
</style>

通过以上步骤,我们完成了一个功能完善的 uni-app 途径站点组件。该组件具有良好的通用性和可扩展性,能够满足不同场景下的需求。希望本文的分享能对大家有所帮助,如果你有更好的想法或建议,欢迎在评论区交流讨论。


网站公告

今日签到

点亮在社区的每一天
去签到