更新记录

1.0.2(2025-12-09)

调整兼容范围

1.0.1(2025-12-09)

更新 readme, JS 部分讲解

1.0.0(2025-12-09)

第一次版本上传

查看更多

平台兼容性

uni-app(3.6.15)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
- - - - -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 快应用-华为 快应用-联盟
- - - - - - - - - -

其他

多语言 暗黑模式 宽屏模式
× ×

聊天界面 自定义的scroll

类似 scroll-view, 直接在组件内 使用插槽循环你的聊天记录就行

重点讲在前面, 这个重要的点在于高度, 一定下载示例项目看看

在示例项目中有演示 nowPageHeight 方案, 主要是去除 标题栏 + 输入框 + 安全区 高度,

标题栏 ( 纯示例,真实项目不要这样设置标题文字的位置, 不过标题栏高度可以这样用,而且自己能清晰的知道高度, 比用UI框架中方便 ) 高度一定考虑手机底部的安全区

组件内也实时响应了 这个高度 nowPageHeight

重重点

图片需要你自己记录高度, 插件内不计算你的图片, 只算你的dom 高度, 因为图片没加载出来的时候,dom高度不准确, 所以找个盒子初始化高度,并给图片做 最高高度 max-height

软键盘高度 用 @blur 去掉

示例中的阴影等等 效果都是组件外部的 css 样式, 组件只是一个容器

使用示例


<yy-chat-scroll ref="imScroll" :page-height="nowPageHeight" @loadMoreHistory="onLoadMoreHistory">
    <!-- 消息列表 -->
    <template #msg>
        <view class="main-box" :style="`min-height:${nowPageHeight}`">
            <view v-for="(msg, index) in msgList" :key="msg.id" class="my-msg-item" :class="{
                'bb-msg': !!!msg.is_self
            }">
                 {{ msg.text }}
            </view>
        </view>
    </template>
</yy-chat-scroll>

支持自定义的下拉刷新

loading loading2 是2种刷新状态

loading 是没到刷新阈值的状态

loading2 是达到阈值的状态

progress 是一个 0-1的值, 用于你自定义动画


<template #header="{ loading, loading2, progress }">
    <view class="my-header" :style="{
    transform: `translateY(${(1 - progress) * -20}px) scale(${0.8 + 0.2 * progress})`,
    opacity: 0.3 + 0.7 * progress
  }">
        <text v-if="loading">加载中 {{ Math.round(progress * 100) }}%</text>
        <text v-else-if="loading2">松开加载历史</text>
        <text v-else>下拉加载历史</text>
    </view>
</template>

讲下 JS 部分


// 这样 发送一个消息进聊天框
this.$refs.imScroll.addOne(func)

// 这样加载历史记录
this.$refs.imScroll.loadMoreHistory(func)

// func 要求是一个同步的函数

// 同步就是  func 不能返回一个 Promise, 就是  当  func 执行完成,  msgList 必须赋值完成

// 这样的func 可以
function func() {
    this.msgList = [...返回的data, ...this.msgList]
}

// 不可以的func
function func() {
    this.$api('api/getHistory').then(res=>{
        this.msgList = [...res.data, ...this.msgList]
    })
}

// 不可以的 func
function func() {
    this.$api({
        url: 'api/getHistory',
        success: res=>{
            this.msgList = [...res.data, ...this.msgList]
        }
    })
}

// Promise 转同步
async function func() {
    let result = await this.$api('api/getHistory')
    this.msgList = [...result.data, ...this.msgList]
}

// callback 转同步
function getHistory() {
    // 如果你的 this.$api  返回不是 Promise,  那么  你需要自己封装一个 Promise
    // 然后再别的地方调用这个 getHistory()
    return new Promise((resolve, reject) => {
        this.$api({
            url: 'api/getHistory',
            success: res => resolve(res),
            fail: err => reject(err)
        })
    })
    // 如果 this.$api 返回是 Promise,就像刚才那样用
}

async function func() {
    const res = await getHistory.call(this)
    this.msgList = [...res.data, ...this.msgList]
}

祝你用的愉快

__ 菜菜给菜菜的前女友造轮子

私信给我 想要什么功能

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。