Boot.registerMenu(saveConf) 注册自定义菜单项存在重复注册的问题
bug 描述
编辑器封装为一个组件,在多个页面使用。自定义了一个菜单项,在组件里面注册,报错 Uncaught (in promise) Error: Duplicated key 'customSave7' in menu items at chunk-Y4OLSECU.js?v=81a33f40:26106:15 at e10.registerMenu (chunk-Y4OLSECU.js?v=81a33f40:26110:6) at setup (RichEditor.vue:64:6) at callWithErrorHandling (chunk-R5FCYZP3.js?v=81a33f40:1659:19) at setupStatefulComponent (chunk-R5FCYZP3.js?v=81a33f40:9073:25) at setupComponent (chunk-R5FCYZP3.js?v=81a33f40:9034:36) at mountComponent (chunk-R5FCYZP3.js?v=81a33f40:7363:7) at processComponent (chunk-R5FCYZP3.js?v=81a33f40:7329:9) at patch (chunk-R5FCYZP3.js?v=81a33f40:6795:11) at mountChildren (chunk-R5FCYZP3.js?v=81a33f40:7043:7)
你预期的样子是?
不报错
系统和浏览器及版本号
- 操作系统 mac m1
- 浏览器和版本 chrome 125.0.6422.78
wangEditor 版本 ^5.1.23
class SaveButtonMenu { constructor() { this.title = '保存' // 自定义菜单标题 // 可选 this.iconSvg = '<svg xmlns="http://www.w3.org/2000/svg" fill="#000000" version="1.1" width="20" height="20" viewBox="0 0 20 20"><g><path d="M15,17.5L15,10.83333L5,10.83333L5,17.5L3.333333,17.5C2.873096,17.5,2.5,17.1269,2.5,16.6667L2.5,3.333333C2.5,2.873096,2.873096,2.5,3.333333,2.5L14.1667,2.5L17.5,5.83333L17.5,16.6667C17.5,17.1269,17.1269,17.5,16.6667,17.5L15,17.5ZM13.3333,17.5L6.66667,17.5L6.66667,12.5L13.3333,12.5L13.3333,17.5Z" fill-opacity="1"/></g></svg>' this.tag = 'button' this.alwaysEnable = true } // 获取菜单执行时的 value ,用不到则返回空 字符串或 false getValue(editor) { // JS 语法 return '' } // 菜单是否需要激活(如选中加粗文本,“加粗”菜单会激活),用不到则返回 false isActive(editor) { // JS 语法 return false } // 菜单是否需要禁用(如选中 H1 ,“引用”菜单被禁用),用不到则返回 false isDisabled(editor) { // JS 语法 return false } // 点击菜单时触发的函数 exec(editor, value) { // JS 语法 console.log('点击了保存按钮') // saveFunction(editor) if (editor.isDisabled(editor)) return editor.insertText(value) emit('handleSave') } } const saveConf = { key: 'customSave7', // 定义 menu key :要保证唯一、不重复(重要) factory() { return new SaveButtonMenu() // 把 YourMenuClass 替换为你菜单的 class } } if (localStorage.getItem('customSave7') === null) { localStorage.setItem('customSave7', 'true') Boot.registerMenu(saveConf) } 我在 // 点击菜单时触发的函数
exec(editor, value) {
// JS 语法
console.log('点击了保存按钮')
// saveFunction(editor)
if (editor.isDisabled(editor)) return
editor.insertText(value)
emit('handleSave')
} 虽然我用if (localStorage.getItem('customSave7') === null) {
localStorage.setItem('customSave7', 'true')
Boot.registerMenu(saveConf)
}这种方法保证只注册一次,但是点击菜单触发的时候需要把这事件通过 emit('handleSave')传递给父组件,也传递不出去。
传给父组件,也传不出去。
能用 sandbox 做个最小复现吗😳
同样是这个问题,按照官网的自定义button menu 三步走的。
<script setup lang="ts">
import "@wangeditor/editor/dist/css/style.css"; // 引入 css
import {
onMounted,
onBeforeUnmount,
computed,
shallowRef,
getCurrentInstance,
nextTick,
ref
} from "vue";
import { Editor } from "@wangeditor/editor-for-vue";
import { Boot } from "@wangeditor/editor";
import { MyButtonMenu } from "@/packages/RegisterCommentButton";
// 自定义菜单配置
const menu1Conf = {
key: "commentButton", // 定义 menu key :要保证唯一、不重复(重要)
factory() {
return new MyButtonMenu(); // 把 `YourMenuClass` 替换为你菜单的 class
}
};
// 注册菜单
Boot.registerMenu(menu1Conf);
// 编辑器实例,必须用 shallowRef
const editorRef = shallowRef();
const editorConfig = { placeholder: "请输入内容...", autoFocus: false };
// 组件销毁时,也及时销毁编辑器
onBeforeUnmount(() => {
const editor = editorRef.value;
if (editor == null) return;
editor.destroy();
});
const handleCreated = async editor => {
editorRef.value = editor; // 记录 editor 实例,重要!
console.log("editor", editorRef.value);
await nextTick();
console.log(editor.getMenuConfig("bold"));
};
const handleChange = editor => {
// 内容改变事件
// console.log("change:", editor.children);
// console.log("getAllMenuKeys():", editor.getAllMenuKeys());
};
</script>
这是类的定义
import { IButtonMenu, IDomEditor } from "@wangeditor/editor";
export class MyButtonMenu implements IButtonMenu {
// TS 语法
// class MyButtonMenu { // JS 语法
title = "";
tag = "";
constructor() {
this.title = "My menu title"; // 自定义菜单标题
// this.iconSvg = '<svg>...</svg>' // 可选
this.tag = "button";
}
// 获取菜单执行时的 value ,用不到则返回空 字符串或 false
getValue(editor: IDomEditor): string | boolean {
// TS 语法
// getValue(editor) { // JS 语法
return " hello ";
}
// 菜单是否需要激活(如选中加粗文本,“加粗”菜单会激活),用不到则返回 false
isActive(editor: IDomEditor): boolean {
// TS 语法
// isActive(editor) { // JS 语法
return false;
}
// 菜单是否需要禁用(如选中 H1 ,“引用”菜单被禁用),用不到则返回 false
isDisabled(editor: IDomEditor): boolean {
// TS 语法
// isDisabled(editor) { // JS 语法
return false;
}
// 点击菜单时触发的函数
exec(editor: IDomEditor, value: string | boolean) {
// TS 语法
// exec(editor, value) { // JS 语法
if (this.isDisabled(editor)) return;
editor.insertText(value); // value 即 this.value(editor) 的返回值
}
}
Uncaught (in promise) Error: Duplicated key 'commentButton' in menu items 这个是报错
@liubiliubi 你好,能使用这个 沙盒demo做个最小复现吗
这有助于快速排查修复bug,业余维护,时间有限。
这有助于快速排查修复bug,业余维护,时间有限。
好的,等会发您
这有助于快速排查修复bug,业余维护,时间有限。
我解决了。问题是没有安装@wangeditor/editor的依赖,但是为啥没有提示找不到模块的报错??不得而知
在使用 npm 或其它时应该会提示 peerDependencies @wangeditor/editor 必须大于 5.1.0,确实提示不够明显,这也是个问题。
font{
line-height: 1.6;
}
ul,ol{
padding-left: 20px;
list-style-position: inside;
}
目前没有时间,这个等我有时间写下,目前不太着急
pengzhiqiang916870
***@***.***
---- 回复的原邮件 ----
发件人
***@***.***>
发送日期
2024年07月3日 10:47
收件人
***@***.***>
抄送人
***@***.***>
,
***@***.***>
主题
Re: [wangeditor-team/wangEditor] Boot.registerMenu(saveConf) 注册自定义菜单项存在重复注册的问题 (Issue #5876)
@liubiliubi 你好,能使用这个 沙盒demo做个最小复现吗
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you authored the thread.Message ID: @.***>
这个问题是自定义菜单重复注册导致的。 解决方法:在注册前判断是否已经注册
// saveConf 是自定义菜单 // editor 是编辑器实例 // getAllMenuKeys() 获取所有注册的菜单
if(!editor.getAllMenuKeys().includes(saveConf)){ Boot.registerMenu(saveConf) }
这样判断吧 if (Boot.plugins.length <= 12) { Boot.registerModule(attachmentModule) }
我只想说这个bug 真让人无语呀,关闭时都 销毁了,再次打开还报重复。。。。内部不能判断的?
注册到main.js 全局 也可以 使用的地方 就不用注册了