uni-app 即时聊天:制作分组导航
样式图
效果图
制作方法
用户分组
制作分组导航首先要做的就是将用户分组,在这个项目中我是根据用户昵称的首字母来进行分组的,所以就需要==将汉字转为拼音==,转换的方法大家可以在网上搜索,另外就是这个操作你可以在前端执行也可以在后端执行,当然还是在前端执行比较好,我是在后端执行好的,只作为参考,方法如下:
javascript
let result = await Friend.findOne({ userID: tokenRes.id }).populate("friend_list.user", "avatars")
let friend_list = result.friend_list
// 生成大写字母并生成分组对象
let val = {}
for (var i = 0; i < 26; i++) {
let res = String.fromCharCode(65 + i);
val[res] = []
}
// 将好友昵称文字转为拼音并将放入分组对象中
for (let i = 0; i < friend_list.length; i++) {
let reg = new RegExp("^[a-zA-Z]") //匹配备注是以字母开头的
let initial = null
if (reg.test(friend_list[i].nickName)) { //如果备注是以字母开头的
initial = friend_list[i].nickName.substr(0, 1)
} else { //备注是文字开头 chineseToPinYin是汉字转为拼音的方法
let pinyin = chineseToPinYin(friend_list[i].nickName)
initial = pinyin.substr(0, 1)
}
initial = initial.toUpperCase()
val[initial].push(friend_list[i])
}
return { friends: val, total: friend_list.length, friend_list }
最终返回给前端的好友分组数据格式(示例)如下:
json
//每个分组的是一个数组,数组里面包含着对应的用户对象
//每个用户对象都有对应的属性(这里省略不写)
{
A:[{},{}]
B:[{},{},{}]
C:[{},{}]
D:[{},{}]
E:[]
...
}
数据接收到后就可以在前端展示出来
HTML
<!-- getFriends是好友分组对象 -->
<template v-for="(value, key, index) in getFriends">
<view class="ground" v-if="value.length > 0">
<!--
下面这句代码是对应的分组:A,B,C,D 需要绑定好id,
后面跳转的时候是根据id来跳转的
-->
<view class="ground-item" :id="key">{{ key }}</view>
<!--将分组里的好友遍历出来-->
<view class="item"
v-for="(item, index) in value"
:key="item._id"
@tap="goInfo(item.user._id)">
<view class="item-left">
<view class="imgbox">
<image :src="item.user.avatars" mode="aspectFill">
</image>
</view>
</view>
<view class="item-right">{{ item.nickName }}</view>
</view>
</view>
</template>
制作分组导航条
制作这个的方式是比较简单的,方法如下 js代码
javascript
// 生成左侧的字母导航条
getAlphabet() {
//这种方式是生成26个字母,但是可能有的分组是没有好友的
// for (var i = 0; i < 26; i++) {
// let res = String.fromCharCode(65 + i);
// this.alphabet.push(res);
// }
this.alphabet = []
//这种是根据分组是否有好友,有则生成对应分组,没有则不生成分组
for (let key in this.getFriends) {
if (this.getFriends[key].length > 0) {
this.alphabet.push(key);
}
}
},
html代码
HTML
/* data-value 是自定义属性,需要根据这个来知道应该跳转的分组是哪个*/
<view class="alnavbar" @tap="clickAlnavbar">
<view class="al-item" data-value="top">↑</view>
<view class="al-item"
v-for="(item, index) in alphabet"
:key="index"
:data-value="item"
>
{{ item }}
</view>
</view>
跳转的方法
javascript
// 点击左边的字母导航进行跳转
clickAlnavbar(event) {
//每次跳转的时候先返回到顶部,避免计算出错
uni.pageScrollTo({
duration: 0,
scrollTop: 0
});
if (event.target.dataset.value == 'top') {
//这是返回顶部,因为跳转的时候都是先返回到顶部,所以不需要继续执行以下代码
return;
}
let id = '#' + event.target.dataset.value;
uni.createSelectorQuery()
.select(id)
.boundingClientRect(res => {
if (res) {
let top = res.top;
// #ifdef APP-PLUS
uni.pageScrollTo({
duration: 0,
scrollTop: top - 68
});
// #endif
// #ifdef H5
uni.pageScrollTo({
duration: 0,
scrollTop: top - 48
});
// #endif
}
})
.exec();
},