【uniapp】仿微信通讯录列表实现

效果图

【uniapp】仿微信通讯录列表实现_第1张图片

代码实现

<view class="main-container">
    
    <scroll-view
        class="member-list"
        :style="computedHeight"
        :scroll-y="true"
        :enable-back-to-top="true"
        :scroll-with-animation="true"
        :scroll-into-view="toView"
        :scroll-top="scrollTop"
        @scroll="onScroll"
    >
        <view class="list-wrap">
            <view class="category">发起人view>
            <view class="list-item">
                <image class="list-item-img" :src="initiatorInfo.headUrl" />
                <view class="list-item-name">{{ initiatorInfo.nickName }}view>
            view>
        view>
        <view class="list-wrap last-wrap" v-for="(v, i) in memberList" :key="i" :id="v.sign == '#' ? 'intoView_' : 'intoView' + v.sign">
            <view class="category">{{ v.sign }} ({{ v.list.length }}人)view>
            <view class="list-item" v-for="item in v.list" :key="item.numberId">
                <image class="list-item-img" :src="item.headUrl" />
                <view class="list-item-name">{{ item.nickName }}view>
                <view class="list-item-btn" @click="handleRemove(item)" v-if="item.userType != 'System'">将TA移出view>
            view>
        view>
    scroll-view>
    
    <scroll-view class="letter-list">
        <view :class="['letter-item', activeLetter == '↑' ? 'active' : '']" @click.stop="toTop" @touchend.stop="handleTouchEnd">view>
        
        <view :class="['letter-item', activeLetter == item ? 'active' : '']" v-for="(item, index) in allLetterList" :key="index" @click.stop="toLetter(item)" @touchend.stop="handleTouchEnd">
            {{ item }}
        view>
    scroll-view>
view>

需要下载js-pinyin包

npm install js-pinyin --save

引入js-pinyin包

import pinyin from 'js-pinyin'
data() {
    return {
        statusBarHeight: 0,
        initiatorInfo: {}, // 发起人
        groupNo: '',
        allLetterList: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '#'],
        memberList: [],
        scrollTop: 0,
        toView: '',
        activeLetter: ''
    }
},
computed: {
    computedHeight() {
        return { height: `calc(100vh - ${this.statusBarHeight}px - 54px )` }
    }
},
methods: {
    // 获取群组成员
    getList() {
        getGroupUserList({
            groupNo: this.groupNo
        }).then(res => {
            if (res.code == 'SUCCESS') {
                let userList = res.data.userList || []
                this.initiatorInfo = res.data.userList[0] || {}
                let arr = []
                this.allLetterList.forEach((item, index) => {
                    arr.push({
                        sign: item,
                        list: []
                    })
                })
                this.allLetterList.forEach((item, index) => {
                    userList.forEach(item2 => {
                        let firstLetter = pinyin.getCamelChars(item2.nickName)?.slice(0, 1)
                        if (firstLetter == item) {
                            arr[index].list.push(item2)
                        }
                        if (this.allLetterList.indexOf(firstLetter) == -1 && item == '#') {
                            arr[arr.length - 1].list.push(item2)
                        }
                    })
                })
                this.memberList = arr && arr.length ? arr.filter(item => item.list.length > 0) : []
            } else {
                // 弹出报错提示......
            }
        })
    },
    // 滚动
    onScroll(e) {
        this.scrollTop = e.detail.scrollTop
    },
    // 滚动到顶部
    toTop() {
        this.activeLetter = '↑'
        this.scrollTop = 0
    },
    // 滚动到星标好友
    toStar() {},
    // 滚动到某个字母位置
    toLetter(e) {
        this.activeLetter = e
        if (e == '#') {
            this.toView = 'intoView_'
        } else {
            this.toView = 'intoView' + e
        }
    },
    handleTouchEnd() {
        setTimeout(() => {
            this.activeLetter = ''
        }, 600)
    }
}
.main-container {
    width: 100%;
    height: 100%;
    padding: 20rpx 40rpx 0 24rpx;
    box-sizing: border-box;
    overflow-y: auto;
    position: relative;

    .member-list {
        box-sizing: border-box;

        .list-wrap {
            margin-top: 30rpx;
            .category {
                font-size: 24rpx;
                font-weight: 500;
                color: #adb3ba;
                line-height: 32rpx;
                margin-bottom: 20rpx;
            }
            .list-item {
                display: flex;
                align-items: center;
                margin-bottom: 40rpx;

                &-img {
                    width: 70rpx;
                    height: 70rpx;
                    background: #d8d8d8;
                    flex-shrink: 0;
                    border-radius: 50%;
                }
                &-name {
                    flex: 1;
                    font-size: 28rpx;
                    font-weight: 500;
                    color: #2d3f49;
                    line-height: 36rpx;
                    padding: 20rpx 16rpx 14rpx;
                }
                &-btn {
                    font-size: 24rpx;
                    font-weight: 500;
                    color: #ff466d;
                    line-height: 32rpx;
                    padding: 14rpx 21rpx;
                    flex-shrink: 0;
                    background: #ffedf1;
                    border-radius: 36rpx;
                }
            }
            .list-item:last-child {
                margin-bottom: 0;
            }
        }
        .last-wrap:last-of-type {
            padding-bottom: 30rpx;
        }
    }

    .letter-list {
        width: 32rpx;
        text-align: center;
        position: absolute;
        top: 50%;
        right: 6rpx;
        transform: translateY(-50%);

        .letter-item {
            width: 32rpx;
            height: 32rpx;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 22rpx;
            font-weight: 500;
            color: #999999;
            line-height: 32rpx;
        }
        .active {
            width: 32rpx;
            height: 32rpx;
            background: #fb5c4e;
            color: #fff;
            border-radius: 50%;
        }
    }
}

你可能感兴趣的:(CSS,JavaScript,uni-app)