小程序模仿微信聊天界面

首先,这个消息聊天框的设计要考虑到:

  1. 消息的 发出者,接收者
  2. 消息的状态:已发(用数组保存起来);未发(输入值并获取)
  3. 手机端键盘弹起的高度对界面内容的展示的影响

 第一个问题  消息的 发出者,接收者

    这两种角色可以用一组对象完成,用speaker来定义两种角色,通过判断是哪一种角色进行循环遍历他们的消息内容

 第三个问题  手机端键盘弹起的高度对界面内容的展示的影响

    当键盘弹起时,我们所展示的聊天消息要展示当前的最后一条;所以我们要找到最后一条消息,通过 scroll-into-view 跳转到与其 id名一致的位置(可查看scroll-view的用法),通过为每一种角色数据的循环遍历,确定最后一条数据的位置;将整个页面的高度-键盘的高度=可视化的页面高度;将数据显示在这个可视化页面区域

wxml

<!--pages/message/detail-message/detail-message.wxml-->
<view>
  <van-nav-bar left-arrow title="标题" bind:click-left="onClickLeft" />

  <view>
    <scroll-view scroll-y scroll-into-view='{{toView}}' style='height: {{scrollHeight}};'>
      <block wx:key="*this" wx:for='{{msgList}}' wx:for-index="index">

        <!-- 单个消息1 客服发出(左) -->
        <view wx:if='{{item.speaker=="server"}}' id='msg-{{index}}' class="server">
          <view class="see-server">
            <image class="avatar" src='../../../icons/profiles/workbench-bg.jpg'>
            </image>
          </view>
          <view class="before-icon">
            <image src='../../../icons/message/left.png' mode='widthFix'></image>
          </view>
          <view class='leftMsg'>{{item.content}}</view>
        </view>

        <!-- 单个消息2 用户发出(右) -->
        <view wx:else id='msg-{{index}}' class="custom">
          <view class='rightMsg'>{{item.content}}</view>
          <view class="before-icon">
            <image src='../../../icons/message/right.png' mode='widthFix'></image>
          </view>
          <view style='width: 11vw; height: 11vw;'>
            <image class="avatar" src='{{picHead}}'></image>
          </view>
        </view>
      </block>
      <!-- 占位 -->
      <view class="site"></view>
    </scroll-view>

    <view class='inputRoom' style='bottom: {{inputBottom}}'>
      <input 
        bindconfirm='sendClick' 
        adjust-position='{{false}}' 
        value='{{inputVal}}' 
        confirm-type='send'
        bindfocus='focus' 
        bindblur='blur'
        class="send-input"
      ></input>
    </view>
  </view>
</view>

js

const app = getApp();
let inputVal = '';  //输入框的内容,未发
let msgList = [];   //聊天记录,已发
let windowWidth = wx.getSystemInfoSync().windowWidth;  //可使用屏幕宽度
let windowHeight = wx.getSystemInfoSync().windowHeight;//可使用屏幕高度
let keyHeight = 0; //键盘弹起高度

/**
 * 初始化数据
 */
function initData(that) {
  inputVal = '';
  msgList = [
    {
      speaker: 'server',
      contentType: 'text',
      content: '我是左边'
    },
    {
      speaker: 'customer',
      contentType: 'text',
      content: '我是右边'
    },
    {
      speaker: 'server',
      contentType: 'text',
      content: '左边已经收到右边来的数据'
    },
  ]
  that.setData({
    msgList,
    inputVal
  })
}

Page({

  /**
   * 页面的初始数据
   */
  data: {
    scrollHeight: '100vh', //这个高度一定要有
    inputBottom: 0,
    inputVal: '',
    picHead: '../../../icons/profiles/avatar.jpg'
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    initData(this);
    // this.setData({
    //   picHead: app.globalData.userInfo.picHead,
    // });
  },

  // 获取聚焦,键盘弹起
  focus: function(e) {
    keyHeight = e.detail.height;
    this.setData({
      scrollHeight: (windowHeight - keyHeight) + 'px'
    });
    this.setData({
      toView: 'msg-' + (msgList.length - 1),
      inputBottom: keyHeight + 'px'
    })
  },

  //失去聚焦(软键盘消失)
  blur: function(e) {
    this.setData({
      scrollHeight: '100vh',
      inputBottom: 0
    })
    this.setData({
      toView: 'msg-' + (msgList.length - 1)
    })

  },

  // 发送点击监听
  sendClick: function(e) {
    msgList.push({
      speaker: 'customer',
      contentType: 'text',
      content: e.detail.value
    })
    inputVal = '';
    this.setData({
      msgList,
      inputVal
    });
  },

  // nav栏返回
  onClickLeft() {
    wx.reLaunch({
      url: '/pages/message/message',
    })
  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})

wxss

page{
  background-color: #eee;
}
.van-nav-bar{
  padding: 0 !important;
}

.server{
  display: flex; 
  padding: 2vw 11vw 2vw 2vw;
}

.see-server{
  width: 11vw; 
  height: 11vw;
}

.avatar{
  width: 11vw; 
  height: 11vw; 
  border-radius: 10rpx;
}

.before-icon{
  position: relative;
  width: 4vw; 
  height: 11vw; 
  margin-left: 0.5vw; 
  display: flex; 
  align-items: center; 
  z-index: 9;
}

.before-icon image{
  width: 4vw;
}

.custom{
  display: flex; 
  justify-content: flex-end; 
  padding: 2vw 2vw 2vw 11vw;
}

.inputRoom {
  width: 100vw;
  height: 16vw;
  border-top: 1px solid #cdcdcd;
  background-color: #f1f1f1;
  padding-left: 50rpx;
  position: fixed;
  bottom: 0;
  display: flex;
  align-items: center;
  z-index: 20;
}

input {
  width: 76vw;
  height: 9.33vw;
  background-color: #fff;
  border-radius: 40rpx;
  margin-left: 2vw;
  padding: 0 3vw;
  font-size: 28rpx;
  color: #444;
}

.leftMsg {
  font-size: 35rpx;
  color: #444;
  line-height: 7vw;
  padding: 2vw 2.5vw;
  background-color: #fff;
  margin-left: -1.6vw;
  border-radius: 10rpx;
  z-index: 10;
}

.rightMsg {
  font-size: 35rpx;
  color: #444;
  line-height: 7vw;
  padding: 2vw 2.5vw;
  background-color: #96EB6A;
  margin-right: -1.6vw;
  border-radius: 10rpx;
  z-index: 10;
}

.site{
  width: 100%; 
  height: 18vw;
}

.footer{
  width: 7vw; 
  margin-left: 3.2vw;
}

转载于:https://blog.csdn.net/java558/article/details/86001064?utm_source=distribute.pc_relevant.none-task

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值