封装一个丝滑的聊天框组件

需求背景

应公司业务要求,需要做个聊天机器人,要适应不同的业务场景,大概就跟淘宝客服类似,发送消息,机器人自动回复。

话不多说,直接开撸

技术栈: react(hooks写法) + flex布局

功能点梳理

  • 配置信息接收(机器人名称,超时自动回复,人工回复等待超时等等)
  • 发送消息
  • 接收接口返回的消息(包括图片)
  • 输入框鼠标拖动伸缩
  • 下拉获取历史聊天记录
  • 聊天消息过多时的滚动条处理

页面结构如下图

在这里插入图片描述

所用技术细节

1、下拉获取历史聊天记录:react-pull-to-refresh
	使用react-pull-to-refresh这个插件,在消息展示框外围套上该插件,使用方式如下
	它跟翻页是一个原理,只不过要处理一下数组的展示顺序,这个很简单。

在这里插入图片描述

2、 把接口请求放进props中,如下:
	大部分都是接口传递,因为需要多个地方的机器人使用,所以这样处理

图1

3、发送消息的逻辑处理

这里没有写滚动条的处理逻辑,手写一下: 用ref绑定滚动条,发送消息or拉取历史记录,需要计算滚动条滚动的高度并作出对应处理
在这里插入图片描述

4、 flex布局,比较基础,这里就掠过,主要是消息展示框自适应
5、 伸缩input, 给input上方放一个div占位,设置onmousedown,监听onmousemove来设置input的高度

这里我加了一个额外的组件处理,直接看代码吧,比较直观

import React, { useState } from 'react';
import { useSelector } from 'react-redux';

import './index.scss';

export default function ResizeWrapper(props) {
  const [mouseIsDown, setMouseIsDown] = useState(false); // 标识鼠标是否被按下
  // 获取侧边栏的打开状态
  const { sidebarOpenning } = useSelector((state) => state.sidebarState);
  const { child } = props; // content为聊天框组件
  const [contentWidth, setContentWidth] = useState(600); // 内容区域宽度

  document.onmousemove = function (e) {
    if (!mouseIsDown) return;

    let w;
    // 用鼠标点击的clientX 减去侧边栏的宽度还有额外的padding or margin 得到想要的宽度
    if (sidebarOpenning) {
      w = e.clientX - 180 - 12;
    } else {
      w = e.clientX - 60 - 12;
    }
    if (w < 420 || w > 800) {
      console.log(contentWidth);
      return;
    }
    setContentWidth(w);
  };
  document.onmouseup = function () {
    setMouseIsDown(false);
  };
  const handleMouseDown = (e) => {
    setMouseIsDown(true);
    console.log('down', e.clientX);
  };

  return (
    <>
      <div className="resize-container" style={{ width: contentWidth + 'px' }}>
        {child}
      </div>
      <div className="resize-bar" onMouseDown={handleMouseDown}></div>
    </>
  );
}


效果如下:
请添加图片描述

最终效果如下:https://live.csdn.net/v/262594

ok,完美收关!

  • 25
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
好的,我可以帮你封装一个单选组件,可以通过传值来设置选中项。以下是示例代码: ```jsx import React from 'react'; function RadioButton({ options, selectedOption, onChange }) { return ( <div> {options.map(option => ( <label key={option.value}> <input type="radio" value={option.value} checked={selectedOption === option.value} onChange={() => onChange(option.value)} /> {option.label} </label> ))} </div> ); } export default RadioButton; ``` 其中,`options` 是单选选项的数组,每个选项包含 `value` 和 `label` 两个属性;`selectedOption` 是当前选中的选项的值;`onChange` 是选中某个选项时的回调函数。 你可以在父组件中使用该组件,并通过传值来设置选中项,示例代码如下: ```jsx import React, { useState } from 'react'; import RadioButton from './RadioButton'; function App() { const [selectedOption, setSelectedOption] = useState('option1'); const options = [ { value: 'option1', label: 'Option 1' }, { value: 'option2', label: 'Option 2' }, { value: 'option3', label: 'Option 3' }, ]; const handleOptionChange = (value) => { setSelectedOption(value); }; return ( <div> <RadioButton options={options} selectedOption={selectedOption} onChange={handleOptionChange} /> </div> ); } export default App; ``` 在上述示例中,我们使用了 `useState` 来保存当前选中项的值 `selectedOption`,并将其作为 `RadioButton` 组件的 `selectedOption` 属性传递进去。当用户选择某个选项时,`handleOptionChange` 函数会更新 `selectedOption` 的值,从而实现选中项的变更。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值