我们在上一章节讲的是消息页开发,重点教大家如何封装组件,然后使用组件,以及父子组件的事件传递,目的是为了让大家对组件的基础知识有更深入的了解,我们在实际开发中,更多的是利用已开发好的组件来提升开发效率,避免重复造轮子,因此,我们既然已经引入了UI框架(uView),那么接下里的页面,我们将更多利用uView的组件,来完成页面开发。

# 一、 好友列表页开发

# 1. 顶部导航栏开发

  1. 新建好友列表页 pages/friendsList/friendsList.nvuepages.json
   {
        "path" : "pages/friendsList/friendsList",
        "style" : 
        {
            "navigationBarTitleText" : "好友列表",
            "navigationStyle": "custom"
        }
    }
  1. 在页面 pages/friendsList/friendsList.nvue
<template>
	<view>
		<!-- 导航栏 -->
		<chat-navbar title="好友列表" :fixed="true"
		:showPlus="false" :showUser="false"
		:showBack="true"></chat-navbar>
	</view>
</template>

<script>
	...
</script>

<style>
    /* #ifdef H5 */
	@import '/common/css/common.nvue.vue.css';
	/* #endif */
</style>

  1. 优化组件 /components/chat-navbar/chat-navbar.vue 导航栏
<template>
	<view>
		<!-- 导航栏 -->
		<view class="bg-light" :class="[fixed ? 'fixed-top' : '']">
			<!-- 状态栏 -->
			<view :style="'height:' + statusBarHeight + 'px;'"></view>
			<!-- 导航 -->
			<!-- #ifdef APP || H5 -->
			<view class="flex justify-between align-center"
			style="height: 90rpx;">
				<!-- 左边 -->
				<view class="flex align-center">
					<!-- 返回箭头 -->
					<chat-navbar-icon-button @click="navigateBack" v-if="showBack">
						<text class="ml-3 iconfont font-md" >&#xe68e;</text>
					</chat-navbar-icon-button>
					<!-- 标题 -->
					...
				</view>
				<!-- 右边 -->
				<view class="flex align-center">
					<chat-navbar-icon-button @click="openUser" v-if="showUser">
						<text class="iconfont font-lg">&#xe650;</text>
					</chat-navbar-icon-button>
					<chat-navbar-icon-button @click="openPlus" v-if="showPlus">
						<text class="iconfont font-md">&#xe655;</text>
					</chat-navbar-icon-button>
				</view>
			</view>
			<!-- #endif -->
			<!-- #ifdef MP -->
			<view class="flex align-center"
			style="height: 90rpx;justify-content: space-between;">
			    <!-- 左边 -->
				<view class="flex align-center flex-1">
					<!-- 返回箭头 -->
					<chat-navbar-icon-button @click="navigateBack" v-if="showBack">
						<text class="ml-3 iconfont font-md" >&#xe68e;</text>
					</chat-navbar-icon-button>
					<chat-navbar-icon-button @click="openPlus" v-if="showPlus">
						<text class="iconfont font-md">&#xe655;</text>
					</chat-navbar-icon-button>
					<chat-navbar-icon-button @click="openUser" v-if="showUser">
						<text class="iconfont font-lg">&#xe650;</text>
					</chat-navbar-icon-button>
				</view>
				<!-- 中间 -->
				...
				<!-- 右边 -->
				...
			</view>
			<!-- #endif -->
			
		</view>
		<!-- 占位符:占用 状态栏 + 导航栏的高度 -->
		...
		
		<!-- 导航栏点击加号的弹出菜单 -->
		...
	</view>
</template>

<script>
	import toolJS from '@/common/mixins/tool.js';
	export default {
		name:"chat-navbar",
		mixins:[toolJS],
		props:{
			...,
			// 是否显示加号图标
			showPlus:{
				type:Boolean,
				default:true
			},
			// 是否显示朋友列表图标
			showUser:{
				type:Boolean,
				default:true
			},
			// 是否显示返回箭头
			showBack:{
				type:Boolean,
				default:false
			},
		},
		...,
		methods: {
			openUser(){
				console.log('点击了通讯录图标');
				uni.navigateTo({
					url:'/pages/friendsList/friendsList'
				})
			},
			...
		},
	}
</script>

<style>
	...
</style>
  1. 混入mixins 新建 /common/mixins/tool.js
export default {
	methods: {
		//页面返回逻辑
		// 返回首页逻辑
		async redirectToHome() {
		    try {
		      // 优先尝试标准跳转
		      await uni.redirectTo({ url: '/pages/xiaoxi/xiaoxi' })
		    } catch (e) {
		          // 处理tab页情况
		          try {
			         await uni.switchTab({ url: '/pages/xiaoxi/xiaoxi' })
		          } catch (e) {
			          // 终极兜底方案
			         uni.reLaunch({ url: '/pages/xiaoxi/xiaoxi' }) 
		          }
		    }
		},
		//页面返回
		navigateBack() {
			const pages = getCurrentPages()
		    // 判断是否是分享进入的独立页面
			if (pages.length === 1 || pages.length === 0) {
			  // 尝试多种跳转方式确保可靠性
			  this.redirectToHome().catch(() => {
				uni.showToast({ title: '返回首页失败', icon: 'none' })
			  })
			} else {
			  uni.navigateBack()
			}
		},
	}
}

# 2. 好友列表开发

  1. 在UI框架(uView)中,提供了 IndexList 索引列表 这个组件:https://uviewui.com/components/indexList.html (opens new window) 帮我们快速开发这个页面。
  2. 大家可以在uni-app的插件市场:https://ext.dcloud.net.cn/plugin?id=1593 (opens new window)
  1. 使用HBuilderX导入示例项目 或者 下载示例项目压缩包导入HBuilderX查看示例。
  2. 当前列表样式用到示例项目中的: pages/componentsC/indexList/indexList.nvue

朋友列表静态页面完整代码: /pages/friendsList/friendsList.nvue

<template>
	<view>
		<!-- 导航栏 -->
		<chat-navbar title="好友列表" :fixed="true"
		:showPlus="false" :showUser="false"
		:showBack="true"></chat-navbar>
		
		<!-- 好友列表 -->
		<u-index-list :indexList="indexList">
			<view slot="header" class="list">
				<view class="list__item">
					<u-avatar shape="square" size="35" 
					icon="man-add-fill" fontSize="26" randomBgColor></u-avatar>
					<text class="list__item__user-name">新的朋友</text>
				</view>
				<u-line></u-line>
				<view class="list__item">
					<u-avatar shape="square" size="35" 
					icon="tags-fill" fontSize="26" randomBgColor></u-avatar>
					<text class="list__item__user-name">标签</text>
				</view>
				<u-line></u-line>
				<view class="list__item">
					<u-avatar shape="square" size="35" 
					icon="chrome-circle-fill" fontSize="26" randomBgColor></u-avatar>
					<text class="list__item__user-name">朋友圈</text>
				</view>
				<u-line></u-line>
				<view class="list__item">
					<u-avatar shape="square" size="35" 
					icon="qq-fill" fontSize="26" randomBgColor></u-avatar>
					<text class="list__item__user-name">QQ</text>
				</view>
				<u-line></u-line>
			</view>
			<!-- 列表部分 -->
			<template v-for="(item, index) in itemArr">
				<!-- #ifdef APP-NVUE -->
				<u-index-anchor :text="indexList[index]" :key="index"></u-index-anchor>
				<!-- #endif -->
				<u-index-item :key="index">
					<!-- #ifndef APP-NVUE -->
					<u-index-anchor :text="indexList[index]"></u-index-anchor>
					<!-- #endif -->
					<view class="list" v-for="(item1, index1) in item" :key="index1">
						<view class="list__item">
							<image class="list__item__avatar" :src="item1.url"></image>
							<text class="list__item__user-name">{{item1.name}}</text>
						</view>
						<u-line></u-line>
					</view>
				</u-index-item>
			</template>
			<view slot="footer" class="u-safe-area-inset--bottom">
				<text class="list__footer">共305位好友</text>
			</view>
		</u-index-list>
		
	</view>
</template>

<script>
	// 定义列表数据
	const indexList = () => {
		const indexList = []
		const charCodeOfA = 'A'.charCodeAt(0)
		indexList.push("↑")
		indexList.push("☆")
		for (let i = 0; i < 26; i++) {
			indexList.push(String.fromCharCode(charCodeOfA + i))
		}
		console.log('indexList当前数据',indexList);
		indexList.push('#')
		return indexList
	}
	export default {
		data() {
			return {
				indexList: indexList(),
				urls: [
					'https://docs-51yrc-com.oss-cn-hangzhou.aliyuncs.com/chat/avatar-01.png',
					'https://docs-51yrc-com.oss-cn-hangzhou.aliyuncs.com/chat/avatar-02.png',
					'https://docs-51yrc-com.oss-cn-hangzhou.aliyuncs.com/chat/avatar-03.png',
					'https://docs-51yrc-com.oss-cn-hangzhou.aliyuncs.com/chat/avatar-04.png',
					'https://docs-51yrc-com.oss-cn-hangzhou.aliyuncs.com/chat/avatar-05.png',
					'https://docs-51yrc-com.oss-cn-hangzhou.aliyuncs.com/chat/avatar-06.png',
					'https://docs-51yrc-com.oss-cn-hangzhou.aliyuncs.com/chat/avatar-07.png',
					'https://docs-51yrc-com.oss-cn-hangzhou.aliyuncs.com/chat/avatar-08.png',
					'https://docs-51yrc-com.oss-cn-hangzhou.aliyuncs.com/chat/avatar-09.png',
					'https://docs-51yrc-com.oss-cn-hangzhou.aliyuncs.com/chat/avatar-10.png',
				],
				names: ["晓明哥", "热巴", "GIGI梁咏琪", "古巨基", "古力娜扎", "阿祖",
					"力宏哥", "华仔", "黄奕", "刘涛", "林俊杰", "涛涛", 
					"阿力", "许文强", "周杰伦", "王心凌"
				]
			}
		},
		computed: {
			itemArr() {
				return this.indexList.map(item => {
					const arr = []
					for (let i = 0; i < 10; i++) {
						arr.push({
							name: this.names[uni.$u.random(0, this.names.length - 1)],
							url: this.urls[uni.$u.random(0, this.urls.length - 1)]
						})
					}
					return arr
				})
			}
		},
		methods: {
			
		}
	}
</script>

<style>
    /* #ifdef H5 */
	@import '/common/css/common.nvue.vue.css';
	/* #endif */
</style>
<style lang="scss">
	.list {
		
		&__item {
			@include flex;
			padding: 6px 12px;
			align-items: center;
			
			&__avatar {
				height: 35px;
				width: 35px;
				border-radius: 3px;
			}
			
			&__user-name {
				font-size: 16px;
				margin-left: 10px;
				color: $u-main-color;
			}
		}
		
		&__footer {
			color: $u-tips-color;
			font-size: 14px;
			text-align: center;
			margin: 15px 0;
		}
	}
</style>

# 二、我的页面开发

  1. pages.json
   {
        "path" : "pages/wode/wode",
        "style" : 
        {
            "navigationBarTitleText" : "我的",
            "navigationStyle": "custom"
        }
    },
  1. 在我的页面 pages/wode/wode.nvue
<template>
	<view>
		<!-- 头像昵称 -->
		<view :style="avatarTopStyle"
		class="px-3 pb-5">
			<view class="flex align-center justify-between">
				<!-- 头像 -->
				<view class="ml-1 mr-3">
					<u--image 
					src="https://docs-51yrc-com.oss-cn-hangzhou.aliyuncs.com/chat/avatar-01.png" 
					mode="widthFix"
					width="120rpx" height="120rpx" radius="20rpx"></u--image>
				</view>
				<!-- 昵称 -->
				<view class="flex flex-1 flex-column justify-center">
					<text class="font-weight-bold font-lg">小二哥</text>
					<view class="flex justify-between mt-2">
					   <text class="font text-light-muted">账号:xiaoerge001</text>
					   <text class="font-lg text-light-muted iconfont">&#xe657;</text>
					</view>
				</view>
			</view>
		</view>
		<!-- 间隔槽 -->
		<u-gap height="10" bgColor="#EDEDED"></u-gap>
		<!-- Cell 单元格 -->
		<u-cell-group>
			<u-cell icon="plus-people-fill" title="添加朋友" 
			:border="false" clickable isLink
			:customStyle="customStyles"
			:iconStyle="iconStyles"
			:titleStyle="titleStyles"></u-cell>
			<u-cell icon="chat" title="发起群聊"
			:border="false" clickable isLink 
			:customStyle="customStyles"
			:iconStyle="iconStyles"
			:titleStyle="titleStyles"></u-cell>
			<u-cell icon="scan" title="扫一扫" 
			:border="false" clickable isLink
			:customStyle="customStyles"
			:iconStyle="iconStyles"
			:titleStyle="titleStyles"></u-cell>
		</u-cell-group>
		<u-gap height="10" bgColor="#EDEDED"></u-gap>
		<u-cell-group>
			<u-cell icon="grid" title="我的二维码" 
			:border="false" clickable isLink
			:customStyle="customStyles"
			:iconStyle="iconStyles"
			:titleStyle="titleStyles"></u-cell>
		</u-cell-group>
		
	</view>
</template>

<script>
	export default {
		data() {
			return {
				statusBarHeight:0,//状态栏高度动态计算
				fixedHeight:0, //占位:状态栏+导航栏
			}
		},
		onLoad() {
			this.statusBarHeight = uni.getSystemInfoSync().statusBarHeight;
			this.fixedHeight = this.statusBarHeight + uni.upx2px(90);
		},
		computed:{
			avatarTopStyle(){
				return `padding-top:${this.fixedHeight}px;`
			},
			customStyles(){
				return `padding-top:20rpx;padding-bottom:20rpx;`;
			},
			iconStyles(){
				return `font-size:52rpx;margin-right:30rpx;color:#5696DA`;
			},
			titleStyles(){
				return `font-size:32rpx;`;
			}
		},
		methods: {
			
		}
	}
</script>

<style>
	/* #ifdef H5 */
	@import '/common/css/common.nvue.vue.css';
	/* #endif */
</style>

更新时间: 2025年6月15日星期日晚上7点08分