当前位置: 首页 > article >正文

微信小程序仿微信聊天界面

界面结构:

  • 消息列表: 使用 scroll-view 实现滚动,每条消息使用 view 组件包裹,根据消息类型 (文本、图片、文件) 显示不同内容。
  • 输入框区域: 包含输入框 (textarea)、发送按钮 (button) 和上传文件按钮 (view 组件模拟)。
  • 头像: 使用 image 组件展示。

功能实现:

  • 多行输入框高度自适应: 使用 textarea 组件的 auto-height 属性,并监听 linechange 事件动态调整高度。
  • 消息气泡样式: 使用 CSS 实现不同类型消息的气泡样式。
  • 发送消息: 点击发送按钮或输入框回车时,将消息内容添加到消息列表中,并清空输入框。
  • 上传文件: 点击上传文件按钮,调用小程序 API 选择文件并上传。

代码示例:

<!-- pages/chat/chat.wxml -->
<view class="container">
  <scroll-view class="message-list" scroll-y="true" style="height:{{scrollHeight}}px;">
    <view class="message-item {{item.isMe?'message-item-right':'message-item-left'}}" wx:for="{{messages}}" wx:key="index">
      <image class="avatar" src="{{item.isMe?'my-avatar.png':'other-avatar.png'}}"></image>
      <view class="message-content {{item.isMe?'message-content-right':'message-content-left'}}">
        <view wx:if="{{item.type === 'text'}}">{{item.content}}</view>
        <image wx:if="{{item.type === 'image'}}" src="{{item.content}}" mode="widthFix"></image>
        <view wx:if="{{item.type === 'file'}}" class="file-message">
          <text class="file-name">{{item.content.name}}</text>
          <text class="file-size">{{item.content.size}}</text>
        </view>
      </view>
    </view>
  </scroll-view>

  <view class="input-area">
    <view class="input-bar">
      <view class="upload-btn" bindtap="uploadFile">+</view>
      <textarea class="input-text" auto-height value="{{inputValue}}" bindinput="onInput" bindconfirm="sendMessage" placeholder="请输入消息内容" />
      <button class="send-btn" bindtap="sendMessage">发送</button>
    </view>
  </view>
</view>
// pages/chat/chat.js
Page({
  data: {
    scrollHeight: 0, // 滚动区域高度
    inputValue: '', // 输入框内容
    messages: [
      { isMe: false, type: 'text', content: '你好' },
      { isMe: true, type: 'text', content: '你好,请问有什么可以帮您?' },
    ],
  },

  // 页面加载时获取滚动区域高度
  onLoad: function () {
    const that = this;
    wx.getSystemInfo({
      success: function (res) {
        that.setData({
          scrollHeight: res.windowHeight - 50, // 50 为输入框区域高度
        });
      },
    });
  },

  // 监听输入框内容变化
  onInput: function (e) {
    this.setData({
      inputValue: e.detail.value,
    });
  },

  // 发送消息
  sendMessage: function () {
    if (this.data.inputValue.trim() === '') return;

    this.data.messages.push({
      isMe: true,
      type: 'text',
      content: this.data.inputValue,
    });

    this.setData({
      messages: this.data.messages,
      inputValue: '',
    });

    // 滚动到底部
    this.scrollToBottom();
  },

  // 上传文件
  uploadFile: function () {
    const that = this;
    wx.chooseMessageFile({
      count: 1, // 只允许选择一个文件
      type: 'all', // 可以选择任意类型的文件
      success: function (res) {
        const file = res.tempFiles[0];
        // 将文件信息添加到消息列表中
        that.data.messages.push({
          isMe: true,
          type: 'file',
          content: {
            name: file.name,
            size: that.formatFileSize(file.size),
          },
        });

        that.setData({
          messages: that.data.messages,
        });

        // 滚动到底部
        that.scrollToBottom();

        // TODO: 上传文件到服务器
        // wx.uploadFile({
        //   // ...
        // });
      },
    });
  },

  // 格式化文件大小
  formatFileSize: function (size) {
    if (size < 1024) {
      return size + 'B';
    } else if (size < 1024 * 1024) {
      return (size / 1024).toFixed(1) + 'KB';
    } else if (size < 1024 * 1024 * 1024) {
      return (size / (1024 * 1024)).toFixed(1) + 'MB';
    } else {
      return (size / (1024 * 1024 * 1024)).toFixed(1) + 'GB';
    }
  },

  // 滚动到底部
  scrollToBottom: function () {
    this.setData({
      scrollTop: 999999,
    });
  },
});
/* pages/chat/chat.wxss */
.container {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding-bottom: 0rpx;
  padding-bottom: constant(safe-area-inset-bottom); /*兼容 IOS<11.2*/
  padding-bottom: env(safe-area-inset-bottom); /*兼容 IOS>11.2*/
}

.message-list {
  flex: 1;
  padding: 20rpx;
}

.message-item {
  display: flex;
  padding-bottom: 20rpx;
}

.message-item-left {
  justify-content: flex-start;
}

.message-item-right {
  flex-direction: row-reverse;
}

.avatar {
  width: 80rpx;
  height: 80rpx;
  border-radius: 50%;
  margin: 10rpx;
}

.message-content {
  max-width: 70%;
  padding: 20rpx;
  border-radius: 10rpx;
}

.message-content-left {
  background-color: #77dbd3;
}

.message-content-right {
  background-color: #9eea6a;
}

.input-area {
  height: 50px;
  padding: 10rpx;
  background-color: #f6f6f6;
}

.input-bar {
  display: flex;
  align-items: center;
  background-color: #fff;
  border-radius: 10rpx;
}

.upload-btn {
  width: 40rpx;
  height: 40rpx;
  line-height: 40rpx;
  text-align: center;
  margin-left: 10rpx;
  background-color: #f6f6f6;
  border-radius: 50%;
}

.input-text {
  flex: 1;
  height: 80rpx;
  padding: 10rpx;
  font-size: 28rpx;
  line-height: 40rpx;
}

.send-btn {
  width: 120rpx;
  height: 80rpx;
  line-height: 80rpx;
  text-align: center;
  margin-left: 10rpx;
  background-color: #07c160;
  color: #fff;
  border-radius: 10rpx;
}

.file-message {
  display: flex;
  flex-direction: column;
}

.file-name {
  font-size: 24rpx;
}

.file-size {
  font-size: 20rpx;
  color: #999;
}

注意:

  • 代码中只实现了基本功能,还有很多细节可以优化,例如消息时间显示、图片预览、文件下载等。
  • 上传文件功能需要配合后端接口实现。
  • 样式可以根据实际需求进行调整。

希望以上代码可以帮助你!


http://www.kler.cn/news/294357.html

相关文章:

  • 【spring】does not have member field ‘com.sun.tools.javac.tree.JCTree qualid
  • 【网络安全】密码学概述
  • 『功能项目』更换URP场景【32】
  • 【BUUCTF】HardSQL
  • 交换两个变量数值的3种方法
  • 创建Hive表后,查看表结构发现中文注释乱码
  • 【C++模版初阶】——我与C++的不解之缘(七)
  • Maven使用指南的笔记
  • 笔试强训,[NOIP2002普及组]过河卒牛客.游游的水果大礼包牛客.买卖股票的最好时机(二)二叉树非递归前序遍历
  • uniapp使用uni-popup做底部弹出选项(vue3)
  • R语言中rds 文件是什么,都保存了什么数据,详解
  • 宠物浮毛对身体危害竟这么大?再不预防就来不及了
  • Selenium4.0详细介绍
  • 龙芯+FreeRTOS+LVGL实战笔记(新)——05部署主按钮
  • 从零开始,认识游戏设计师(4)体验源于设计师②
  • 数据结构----链表
  • C# 特性与属性的区别
  • iOS 中,用户点击一个按钮到响应的全部流程
  • 【网络安全】服务基础第二阶段——第二节:Linux系统管理基础----Linux统计,高阶命令
  • 利用Spring Boot打造图书个性化推荐平台
  • C语言练习题之 数组中出现次数超过一半的数
  • C# 通过拖控件移动窗体
  • MySQL · 性能优化 · 提高查询效率的实用指南(上)
  • 第十四节:学习Springboot 的restful接口风格(自学Spring boot 3.x的第三天)
  • ROADM(可)-介绍
  • 【Linux网络编程】协议|OSI模型|TCP/IP模型|局域网通信|跨网络通信|地址管理|流程图
  • Kafka和ES加密
  • 深度学习dataset等概念
  • 【杂谈】-国产单片机学习成本高的原因分析
  • Deep Ocr