Skip to content

React + Antd Mentions 实现艾特(@)

当前字数: 0 字 阅读时长: 0 分钟

tsx
import { Mentions } from "antd";
import { useCallback, useState } from "react";
import { MentionsUsersListItem } from "../../process/ProcessHistory/typing";
import { sysNoticeUserSearch } from "../../views/system/User/services";
import debounce from "lodash/debounce";

const { Option } = Mentions;

export type MentionsProps = {
  value?: string;
  onChange?: (value?: string) => void;
};

export default (props: MentionsProps) => {
  const [loading, setLoading] = useState(false);
  const [mentionsUsers, setMentionsUsers] = useState<MentionsUsersListItem[]>();

  // 模糊查询用户
  const loadMentionsUsers = async (key: string) => {
    if (!key) {
      setMentionsUsers([]);
      return;
    }
    const res = await sysNoticeUserSearch(key);
    setLoading(false);
    setMentionsUsers(res?.rows);
  };

  // 800ms 防抖
  const debounceLoadMentionsUsers = useCallback(
    debounce(loadMentionsUsers, 800),
    []
  );

  const onSearch = (search: string) => {
    setLoading(!!search);
    setMentionsUsers([]);
    debounceLoadMentionsUsers(search);
  };

  const getNoticeParams = (noticePerson: string) => {
    const persons = noticePerson?.split(",")?.map((item) => item.trim());
    if (persons?.[persons.length - 1] === "") {
      persons.pop();
    }
    return persons?.join(",");
  };

  const onMentionsChange = (noticePerson: string) => {
    const value = getNoticeParams(noticePerson);
    props.onChange?.(value);
  };

  return (
    <Mentions
      loading={loading}
      onSearch={onSearch}
      onChange={onMentionsChange}
      placeholder="@ 员工号、员工名字"
      style={{ width: "100%" }}
      autoSize
    >
      {mentionsUsers?.map(({ userName, userRealname }, index) => (
        <Option
          key={index + ""}
          value={userName + ":" + userRealname + ","}
          className="antd-demo-dynamic-option"
        >
          <span>{userName + ":" + userRealname}</span>
        </Option>
      ))}
    </Mentions>
  );
};

Released under the MIT License.