wangEditor icon indicating copy to clipboard operation
wangEditor copied to clipboard

Boot.registerMenu(saveConf) 注册自定义菜单项存在重复注册的问题

Open pengzhiqiang110 opened this issue 1 year ago • 15 comments

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

pengzhiqiang110 avatar Jun 01 '24 08:06 pengzhiqiang110

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')传递给父组件,也传递不出去。 传给父组件,也传不出去。

pengzhiqiang110 avatar Jun 01 '24 08:06 pengzhiqiang110

能用 sandbox 做个最小复现吗😳

cycleccc avatar Jun 01 '24 08:06 cycleccc

同样是这个问题,按照官网的自定义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>

liubiliubi avatar Jul 03 '24 02:07 liubiliubi

这是类的定义

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) 的返回值
  }
}

liubiliubi avatar Jul 03 '24 02:07 liubiliubi

Uncaught (in promise) Error: Duplicated key 'commentButton' in menu items 这个是报错

liubiliubi avatar Jul 03 '24 02:07 liubiliubi

@liubiliubi 你好,能使用这个 沙盒demo做个最小复现吗

cycleccc avatar Jul 03 '24 02:07 cycleccc

这有助于快速排查修复bug,业余维护,时间有限。

cycleccc avatar Jul 03 '24 02:07 cycleccc

这有助于快速排查修复bug,业余维护,时间有限。

好的,等会发您

liubiliubi avatar Jul 03 '24 02:07 liubiliubi

这有助于快速排查修复bug,业余维护,时间有限。

我解决了。问题是没有安装@wangeditor/editor的依赖,但是为啥没有提示找不到模块的报错??不得而知

liubiliubi avatar Jul 03 '24 03:07 liubiliubi

在使用 npm 或其它时应该会提示 peerDependencies @wangeditor/editor 必须大于 5.1.0,确实提示不够明显,这也是个问题。

cycleccc avatar Jul 03 '24 03:07 cycleccc

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: @.***>

pengzhiqiang110 avatar Jul 03 '24 06:07 pengzhiqiang110

这个问题是自定义菜单重复注册导致的。 解决方法:在注册前判断是否已经注册

// saveConf 是自定义菜单 // editor 是编辑器实例 // getAllMenuKeys() 获取所有注册的菜单

if(!editor.getAllMenuKeys().includes(saveConf)){ Boot.registerMenu(saveConf) }

kongbg avatar Jul 26 '24 00:07 kongbg

这样判断吧 if (Boot.plugins.length <= 12) { Boot.registerModule(attachmentModule) }

lvlinmufeng avatar Jan 08 '25 12:01 lvlinmufeng

我只想说这个bug 真让人无语呀,关闭时都 销毁了,再次打开还报重复。。。。内部不能判断的?

lvlinmufeng avatar Jan 08 '25 12:01 lvlinmufeng

注册到main.js 全局 也可以 使用的地方 就不用注册了 image

lvlinmufeng avatar Jan 08 '25 12:01 lvlinmufeng