React 实践 - 聊天界面添加表情面板

1,868 阅读2分钟

React 实践 - 聊天界面添加表情面板

导读

通过本篇学习,基于 React

  • antd 组件使用

  • CSS 样式、布局结构

  • 组件化

  • 父子组件传值

  • 事件、数据函数回调

  • React 构建聊天界面

操作实践

添加显示表情显示位置

在输入框上方添加可操作区域

需要支持扩展,方便添加其他一些操作显示(发送文件、其他 ...)

...

<div className={styles['chat-input-operator']}>
    {/* 表情 */}
    <span className={styles.emoticon} title="表情">
      <EmoticonView onChooseEmoji={onChooseEmoji} />
    </span>
</div>

...
  • onChooseEmoji 回调事件,可以在子组件点击 emoji 条目,回调给父组件,可以知道点击了那个

EmoticonView

显示表情按钮封装为一个组件,使用 antd Tooltip 组件来实现效果

const EmoticonView = () => {
  return (
    <Tooltip
      // 设置颜色为白色会覆盖字体颜色color="white"
      // 触发条件点击时触发
      trigger="click"
      // 悬浮样式可以修改悬浮大小
      overlayClassName={styles["emoticon-box-tip-tootip"]}
      // 具体弹出显示组件
      title={<EmoticonBox onEmojiItemClick={onChooseEmoji} />}
    >
      {/* 显示为一个表情 */}
      <img src={require("./icons/emoticon.svg")} alt="" />
    </Tooltip>
  );
};
  • onEmojiItemClick 传递父组件事件,一层层传递
  • 也可以使用 redux\dva 状态管理框架对状态直接进行监听改变

EmoticonBox

const EmoticonBox = ({ onEmojiItemClick }) => {
  const [emotionType, setEmotionType] = useState(0);
  return (
    <div className={styles["emoticon-box-tip-card"]}>
      <span className={styles["emoticon-title"]}>
        {emotionType === 0 ? "默认表情" : "收藏表情"}
      </span>
      <div className={styles["emoticon-box"]}>
        {emotionType === 0 ? (
          <DefaultEmoticonBox onEmojiItemClick={onEmojiItemClick} />
        ) : (
          <CollectEmotionBox />
        )}
      </div>
      <div className={styles["emoticon-type"]}>
        <Tooltip title="默认表情">
          <img
            src={require("./icons/default.svg")}
            alt="默认表情"
            onClick={() => setEmotionType(0)}
          />
        </Tooltip>

        <Tooltip title="收藏表情" arrowContent={null}>
          <img
            className={styles.collect}
            src={require("./icons/collect.svg")}
            alt="收藏表情"
            onClick={() => setEmotionType(1)}
          />
        </Tooltip>
      </div>
    </div>
  );
};
  • emotionType 控制表情类型,当前只添加了两种,默认表情、收藏表情。

  • 点击时,切换当前类型 setEmotionType

添加表情

使用 mock 数据进行循环添加,具体数据可以查看

gitee.com/shizidada/m…

默认表情

DefaultEmoticonBox
const DefaultEmoticonBox = ({ onEmojiItemClick }) => {
  return (
    <div className={styles["emoji-icons"]}>
      {defaultEmojiIconGroup1.map((item) => {
        return (
          <Tooltip title={item.name} key={item.id}>
            <div
              className={styles["emoji-box"]}
              onClick={() => onEmojiItemClick(item)}
            >
              <img
                className={styles["emoji-item"]}
                src={item.path}
                alt={item.name}
              />
            </div>
          </Tooltip>
        );
      })}
    </div>
  );
};

收藏表情

CollectEmotionBox
const CollectEmotionBox = ({ onEmojiItemClick }) => {
  return (
    <div className={styles["collect-icons"]}>
      {collectIcons.map((item) => {
        return (
          <Tooltip title={item.name} key={item.iconPath}>
            <div
              className={styles.collect}
              onClick={() => onEmojiItemClick(item)}
            >
              <img src={item.iconPath} alt={item.name} />
            </div>
          </Tooltip>
        );
      })}
    </div>
  );
};

合并问题

默认表情和收藏表情可以合并为一个组,需要传递 props 进行控制显示

默认表情和收藏表情显示的尺寸可能是不一样的,可能需要加一些额外的样式,所以分了两个组件展示

图片资源

  • 使用到的图片资源都是在 iconfont-阿里巴巴矢量图标库 搜索下载。www.iconfont.cn/
  • 代码中使用到的,可以查看

gitee.com/shizidada/m…

  • 这些图片数据都是通过前端 Mock 数据,可以把这些图片存入数据,通过接口的方式请求展示
  • 常用图片功能,基于上一条,记录发送的 emoji 图片次数,放入常用表情列表展示

往期回顾

React 快速上手实践

React 实践 - 构建聊天界面

React 实践 - 前后端分离、实现消息接收、推送

React 实践 - 前后端分离、分页请求历史聊天消息

SpringBoot 实践 - 前后端分离、实现消息接收、推送

更多学习知识


关注公众号 全栈技术部,不断学习更多有趣的技术知识。