UNPKG

hi-mention

Version:

纯JS聊天框,兼容原生HTML/React/Vue等各种框架;支持@提及功能、插入富文本等多功能编辑器;内置H5和PC的交互样式

286 lines (236 loc) 11.2 kB
# Mention 提及 纯 JS 插件,无依任何赖,兼容原生 HTML 及各大前端框架,提供高自由度接口 - [查看 demo 示例](http://mention.bauble.vip) - [QQ 群](https://qm.qq.com/q/LqSPY7LrGM) ## 安装 ```bash npm install hi-mention --save ``` ## 引入 ```js import HiMention from "hi-mention"; ``` ## 使用 ```javascript // options非必要参数,可根据需要自行调整 new HiMention(element, options); ``` ## VUE 使用示例 ```html <template> <div class="editor-content"></div> </template> <script lang="ts" setup> import { onMounted } from "vue"; // 引入插件 import HiMention from "hi-mention"; // 引入插件样式 import "hi-mention/index.css"; onMounted(() => { new HiMention(".editor-content", { users: [ { name: "张三", id: 1 }, { name: "李四", id: 2 }, { name: "王五", id: 3 }, { name: "赵六", id: 4 }, { name: "钱七", id: 5 }, { name: "孙八", id: 6 }, { name: "周九", id: 7 }, { name: "吴十", id: 8 }, ], }) .on("focus", (e) => { console.log("focus", e); }) .on("blur", (e) => { console.log("blur", e); }) .on("change", (d) => { console.log("change", d?.html); msg.value = d?.html || ""; }); }); </script> <style> .editor-content { width: 500px; height: 200px; border: 1px solid #ccc; padding: 5px 10px; } </style> ``` ## Options 属性 | 属性名 | 说明 | 类型 | 默认值 | | ------------------ | --------------------------------------------- | ------------- | --------- | | `trigger` | 触发字符 | `string` | `@` | | `placeholder` | 占位符 | `string` | `请输入` | | `placeholderColor` | 占位符颜色 | `string` | `#aaa` | | `mentionColor` | 提及用户颜色 | `string` | `#0090FF` | | `users` | 用户列表 | `Array<User>` | `[]` | | `media` | 媒体类型(`PC` 和 `H5` 的用户列表展示有差异) | `PC`/`H5` | `PC` | | `idKey` | `User`对象`id`字段(该字段支持`@搜索`) | `string` | `id` | | `nameKey` | `User`对象`name`字段(该字段支持`@搜索`) | `string` | `name` | | `pingyinKey` | `User`对象`pingyin`字段(该字段支持`@搜索`) | `string` | `pingyin` | | `avatarKey` | `User`对象`avatar`字段 | `string` | `avatar` | | `usersWdith` | 用户列表宽度(`media`=`PC`时有效) | `string` | `200px` | | `usersHeight` | 用户列表最大高度 | `string` | `200px` | ## API | 方法 | 说明 | 类型 | 备注 | | ------------- | -------------------------------- | -------------------------------------------- | ---- | | `setOptions` | 设置`options`属性 | `(options: Partial<MentionOptions>)=>this` | - | | `getOptions` | 获取`options`属性 | `()=>MentionOptions` | - | | `on` | 监听事件 | `(key:EventType,fn:(data?:any)=>void)=>this` | - | | `mentionUser` | 提及用户 | `(user:User)=>this` | - | | `clear` | 清空输入框 | `()=>this` | - | | `insertText` | 在光标位置插入文本内容 | `(text:string)=>this` | - | | `insertHtml` | 在光标位置插入 HTML 内容 | `(html:Element)=>this` | - | | `focus` | 获取焦点将光标移动到输入框末尾 | `()=>this` | - | | `getData` | 获取输入框内容 | `()=>{html:string,text:string}` | - | | `getMentions` | 获取输入框内提及的用户对象列表 | `()=>Array<User>` | - | ### EventType | 类型 | 说明 | 备注 | | -------------- | -------- | ---- | | `input` | 输入事件 | - | | `focus` | 获取焦点 | - | | `blur` | 失去焦点 | - | | `keydown` | 键盘按下 | - | | `keyup` | 键盘抬起 | - | | `change` | 内容改变 | - | | `mention-user` | 提及用户 | - | ### User 类型 - 以下字段为推荐字段,若字段不存在,请使用`idKey``nameKey``pingyinKey``avatarKey`字段进行配置 | 字段名 | 必须 | 说明 | 类型 | | --------- | ---- | ---------------------------------------------------- | --------- | | `id` || 键(该字段支持@查询) | `string` | | `name` || 名字(该字段支持@查询) | `string` | | `pingyin` || 拼音(该字段支持@查询) | `string` | | `avatar` || 头像 | `string` | | `element` || 用户列表中展示的元素,若不提供该字段,则使用默认样式 | `Element` | ## 自定义 - 如果内置功能如无法满足需求,可以通过继承 HiMention 组件,以下方法来实现自定义用户列表 ### HiMention 接口 | 接口名 | 说明 | 类型 | 备注 | | ------------------- | ---------------------- | ------------------------------ | ----------------------------------------- | | `initUserSelector` | 方法:初始化用户选择器 | `()=>void` | - | | `closeUserSelector` | 方法:关闭用户选择器 | `()=>void` | - | | `openUserSelector` | 方法:打开用户列表 | `(query:User)=>void` | `query`:为用户输入`@`时后面跟的查询字符串 | | `onWordDelete` | 方法:删除/退格 | `(e: KeyboardEvent)=> boolean` | 返回 `true` 阻止默认事件和触发其他事件 | | `onMoveCursor` | 方法:光标移动 | `(e: KeyboardEvent)=> boolean` | 返回 `true` 阻止默认事件和触发其他事件 | | `onWordWrap` | 方法:换行 | `(e: KeyboardEvent)=> boolean` | 返回 `true` 阻止默认事件和触发其他事件 | | `onUndoHistory` | 方法:撤销 | `(e: KeyboardEvent)=> boolean` | 返回 `true` 阻止默认事件和触发其他事件 | | `onSelectAll` | 方法:全选 | `(e: KeyboardEvent)=> boolean` | 返回 `true` 阻止默认事件和触发其他事件 | | `onShearContent` | 方法:剪切 | `(e: KeyboardEvent)=> boolean` | 返回 `true` 阻止默认事件和触发其他事件 | | `onMoveCursor` | 方法:移动光标 | `(e: KeyboardEvent)=> boolean` | 返回 `true` 阻止默认事件和触发其他事件 | ### HiUserSelector 接口 | 接口名 | 说明 | 类型 | 备注 | | ---------------- | --------------------------- | ---------------------- | ---- | | `element` | 属性:用户列表根元素 | `HTMLElement` | - | | `open` | 方法:打开用户列表 | `(query:string)=>void` | - | | `close` | 方法:关闭用户列表 | `()=>void` | - | | `createUserItem` | 方法:创建用户选项`Element` | `(user:User)=>Element` | - | - 继承示例 ```javascript // 引入插件 import HiMention, { HiUserSelector } from "hi-mention"; // 引入插件样式 import "hi-mention/index.css"; // 创建自定义用户选择器 class MyHiUserSelector extends HiUserSelector { element: HTMLElement = document.createElement("div"); // 这是用户列表的根元素 constructor(props) { super(props); } open(query: string) { // 自定义打开列表逻辑 } close() { // 自定义关闭列表逻辑 } // 该方法返回的元素将被展示在默认用户列表中 createUserItem(user) { const { name, avatar } = user; const img = document.createElement("img"); img.src = avatar; img.style.width = "20px"; img.style.height = "20px"; img.style.marginRight = "5px"; const span = document.createElement("span"); span.innerText = name; const div = document.createElement("div"); div.appendChild(img); div.appendChild(span); // 该元素将被当成选项展示在用户列表中 return div; } } // 使用自定义选择器 class MyHiMention extends HiMention { constructor(props) { super(props); } // 初始化用户选择器 initUserSelector() { this.userSelector = new MyHiUserSelector(); // 监听鼠标在用户列表中按下事件,防止鼠标点击用户列表时,触发编辑器失去焦点事件 this.userSelector.element.onmousedown = () => setTimeout(() => clearTimeout(this.blurtimeout), 100); // 监听选择用户事件 this.userSelector.onSelectUser((user) => { this.mentionUser(user); }); } // 打开用户选择器 openUserSelector(query) { this.userSelector.open(query); } // 关闭用户选择器 closeUserSelector() { this.userSelector.close(); } } ``` ### 自定义换行示例 ```javascript // 引入插件 import HiMention from "hi-mention"; // 引入插件样式 import "hi-mention/index.css"; // 使用自定义选择器 class MyHiMention extends HiMention { constructor(props) { super(props); } // 监听用户按下换行按键 onWordWrap(e: KeyboardEvent): boolean { if (["Enter", "NumpadEnter"].includes(e.code)) { // 可重新设置快捷键 // 调用内置换行方法 this.wordWrap(); // 可重新设置换行逻辑 // 返回true阻止默认事件和触发其他事件 return true; } return false; // 没有自行换行,返回false } } ``` # 更新日志 ``` v2.2.2 2024-10-27 - 修复选择删除BUG v2.2.1 2024-10-27 - 修复长按删除键导致的光标丢失 v2.2.0 2024-10-27 - 对 v2.1.0 版本 BUG 继续修复 v2.1.0 2024-10-26 - 修复剪切复制粘贴 - 修复移动光标 - 修复换行 - 修复删除 - 修复焦点 - 修复占位符展示异常 - 针对火狐浏览器做兼容处理 v2.0.1 2024-10-25 - 修复默认用户选择器切换用户异常 v2.0.0 2024-10-25 - 重写 ```