> 웹 프론트엔드 > JS 튜토리얼 > WeChat UI의 채팅 기능 구현

WeChat UI의 채팅 기능 구현

php中世界最好的语言
풀어 주다: 2018-03-19 16:38:56
원래의
3088명이 탐색했습니다.

이번에는 WeChat UI의 채팅 기능을 구현하기 위한 주의사항을 알려드리겠습니다. 실제 사례를 살펴보겠습니다.

WeChat 미니 프로그램은 최근 인기가 많을 만큼 WeChat을 열자마자 해당 프로그램을 WeChat에서 사용하는 거의 모든 앱에서 찾을 수 있습니다. 공식 버전은 Tiaotiao와 함께 제공되어 전례 없는 높은 위치에 올랐습니다. 공식 계정과 비교했을 때 제가 생각하는 차이점은 다음과 같습니다.

  • 공식 계정은 좀 번거롭습니다. 콘텐츠를 보려면 먼저 주의를 기울여야 하지만, 미니 프로그램은 그렇지 않습니다. 위챗 공식 계정에 대한 깊은 이해가 있어서 그렇지는 않을 것 같습니다) 양해 부탁드립니다

  • 미니 프로그램의 성능이 더 좋습니다. 미니 프로그램이 정확히 무엇을 구현하는지는 모르겠지만, 실제로 경험 측면에서는 원래 경험에 더 가깝습니다. 하지만 WeChat 공식 계정은 웹페이지 형식을 사용하여 콘텐츠를 표시합니다. 호환성 및 성능 문제를 설명할 필요가 없습니다. 모든 루어가 이미 알고 있습니다

  • 미니 프로그램은 개발하기가 더 쉽습니다. 미니 프로그램은 새로운 코드 규칙 세트를 출시했으며 일련의 구성 요소도 제공합니다. Bai Jia의 공개 계정과 비교하면 형식이 실제로 훨씬 더 통일되어 있습니다. , 최근에야 미니 프로그램 구현을 살펴보기 시작했는데 정말 즐거웠습니다. 개인 개발 요약은 다음과 같습니다.

  • 간단한 공식 웹 사이트 미니 프로그램 프로그램

간단한 작은 프로그램이 있습니다. WeChat 미니 프로그램 공식 웹사이트의 데모 주소는 다음과 같습니다:

https://

mp.weixin.qq.com/debug/wxadoc/dev/index.html, 해당 단계를 따르십시오. 예는 공식적인 것이므로 여기에 프로세스를 게시하지 않겠습니다. 주로 내 전반적인 개인적인 느낌에 대해 이야기해 보세요.

js는 여전히 원본 js이고, css는 여전히 원본 CSS입니다. html 측면에서 몇 가지 사항이 변경되었습니다. 예를 들어 p는 보기가 되고, 텍스트는 텍스트가 되고, img 이미지가 되었지만 수프는 변경되지 않았습니다. 여전히 동일한 방식으로 사용할 수 있으며 의미가 더 명확합니다.

开发一个类似微信UI的简单聊天程序

只是感兴趣稍微做了一下案例,其中功能可能根本就还只是九牛一毛,但是觉得有必要记录一下,说说自己遇到的问题以及解决办法,界面整体如下:

WeChat UI의 채팅 기능 구현

首先,在app.json中编写页面路由,如下:

{
  "pages":[        
    "pages/index/index",
    "pages/list/list",
    "pages/chat/chat"
  ],
  "window":{
    "backgroundTextStyle":"light",
    "navigationBarBackgroundColor": "#000",
    "navigationBarTitleText": "WeChat",
    "navigationBarTextStyle":"#fff"
  }}
로그인 후 복사

这里有3个页面,首页放一个按钮作为入口,列表页表示聊天记录,还有一个聊天页。

列表页没有什么可以讲的,设置列表页的标题可以在list.json中设置即可,如下:

// list.json{
  "navigationBarTitleText": "聊天列表"}
로그인 후 복사

列表页模拟了一些数据,然后再点击每一条的时候,进入单个聊天页面当中,其中需要将当前点击的一些信息传入下一个页面当中,这里仅仅只有名字。

//chat.js//获取应用实例const app = getApp()const friends = require('./list-mock-data.js')Page({
  data: {
    friends: friends.list
  },
  gotoChat(event) {
    const currentUser = event.currentTarget.dataset.user;
    wx.navigateTo({
      url: '../chat/chat?nickname=' + currentUser.nickname
    })  }})
로그인 후 복사

然后进入聊天页面,首先进入聊天页面我想到的是,每一个气泡加上它的头像是否可以做成一个组件,因为只有左右的区分而已,另外如果再加上时间的话,再将时间传递过去就可以了。

因此chat.wxml(시작 페이지 포함)이 있습니다. react/vue의 선언 주기에서는 어느 단계에서 무엇을 할 수 있는지가 더 명확해집니다

🎜🎜🎜코드는 컴포넌트화되어 있으며 와 같이 캡슐화된 많은 컴포넌트를 간단히 참조할 수 있습니다. 지도, 그리고 WeChat 공식 계정에서 개발할 때 전용 지도 플러그인을 작성해야 할 수도 있습니다🎜🎜🎜🎜API가 더 사용자 친화적입니다. 공식 계정을 많이 개발하지는 않았지만, 이전에 구성한 jssdk가 걱정되는 점은 미니 프로그램이 복잡한 것보다 낫다는 것입니다. 미니 프로그램은 appId만 필요하고 코드에서 wx 개체를 직접 사용하여 다양한 API를 호출할 수 있습니다🎜🎜🎜🎜 WeChat UI와 유사한 간단한 채팅 프로그램을 개발해보세요🎜🎜그저 관심이 있어서 약간의 사례 연구를 했습니다. 기능은 그저 한 방울일 수도 있지만, 그것을 기록하고 내가 겪은 문제에 대해 이야기하는 것이 필요하다고 느꼈습니다. 전체 인터페이스는 다음과 같습니다. 🎜🎜WeChat UI의 채팅 기능 구현 🎜🎜먼저 app.json에 다음과 같이 페이지 경로를 작성합니다. 🎜
<block>
  <template></template></block>
로그인 후 복사
로그인 후 복사
🎜여기에는 3개의 페이지가 있습니다. 홈페이지에 입구 버튼이 있고, 목록 페이지는 채팅 기록을 나타냅니다. , 채팅 페이지가 있습니다. 🎜🎜목록 페이지에 대해서는 말할 것도 없습니다. 목록 페이지 제목 설정은 다음과 같이 list.json에서 설정할 수 있습니다. 🎜
// chat.js// 设置昵称setNickName(option) {
    const nickname = option.nickname || 'Marry';
    wx.setNavigationBarTitle({
      title: nickname    });
  },
로그인 후 복사
로그인 후 복사
🎜목록 페이지는 일부 데이터를 시뮬레이션한 후 클릭합니다. 각 항목에 단일 채팅 페이지에 들어갈 때 현재 클릭한 정보 중 일부를 다음 페이지로 전송해야 합니다. 여기에는 이름만 있습니다. 🎜
// chat.wxml<scroll-view>
    <block>
      <template></template>    </block>
  </scroll-view>// chat.jsPage({  data: {    messages: [],         // 聊天记录    msg: '',              // 当前输入    lastId: ''            // 最后一条消息的ID    // ...  },  // ...  send() {    // ...    const data = {      id: `msg${++nums}`,      message: msg,      messageType: 0,      url: '../../images/5.png'
    };
    this.setData({ msg: '', lastId: data.id });
  }
});
로그인 후 복사
로그인 후 복사
🎜그런 다음 채팅 페이지에 들어갑니다. 먼저, 채팅 페이지에 들어갈 때 생각하는 것은 각 버블과 그 아바타를 구성 요소로 만들 수 있는지 여부입니다. 게다가 시간의 차이만 있기 때문입니다. 추가되면 시간이 지나면 그냥 지나치세요. 🎜🎜그래서 chat.wxml은 원래 다음과 같이 계획되었습니다: 🎜
<block>
  <template></template></block>
로그인 후 복사
로그인 후 복사

template中的代码就不展示了,最开始我写模板的时候,是开了一个codePen,然后模拟写出来之后,再往模板中套,保证基本的样子差不多,然后再在模板上进行细微的改动就可以了。

聊天页顶部的标题是通过列表页中传过来的,在页面加载完成的时候,设置就好了:

// chat.js// 设置昵称setNickName(option) {
    const nickname = option.nickname || 'Marry';
    wx.setNavigationBarTitle({
      title: nickname    });
  },
로그인 후 복사
로그인 후 복사

最开始的样子就是这样子的:

WeChat UI의 채팅 기능 구현

至此,基本的页面形态就已经完成了。

遇到的一些问题:

  • 每次进入页面的时候,即使聊天内容已经超过了聊天区域,都会显示为最开始的地方

  • 输入新的聊天记录的时候,如果聊天内容不是处于最底部,那么新加的内容会看不到

针对这两个问题,我按照自己最初的想法是:进入页面获取scrollHieght然后计算scrollTop值,将其滚动就好了,至于第二个问题按照类似的方法就可以解决了,但是我查看小程序的API之后,并没有发现如何计算scrollHeight的方法。只有类似的API,如:boundingClientRectscrollTop

好在天无绝人之路,看到了scroll-view中的scroll-into-view属性,于是就想出了解决上面两个问题的方法:

  • 进入页面,获取历史纪录,获取最后一条消息的ID值,记为lastId,在渲染的时候,消息列表中的每个ID值传入组件,作为每个消息记录的唯一标识,然后使用scroll-in-view={{ id }}就可以轻松地使最后一条消息进入视野当中

  • 在聊天的时候,新加的记录会更新这个lastId值,这样就自动更新视图了

// chat.wxml<scroll-view>
    <block>
      <template></template>    </block>
  </scroll-view>// chat.jsPage({  data: {    messages: [],         // 聊天记录    msg: '',              // 当前输入    lastId: ''            // 最后一条消息的ID    // ...  },  // ...  send() {    // ...    const data = {      id: `msg${++nums}`,      message: msg,      messageType: 0,      url: '../../images/5.png'
    };
    this.setData({ msg: '', lastId: data.id });
  }
});
로그인 후 복사
로그인 후 복사

这样就可以大致实现类似于聊天的效果了,但是还有一个小问题,每次从列表中进入单个聊天页面的时候,会有一个斜向左上方滑动的过程,原因是:页面的转场动画是向左的,但是自动滚动到最后一条记录的动作是向上的,所以会有动作叠加,既然这样,我只需要让滚动的过程延迟一段时间就好

// 延迟页面向顶部滑动
  delayPageScroll() {
    const messages = this.data.messages;
    const length = messages.length;
    const lastId = messages[length - 1].id;
    setTimeout(() => {
      this.setData({ lastId });
    }, 300);
  },
로그인 후 복사

至此问题就算是解决了,在真机模拟的时候,IOS还有一个问题,就是当点击输入框的时候,整体页面会向上顶起来,这个问题我在论坛中也有看到,但是没有找到解决办法,如果各位有遇到,还望不吝赐教。

扩展延伸

如果是一个真正的聊天程序应该怎么做呢?我的设想是这样的:

WeChat UI의 채팅 기능 구현-one

由于当时自己的机器由于莫名的原因不能够进行登录,后来采用了本地开了一个websocket的服务器来实现消息的发送。服务器代码相当简单,只是消息的转发而已

// server.jsconst WebSocket = require('ws');const wss = new WebSocket.Server({ port: 12112 });wss.on('connection', ws => {
  console.log('connection established');
  ws.on('message', message => {
    console.log("on message coming");
    ws.send(message);
  });});
로그인 후 복사

chat.js中需模拟历史消息的发送以及新加消息的发送,因此代码整体看起来是这样的:

//chat.js//获取应用实例const app = getApp()const msgs = require('./chat-mock-data.js');Page({
  data: {
    messages: [],         // 聊天记录
    msg: '',              // 当前输入
    scrollTop: 0,         // 页面的滚动值
    socketOpen: false,    // websocket是否打开
    lastId: '',           // 最后一条消息的ID
    isFirstSend: true     // 是否第一次发送消息(区分历史和新加)
  },
  onLoad(option) {
    // 设置标题
    this.setNickName(option);
  },
  //事件处理函数
  onReady() {
    // 连接websocket服务器
    this.connect();
  },
  onUnload() {
    const socketOpen = this.data.socketOpen;
    if (socketOpen) {
      wx.closeSocket({});
      wx.onSocketClose(res => {
        console.log('WebSocket 已关闭!')      });
    }
  },
  connect() {
    wx.connectSocket({
      url: 'ws://localhost:12112'
    });
    wx.onSocketOpen(res => {
      this.setData({ socketOpen: true });
      // 模拟历史消息的发送
      wx.sendSocketMessage({
        data: JSON.stringify(msgs),
      })    });
    wx.onSocketMessage(res => {
      const isFirstSend = this.data.isFirstSend;
      const data = JSON.parse(res.data);
      let messages = this.data.messages;
      let lastId = '';
      
      // 第一次为接收历史消息,
      // 之后的为新加的消息
      if (isFirstSend) {
        messages = messages.concat(data);
        lastId = messages[0].id;
        this.setData({ messages, lastId, isFirstSend: false });
        // 延迟页面向顶部滑动
        this.delayPageScroll();
      } else {
        messages.push(data);
        const length = messages.length;
        lastId = messages[length - 1].id;
        this.setData({ messages, lastId });
      }
    });
    wx.onSocketError(res => {
      console.log(res);
      console.log('WebSocket连接打开失败,请检查!')    })  },
  // 设置昵称
  setNickName(option) {
    const nickname = option.nickname || 'Marry';
    wx.setNavigationBarTitle({
      title: nickname    });
  },
  // 延迟页面向顶部滑动
  delayPageScroll() {
    const messages = this.data.messages;
    const length = messages.length;
    const lastId = messages[length - 1].id;
    setTimeout(() => {
      this.setData({ lastId });
    }, 300);
  },
  // 输入
  onInput(event) {
    const value = event.detail.value;
    this.setData({ msg: value });
  },
  // 聚焦
  onFocus() {
    this.setData({ scrollTop: 9999999 });
  },
  // 发送消息
  send() {
    const socketOpen = this.data.socketOpen;
    let messages = this.data.messages;
    let nums = messages.length;
    let msg = this.data.msg;
    if (msg === '') {
      return false;
    }
    const data = {
      id: `msg${++nums}`,
      message: msg,
      messageType: 0,
      url: '../../images/5.png'
    };
    this.setData({ msg: '' });
    
    if (socketOpen) {
      wx.sendSocketMessage({
        data: JSON.stringify(data)      })    }
  }})
로그인 후 복사

整体来说,自己的思路就像是上面的代码所描述的,这个只是初步的构想,还有很多东西需要完善:

  • 头像

  • 列表页和聊天页新消息的处理

  • 数据库的历史消息存储

  • 图片以及语音的发送

  • 消息本地化存储

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

Vue指令的使用

JS闭包的使用

위 내용은 WeChat UI의 채팅 기능 구현의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿