uni-app页面使用u-view组件简化版列表页+详情页实现
本文介绍了一个简洁的项目列表页和详情页Vue实现方案。列表页包含顶部导航、状态筛选Tab、项目列表展示、搜索功能以及分页加载逻辑,采用模拟数据进行演示。详情页展示项目基本信息、描述和快捷操作入口,包含加载状态处理。代码特点包括:功能完整但简洁,添加了清晰注释,采用语义化命名和组件化设计,便于扩展和复用。该实现不依赖后端API,适合学习分享,展示了常见的列表-详情交互模式。
列表页 (SimpleList.vue)
<template><view class="container"><!-- 顶部导航 --><cu-custom bgColor="bg-blue" :isBack="true"><block slot="content">项目列表</block><block slot="right"><span @click="showSearch = true"><u-icon name="search" color="#fff" size="28"></u-icon></span></block></cu-custom><!-- 状态筛选Tab --><view class="tabs"><view v-for="(tab, index) in tabs" :key="index":class="['tab', activeTab === index ? 'active' : '']"@click="switchTab(index)">{{ tab }}</view></view><!-- 项目列表 --><scroll-view scroll-y class="list"@scrolltolower="loadMore"refresher-enabled:refresher-triggered="refreshing"@refresherrefresh="refreshData"><view v-for="(item, i) in listData" :key="i" class="item"@click="goDetail(item.id)"><view class="item-header"><text class="title">{{ item.name }}</text><text class="time">{{ item.startDate }} 至 {{ item.endDate }}</text></view><view class="item-footer"><view class="manager"><u-avatar :src="item.avatar" size="24"></u-avatar><text>{{ item.manager }}</text></view><view class="progress"><text>进度: {{ item.progress }}%</text><view class="progress-bar"><view class="progress-inner" :style="{width: item.progress + '%'}"></view></view></view></view></view><u-loadmore :status="loadStatus" /></scroll-view><!-- 搜索面板 --><u-popup v-model="showSearch" mode="bottom" border-radius="20"><view class="search-panel"><view class="search-title">项目搜索</view><u-form :model="searchForm"><u-form-item label="项目名称"><u-input v-model="searchForm.name" placeholder="请输入项目名称" /></u-form-item><u-form-item label="负责人"><u-input v-model="searchForm.manager" placeholder="请输入负责人" /></u-form-item><u-form-item label="状态"><u-radio-group v-model="searchForm.status"><u-radio :name="0">全部</u-radio><u-radio :name="1">进行中</u-radio><u-radio :name="2">已完成</u-radio></u-radio-group></u-form-item></u-form><view class="search-buttons"><u-button type="default" @click="resetSearch">重置</u-button><u-button type="primary" @click="doSearch">搜索</u-button></view></view></u-popup></view>
</template><script>
export default {data() {return {tabs: ['全部', '进行中', '已完成', '已延期'],activeTab: 0,listData: [],page: 1,loadStatus: 'loadmore',refreshing: false,showSearch: false,searchForm: {name: '',manager: '',status: 0}}},onLoad() {this.loadData()},methods: {// 加载数据loadData() {// 模拟API请求setTimeout(() => {// 模拟数据const mockData = Array.from({length: 10}).map((_, i) => ({id: 'proj-' + (this.page * 10 + i),name: `示例项目${this.page * 10 + i}`,startDate: '2023-01-01',endDate: '2023-12-31',manager: ['张经理', '李主管', '王总监'][i % 3],avatar: '',progress: Math.floor(Math.random() * 100),status: [0, 1, 2][Math.floor(Math.random() * 3)] // 0-待启动 1-进行中 2-已完成}))if (this.page === 1) {this.listData = mockData} else {this.listData = [...this.listData, ...mockData]}this.loadStatus = this.page >= 3 ? 'nomore' : 'loadmore'this.refreshing = false}, 800)},// 切换TabswitchTab(index) {this.activeTab = indexthis.page = 1this.loadData()},// 加载更多loadMore() {if (this.loadStatus === 'nomore') returnthis.page++this.loadData()},// 下拉刷新refreshData() {this.refreshing = truethis.page = 1this.loadData()},// 重置搜索resetSearch() {this.searchForm = {name: '',manager: '',status: 0}},// 执行搜索doSearch() {this.showSearch = falsethis.page = 1this.loadData()},// 跳转详情goDetail(id) {uni.navigateTo({url: '/pages/project/SimpleDetail?id=' + id})}}
}
</script><style lang="scss">
.container {background-color: #f5f5f5;min-height: 100vh;
}.tabs {display: flex;background: #fff;padding: 20rpx 0;.tab {flex: 1;text-align: center;font-size: 28rpx;color: #666;&.active {color: #409EFF;font-weight: bold;}}
}.list {height: calc(100vh - 180rpx);padding: 20rpx;
}.item {background: #fff;border-radius: 12rpx;padding: 24rpx;margin-bottom: 20rpx;.item-header {margin-bottom: 20rpx;.title {font-size: 32rpx;font-weight: bold;color: #333;display: block;margin-bottom: 10rpx;}.time {font-size: 24rpx;color: #999;}}.item-footer {display: flex;justify-content: space-between;align-items: center;padding-top: 15rpx;border-top: 1px solid #f0f0f0;.manager {display: flex;align-items: center;font-size: 26rpx;color: #666;text {margin-left: 10rpx;}}.progress {text-align: right;font-size: 24rpx;color: #999;.progress-bar {width: 150rpx;height: 8rpx;background: #eee;border-radius: 4rpx;margin-top: 5rpx;overflow: hidden;.progress-inner {height: 100%;background: #409EFF;border-radius: 4rpx;}}}}
}.search-panel {padding: 30rpx;.search-title {font-size: 32rpx;font-weight: bold;text-align: center;margin-bottom: 30rpx;}.search-buttons {display: flex;margin-top: 40rpx;gap: 20rpx;button {flex: 1;}}
}
</style>
详情页 (SimpleDetail.vue)
<template><view class="container"><!-- 顶部导航 --><cu-custom bgColor="bg-blue" :isBack="true"><block slot="content">项目详情</block></cu-custom><!-- 加载状态 --><u-loading mode="circle" v-if="loading"></u-loading><!-- 内容区域 --><view v-else class="content"><!-- 基本信息 --><view class="card"><view class="title">{{ detail.name }}</view><view class="info-row"><text class="label">时间:</text><text class="value">{{ detail.startDate }} 至 {{ detail.endDate }}</text></view><view class="info-row"><text class="label">负责人:</text><view class="value"><u-avatar :src="detail.avatar" size="30"></u-avatar><text style="margin-left:10rpx">{{ detail.manager }}</text></view></view><view class="info-row"><text class="label">进度:</text><view class="progress"><text>{{ detail.progress }}%</text><view class="progress-bar"><view class="progress-inner" :style="{width: detail.progress + '%'}"></view></view></view></view></view><!-- 项目描述 --><view class="card"><view class="section-title">项目描述</view><view class="desc">{{ detail.desc || '暂无描述' }}</view></view><!-- 快捷操作 --><view class="card"><view class="section-title">快捷操作</view><view class="actions"><view class="action-item" @click="goPage('task')"><u-icon name="list" size="40" color="#409EFF"></u-icon><text>查看任务</text></view><view class="action-item" @click="goPage('file')"><u-icon name="file-text" size="40" color="#409EFF"></u-icon><text>项目文件</text></view></view></view></view></view>
</template><script>
export default {data() {return {loading: true,detail: {}}},onLoad(options) {if (options.id) {this.loadDetail(options.id)}},methods: {// 加载详情数据loadDetail(id) {this.loading = true// 模拟API请求setTimeout(() => {this.detail = {id: id,name: `示例项目 ${id.slice(-3)}`,startDate: '2023-01-01',endDate: '2023-12-31',manager: '张经理',avatar: '',progress: 65,desc: '这是一个示例项目,用于演示详情页的实现。实际项目中这里会显示项目的详细描述信息,包括项目背景、目标、关键节点等内容。'}this.loading = false}, 800)},// 跳转页面goPage(type) {const urlMap = {task: '/pages/project/task?id=' + this.detail.id,file: '/pages/project/file?id=' + this.detail.id}if (urlMap[type]) {uni.navigateTo({url: urlMap[type]})}}}
}
</script><style lang="scss">
.container {background-color: #f5f5f5;min-height: 100vh;
}.content {padding: 20rpx;
}.card {background: #fff;border-radius: 12rpx;padding: 24rpx;margin-bottom: 20rpx;.title {font-size: 36rpx;font-weight: bold;margin-bottom: 20rpx;color: #333;}.info-row {display: flex;margin-bottom: 15rpx;font-size: 28rpx;.label {color: #666;width: 120rpx;}.value {flex: 1;color: #333;display: flex;align-items: center;}.progress {flex: 1;.progress-bar {width: 100%;height: 8rpx;background: #eee;border-radius: 4rpx;margin-top: 5rpx;overflow: hidden;.progress-inner {height: 100%;background: #409EFF;border-radius: 4rpx;}}}}.section-title {font-size: 30rpx;font-weight: bold;margin-bottom: 20rpx;color: #333;padding-bottom: 10rpx;border-bottom: 1px solid #f0f0f0;}.desc {font-size: 28rpx;color: #333;line-height: 1.6;}.actions {display: flex;justify-content: space-around;padding: 20rpx 0;.action-item {display: flex;flex-direction: column;align-items: center;text {margin-top: 10rpx;font-size: 26rpx;color: #666;}}}
}
</style>
特点说明
简洁性:
列表页仅保留核心功能:Tab切换、搜索、下拉刷新、上拉加载
详情页展示基本信息、描述和快捷操作入口
易读性:
添加了清晰的注释说明
使用语义化的class命名
保持一致的代码风格
功能性:
列表页包含完整的分页逻辑
详情页有加载状态处理
保留了必要的交互功能
可扩展性:
数据结构清晰,易于添加新字段
组件化设计,方便复用
适合分享:
使用模拟数据,不依赖后端API
无敏感业务信息
完整的功能演示