React 实践 - 聊天界面添加表情面板
导读
通过本篇学习,基于 React
-
antd 组件使用
-
CSS 样式、布局结构
-
组件化
-
父子组件传值
-
事件、数据函数回调
操作实践
添加显示表情显示位置
在输入框上方添加可操作区域
需要支持扩展,方便添加其他一些操作显示(发送文件、其他 ...)
...
<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 数据进行循环添加,具体数据可以查看
默认表情
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/ - 代码中使用到的,可以查看
- 这些图片数据都是通过前端 Mock 数据,可以把这些图片存入数据,通过接口的方式请求展示
- 常用图片功能,基于上一条,记录发送的 emoji 图片次数,放入常用表情列表展示
往期回顾
SpringBoot 实践 - 前后端分离、实现消息接收、推送
关注公众号 全栈技术部,不断学习更多有趣的技术知识。