富文本编辑器Tinymce的使用、行内富文本编辑器工具栏自定义class、katex渲染数学公式

提示:vue2 + tinymce@5

### 文章目录

  • [@TOC(文章目录)](#文章目录 @TOC 前言 一、行内富文本编辑器工具栏自定义class 二、修改样式 三、展示数学公式 四、添加自定义按钮 四、添加自定义下拉框 总结)
  • [前言](#文章目录 @TOC 前言 一、行内富文本编辑器工具栏自定义class 二、修改样式 三、展示数学公式 四、添加自定义按钮 四、添加自定义下拉框 总结)
  • [一、行内富文本编辑器工具栏自定义class](#文章目录 @TOC 前言 一、行内富文本编辑器工具栏自定义class 二、修改样式 三、展示数学公式 四、添加自定义按钮 四、添加自定义下拉框 总结)
  • [二、修改样式](#文章目录 @TOC 前言 一、行内富文本编辑器工具栏自定义class 二、修改样式 三、展示数学公式 四、添加自定义按钮 四、添加自定义下拉框 总结)
  • [三、展示数学公式](#文章目录 @TOC 前言 一、行内富文本编辑器工具栏自定义class 二、修改样式 三、展示数学公式 四、添加自定义按钮 四、添加自定义下拉框 总结)
  • [四、添加自定义按钮](#文章目录 @TOC 前言 一、行内富文本编辑器工具栏自定义class 二、修改样式 三、展示数学公式 四、添加自定义按钮 四、添加自定义下拉框 总结)
  • [四、添加自定义下拉框](#文章目录 @TOC 前言 一、行内富文本编辑器工具栏自定义class 二、修改样式 三、展示数学公式 四、添加自定义按钮 四、添加自定义下拉框 总结)
  • [总结](#文章目录 @TOC 前言 一、行内富文本编辑器工具栏自定义class 二、修改样式 三、展示数学公式 四、添加自定义按钮 四、添加自定义下拉框 总结)

前言

使用富文本编辑器

一、行内富文本编辑器工具栏自定义class

1、防止直接使用class为tox-tinymce修改样式造成全局污染,添加自定义class名称custom_tinymce_box

c 复制代码
<template>
  <div class="editor_box">
    <div class="editor_content" name="" id="editorId"></div>
  </div>
</template>

<script>
import tinymce from 'tinymce';
// 主题
import 'tinymce/themes/silver/theme.js';
// 图标
import 'tinymce//icons/default/icons.js';
// 工具
import 'tinymce/plugins/image/plugin.js';
import 'tinymce/plugins/code/plugin.js';
export default {
  name: 'Editor',
  data () {
    return {
      
    }
  },
  mounted(){
    this.initTinymce();
  },
  methods:{
    initTinymce(){
      tinymce.init({
        // 选择器
        selector: '#editorId',
        // 工具
        plugins: ["code","image","kityformula-editor","mathJax"],
        base_url: 'static/tinymce/',
        // 控制编辑器内容样式
        content_css:['static/tinymce/css/index.css','static/tinymce/css/test.css'],
        // 允许编辑器跨域访问css文件
        content_css_cors: true,
        // 顶部menu栏
        menubar:"",
        // 底部状态栏
        statusbar: false,
        // 工具栏
        toolbar: " math | formatting | text | align | lineheight | outdent indent | image | code ",
        // 工具组
        toolbar_groups: {
          formatting: {
            icon: 'bold',
            tooltip: 'Formatting',
            items: 'bold italic underline strikethrough'
          },
          text: {
            icon: 'format',
            tooltip: 'text',
            items: 'fontselect fontsizeselect forecolor'
          },
          align: {
            icon: 'align-left',
            tooltip: 'align',
            items: 'alignleft aligncenter alignright alignjustify'
          },
          math: {
            icon: 'character-count',
            tooltip: 'math',
            items: 'mathJax | kityformula-editor'
          }
        },
        // 字体列表
        font_formats: ["黑体", "仿宋", "楷体", "宋体", "GB Pinyinok-A", "iTeach拼音", "方正综艺简体", "微软雅黑", "汉仪糯米团W", "方正楷体简体", "方正粗圆简体", "方正准圆简体", "华文琥珀", "汉仪铸字杂货铺简", "方正胖娃简体", "方正楷体拼音字库", "Microsoft YaHei", "Arial", "Arial Black", "Arial Rounded Bold", "Comic Sans MS", "Times New Roman", "Chalkboard", "MarkerFelt", "Sassoon Infant", "Century Gothic", "calibri", "Jotting", "Kinqsoft Phonetic Plain", "Marydale", "SCRIPT1 Rager Hevvy", "Segoe Print", "GCFruBol", "GCFruRom", "JetBrains Mono", "DIN Condensed"].join(';'),
        // 字号列表
        fontsize_formats: "14px 16px 18px 20px 24px 28px 32px 36px 40px",
        // 行高列表
        line_height_formats: '1 1.2 1.4 1.6 2',
        // 语言包地址
        language_url:"static/tinymce/langs/zh_CN.js",
        // 语言
        language: "zh_CN",
        // 皮肤
        skin_url:'static/tinymce/skins/ui/oxide',
        // 图片可编辑
        image_dimensions: true,
        // 行内元素
        inline: true,
        // 自定义icon地址
        icons_url:'static/tinymce/icon/index.js',
        // 自定义icons
        icons: 'customIcons',
        setup: (ed) => {
          if (ed&&ed.on) {
            // 监听编辑器失焦事件,触发内容变化
            ed.on("init", () => {
                const container = ed.getContainer();
                container.classList.add('custom_tinymce_box');
            });
          }
        }
      });
    },
  },
}
</script>
<style scoped>
.editor_content{
  border: 1px solid #333;
}
</style>

添加前

添加后

二、修改样式

1、安装scss,方便层级嵌套

c 复制代码
npm install sass-loader node-sass --save-dev

安装遇到问题:webpack 3 + Vue2项目匹配的依赖版本不对问题处理

解决方案:配置webpack

c 复制代码
"node-sass": "^4.14.1",
"sass-loader": "^7.3.1",
"vue-loader": "13.7.3",
"vue-style-loader": "^3.0.1",
"vue-template-compiler": "2.5.2",
"webpack": "^3.6.0",

2、editor/Index.vue

c 复制代码
<template>
  <div class="editor_box">
    <div class="editor_content" name="" id="editorId"></div>
  </div>
</template>

<script>
import tinymce from 'tinymce';
// 主题
import 'tinymce/themes/silver/theme.js';
// 图标
import 'tinymce//icons/default/icons.js';
// 工具
import 'tinymce/plugins/image/plugin.js';
import 'tinymce/plugins/code/plugin.js';
export default {
  name: 'Editor',
  data () {
    return {
      
    }
  },
  mounted(){
    this.initTinymce();
  },
  methods:{
    initTinymce(){
      tinymce.init({
        // 选择器
        selector: '#editorId',
        // 工具
        plugins: ["code","image","kityformula-editor","mathJax"],
        base_url: 'static/tinymce/',
        // 控制编辑器内容样式
        content_css:['static/tinymce/css/index.css','static/tinymce/css/test.css'],
        // 允许编辑器跨域访问css文件
        content_css_cors: true,
        // 顶部menu栏
        menubar:"",
        // 底部状态栏
        statusbar: false,
        // 工具栏
        toolbar: " math | formatting | text | align | lineheight | outdent indent | image | code ",
        // 工具组
        toolbar_groups: {
          formatting: {
            icon: 'bold',
            tooltip: 'Formatting',
            items: 'bold italic underline strikethrough'
          },
          text: {
            icon: 'format',
            tooltip: 'text',
            items: 'fontselect fontsizeselect forecolor'
          },
          align: {
            icon: 'align-left',
            tooltip: 'align',
            items: 'alignleft aligncenter alignright alignjustify'
          },
          math: {
            icon: 'character-count',
            tooltip: 'math',
            items: 'mathJax | kityformula-editor'
          }
        },
        // 字体列表
        font_formats: ["黑体", "仿宋", "楷体", "宋体", "GB Pinyinok-A", "iTeach拼音", "方正综艺简体", "微软雅黑", "汉仪糯米团W", "方正楷体简体", "方正粗圆简体", "方正准圆简体", "华文琥珀", "汉仪铸字杂货铺简", "方正胖娃简体", "方正楷体拼音字库", "Microsoft YaHei", "Arial", "Arial Black", "Arial Rounded Bold", "Comic Sans MS", "Times New Roman", "Chalkboard", "MarkerFelt", "Sassoon Infant", "Century Gothic", "calibri", "Jotting", "Kinqsoft Phonetic Plain", "Marydale", "SCRIPT1 Rager Hevvy", "Segoe Print", "GCFruBol", "GCFruRom", "JetBrains Mono", "DIN Condensed"].join(';'),
        // 字号列表
        fontsize_formats: "14px 16px 18px 20px 24px 28px 32px 36px 40px",
        // 行高列表
        line_height_formats: '1 1.2 1.4 1.6 2',
        // 语言包地址
        language_url:"static/tinymce/langs/zh_CN.js",
        // 语言
        language: "zh_CN",
        // 皮肤
        skin_url:'static/tinymce/skins/ui/oxide',
        // 图片可编辑
        image_dimensions: true,
        // 行内元素
        inline: true,
        // 自定义icon地址
        icons_url:'static/tinymce/icon/index.js',
        // 自定义icons
        icons: 'customIcons',
        setup: (ed) => {
          if (ed&&ed.on) {
            // 监听编辑器失焦事件,触发内容变化
            ed.on("init", () => {
                const container = ed.getContainer();
                container.classList.add('custom_tinymce_box');
            });
          }
        }
      });
    },
  },
}
</script>
<style scoped>
.editor_box{
  padding: 60px 20px 20px;
}
.editor_content{
  border: 1px solid #333;
  width: 400px;
}
</style>
<style lang="scss">
.custom_tinymce_box{
  border-radius: 4px!important;
  border: 1px solid #ccc!important;
  box-sizing: border-box;
  padding: 6px;
  transform: translateY(-14px);
  .tox-toolbar__primary,.tox-toolbar-overlord,.tox-editor-container,.tox-editor-header{
    border: 0!important;
  }
  .tox-toolbar__group{
    height: 24px;
    .tox-tbtn{
      width: 24px;
      height: 20px;
      line-height: 20px;
      padding: 0;
      margin: 0;
      
    }
  }
}
</style>

三、展示数学公式

安装vue-katex

c 复制代码
npm i katex vue-katex-auto-render --save-dev

1、src/main.js

c 复制代码
import "katex/dist/katex.min.css";
import katexAutoRender from 'vue-katex-auto-render';

Vue.directive('katex', katexAutoRender);

2、editor/Index.vue

c 复制代码
<template>
  <div class="editor_box">
    <div class="editor_content" name="" id="editorId"></div>
    <div class="editor_content_show" v-katex v-html="contennt"></div>
  </div>
</template>

<script>
import tinymce from 'tinymce';
// 主题
import 'tinymce/themes/silver/theme.js';
// 图标
import 'tinymce//icons/default/icons.js';
// 工具
import 'tinymce/plugins/image/plugin.js';
import 'tinymce/plugins/code/plugin.js';
export default {
  name: 'Editor',
  data () {
    return {
      contennt:'',
    }
  },
  mounted(){
    this.initTinymce();
  },
  methods:{
    initTinymce(){
      tinymce.init({
        // 选择器
        selector: '#editorId',
        // 工具
        plugins: ["code","image","kityformula-editor","mathJax"],
        base_url: 'static/tinymce/',
        // 控制编辑器内容样式
        content_css:['static/tinymce/css/index.css','static/tinymce/css/test.css'],
        // 允许编辑器跨域访问css文件
        content_css_cors: true,
        // 顶部menu栏
        menubar:"",
        // 底部状态栏
        statusbar: false,
        // 工具栏
        toolbar: " math | formatting | text | align | lineheight | outdent indent | image | code ",
        // 工具组
        toolbar_groups: {
          formatting: {
            icon: 'bold',
            tooltip: 'Formatting',
            items: 'bold italic underline strikethrough'
          },
          text: {
            icon: 'format',
            tooltip: 'text',
            items: 'fontselect fontsizeselect forecolor'
          },
          align: {
            icon: 'align-left',
            tooltip: 'align',
            items: 'alignleft aligncenter alignright alignjustify'
          },
          math: {
            icon: 'character-count',
            tooltip: 'math',
            items: 'mathJax | kityformula-editor'
          }
        },
        // 字体列表
        font_formats: ["黑体", "仿宋", "楷体", "宋体", "GB Pinyinok-A", "iTeach拼音", "方正综艺简体", "微软雅黑", "汉仪糯米团W", "方正楷体简体", "方正粗圆简体", "方正准圆简体", "华文琥珀", "汉仪铸字杂货铺简", "方正胖娃简体", "方正楷体拼音字库", "Microsoft YaHei", "Arial", "Arial Black", "Arial Rounded Bold", "Comic Sans MS", "Times New Roman", "Chalkboard", "MarkerFelt", "Sassoon Infant", "Century Gothic", "calibri", "Jotting", "Kinqsoft Phonetic Plain", "Marydale", "SCRIPT1 Rager Hevvy", "Segoe Print", "GCFruBol", "GCFruRom", "JetBrains Mono", "DIN Condensed"].join(';'),
        // 字号列表
        fontsize_formats: "14px 16px 18px 20px 24px 28px 32px 36px 40px",
        // 行高列表
        line_height_formats: '1 1.2 1.4 1.6 2',
        // 语言包地址
        language_url:"static/tinymce/langs/zh_CN.js",
        // 语言
        language: "zh_CN",
        // 皮肤
        skin_url:'static/tinymce/skins/ui/oxide',
        // 图片可编辑
        image_dimensions: true,
        // 行内元素
        inline: true,
        // 自定义icon地址
        icons_url:'static/tinymce/icon/index.js',
        // 自定义icons
        icons: 'customIcons',
        setup: (ed) => {
          if (ed&&ed.on) {
            // 监听编辑器失焦事件,触发内容变化
            ed.on("init", () => {
                const container = ed.getContainer();
                container.classList.add('custom_tinymce_box');
            });
            ed.on("change", () => {
                this.contennt = ed.getContent();
            });
          }
        }
      });
    },
  },
}
</script>
<style scoped>
.editor_box{
  padding: 60px 20px 20px;
}
.editor_content{
  border: 1px solid #333;
  width: 400px;
}
</style>
<style lang="scss">
.custom_tinymce_box{
  border-radius: 4px!important;
  border: 1px solid #ccc!important;
  box-sizing: border-box;
  padding: 6px;
  transform: translateY(-14px);
  .tox-toolbar__primary,.tox-toolbar-overlord,.tox-editor-container,.tox-editor-header{
    border: 0!important;
  }
  .tox-toolbar__group{
    height: 24px;
    .tox-tbtn{
      width: 24px;
      height: 20px;
      line-height: 20px;
      padding: 0;
      margin: 0;
      
    }
  }
}
</style>

四、添加自定义按钮

1、editor/Index.vue

c 复制代码
<template>
  <div class="editor_box">
    <div class="editor_content" name="" id="editorId"></div>
    <div class="editor_content_show" v-katex v-html="contennt"></div>
  </div>
</template>

<script>
import tinymce from 'tinymce';
// 主题
import 'tinymce/themes/silver/theme.js';
// 图标
import 'tinymce//icons/default/icons.js';
// 工具
import 'tinymce/plugins/image/plugin.js';
import 'tinymce/plugins/code/plugin.js';
export default {
  name: 'Editor',
  data () {
    return {
      editor:null,
      contennt:'',
    }
  },
  mounted(){
    this.initTinymce();
  },
  methods:{
    changeFontSize(type) {
      // 检查编辑器实例是否存在
      if (
        !this.editor ||
        !this.editor.queryCommandValue ||
        !this.editor.execCommand
      ) {
        console.warn("编辑器实例未初始化,无法改变字体大小");
        return;
      }

      try {
        // 获取当前字体大小
        let fontSize =
          parseInt(this.editor.queryCommandValue("fontsize")) || 12;

        if (type == "add") {
          // 增加字体大小,最大200px
          if (fontSize < 200) fontSize++;
        } else {
          // 减少字体大小,最小12px
          if (fontSize > 12) fontSize--;
        }

        // 执行字体大小命令
        this.editor.undoManager.transact(() => {
          this.editor.execCommand("FontSize", false, fontSize + "px");
        });
      } catch (error) {
        console.error("改变字体大小失败:", error);
      }
    },
    initTinymce(){
      tinymce.init({
        // 选择器
        selector: '#editorId',
        // 工具
        plugins: ["code","image","kityformula-editor","mathJax"],
        base_url: 'static/tinymce/',
        // 控制编辑器内容样式
        content_css:['static/tinymce/css/index.css','static/tinymce/css/test.css'],
        // 允许编辑器跨域访问css文件
        content_css_cors: true,
        // 顶部menu栏
        menubar:"",
        // 底部状态栏
        statusbar: false,
        // 工具栏
        toolbar: " math | formatting | text | align | lineheight | outdent indent | image | code | A+ A-",
        // 工具组
        toolbar_groups: {
          formatting: {
            icon: 'bold',
            tooltip: 'Formatting',
            items: 'bold italic underline strikethrough'
          },
          text: {
            icon: 'format',
            tooltip: 'text',
            items: 'fontselect fontsizeselect forecolor'
          },
          align: {
            icon: 'align-left',
            tooltip: 'align',
            items: 'alignleft aligncenter alignright alignjustify'
          },
          math: {
            icon: 'character-count',
            tooltip: 'math',
            items: 'mathJax | kityformula-editor'
          }
        },
        // 字体列表
        font_formats: ["黑体", "仿宋", "楷体", "宋体", "GB Pinyinok-A", "iTeach拼音", "方正综艺简体", "微软雅黑", "汉仪糯米团W", "方正楷体简体", "方正粗圆简体", "方正准圆简体", "华文琥珀", "汉仪铸字杂货铺简", "方正胖娃简体", "方正楷体拼音字库", "Microsoft YaHei", "Arial", "Arial Black", "Arial Rounded Bold", "Comic Sans MS", "Times New Roman", "Chalkboard", "MarkerFelt", "Sassoon Infant", "Century Gothic", "calibri", "Jotting", "Kinqsoft Phonetic Plain", "Marydale", "SCRIPT1 Rager Hevvy", "Segoe Print", "GCFruBol", "GCFruRom", "JetBrains Mono", "DIN Condensed"].join(';'),
        // 字号列表
        fontsize_formats: "14px 16px 18px 20px 24px 28px 32px 36px 40px",
        // 行高列表
        line_height_formats: '1 1.2 1.4 1.6 2',
        // 语言包地址
        language_url:"static/tinymce/langs/zh_CN.js",
        // 语言
        language: "zh_CN",
        // 皮肤
        skin_url:'static/tinymce/skins/ui/oxide',
        // 图片可编辑
        image_dimensions: true,
        // 行内元素
        inline: true,
        // 自定义icon地址
        icons_url:'static/tinymce/icon/index.js',
        // 自定义icons
        icons: 'customIcons',
        setup: (ed) => {
          this.editor = ed||{};
          if (ed&&ed.on) {
            // 监听编辑器失焦事件,触发内容变化
            ed.on("init", () => {
                const container = ed.getContainer();
                container.classList.add('custom_tinymce_box');
            });
            ed.on("change", () => {
                this.contennt = ed.getContent();
            });
          }
          // 自定义功能按钮
          const addButtonList = [
            {
              name: "A+",
              text: "A+",
              tooltip: "放大字体",
              onAction: () => {
                this.changeFontSize("add");
              },
            },
            {
              name: "A-",
              text: "A-",
              tooltip: "缩小字体",
              onAction: () => {
                this.changeFontSize("minus");
              },
            },
          ];
          // 注册所有自定义按钮到编辑器
          addButtonList.forEach((item) => {
            try {
              ed.ui.registry.addButton(item.name, item);
            } catch (error) {
              console.error(`注册按钮 ${item.name} 失败:`, error);
            }
          });


        }
      });
    },
  },
}
</script>
<style scoped>
.editor_box{
  padding: 60px 20px 20px;
}
.editor_content{
  border: 1px solid #333;
  width: 400px;
}
</style>
<style lang="scss">
.custom_tinymce_box{
  border-radius: 4px!important;
  border: 1px solid #ccc!important;
  box-sizing: border-box;
  padding: 6px;
  transform: translateY(-14px);
  .tox-toolbar__primary,.tox-toolbar-overlord,.tox-editor-container,.tox-editor-header{
    border: 0!important;
  }
  .tox-toolbar__group{
    height: 24px;
    .tox-tbtn{
      width: 24px;
      height: 20px;
      line-height: 20px;
      padding: 0;
      margin: 0;
      
    }
  }
}
</style>

四、添加自定义下拉框

1、editor/Index.vue

c 复制代码
<template>
  <div class="editor_box">
    <div class="editor_content" name="" id="editorId"></div>
    <div class="editor_content_show" v-katex v-html="contennt"></div>
  </div>
</template>

<script>
import tinymce from 'tinymce';
// 主题
import 'tinymce/themes/silver/theme.js';
// 图标
import 'tinymce//icons/default/icons.js';
// 工具
import 'tinymce/plugins/image/plugin.js';
import 'tinymce/plugins/code/plugin.js';
export default {
  name: 'Editor',
  data () {
    return {
      editor:null,
      contennt:'',
    }
  },
  mounted(){
    this.initTinymce();
  },
  methods:{
    changeFontSize(type) {
      // 检查编辑器实例是否存在
      if (
        !this.editor ||
        !this.editor.queryCommandValue ||
        !this.editor.execCommand
      ) {
        console.warn("编辑器实例未初始化,无法改变字体大小");
        return;
      }

      try {
        // 获取当前字体大小
        let fontSize =
          parseInt(this.editor.queryCommandValue("fontsize")) || 12;

        if (type == "add") {
          // 增加字体大小,最大200px
          if (fontSize < 200) fontSize++;
        } else {
          // 减少字体大小,最小12px
          if (fontSize > 12) fontSize--;
        }

        // 执行字体大小命令
        this.editor.undoManager.transact(() => {
          this.editor.execCommand("FontSize", false, fontSize + "px");
        });
      } catch (error) {
        console.error("改变字体大小失败:", error);
      }
    },
    initTinymce(){
      tinymce.init({
        // 选择器
        selector: '#editorId',
        // 工具
        plugins: ["code","image","kityformula-editor","mathJax"],
        base_url: 'static/tinymce/',
        // 控制编辑器内容样式
        content_css:['static/tinymce/css/index.css','static/tinymce/css/test.css'],
        // 允许编辑器跨域访问css文件
        content_css_cors: true,
        // 顶部menu栏
        menubar:"",
        // 底部状态栏
        statusbar: false,
        // 工具栏
        toolbar: " math | formatting | text | align | lineheight | outdent indent | image | code | A+ A- | textStyle ",
        // 工具组
        toolbar_groups: {
          formatting: {
            icon: 'bold',
            tooltip: 'Formatting',
            items: 'bold italic underline strikethrough'
          },
          text: {
            icon: 'format',
            tooltip: 'text',
            items: 'fontselect fontsizeselect forecolor'
          },
          align: {
            icon: 'align-left',
            tooltip: 'align',
            items: 'alignleft aligncenter alignright alignjustify'
          },
          math: {
            icon: 'character-count',
            tooltip: 'math',
            items: 'mathJax | kityformula-editor'
          }
        },
        // 字体列表
        font_formats: ["黑体", "仿宋", "楷体", "宋体", "GB Pinyinok-A", "iTeach拼音", "方正综艺简体", "微软雅黑", "汉仪糯米团W", "方正楷体简体", "方正粗圆简体", "方正准圆简体", "华文琥珀", "汉仪铸字杂货铺简", "方正胖娃简体", "方正楷体拼音字库", "Microsoft YaHei", "Arial", "Arial Black", "Arial Rounded Bold", "Comic Sans MS", "Times New Roman", "Chalkboard", "MarkerFelt", "Sassoon Infant", "Century Gothic", "calibri", "Jotting", "Kinqsoft Phonetic Plain", "Marydale", "SCRIPT1 Rager Hevvy", "Segoe Print", "GCFruBol", "GCFruRom", "JetBrains Mono", "DIN Condensed"].join(';'),
        // 字号列表
        fontsize_formats: "14px 16px 18px 20px 24px 28px 32px 36px 40px",
        // 行高列表
        line_height_formats: '1 1.2 1.4 1.6 2',
        // 语言包地址
        language_url:"static/tinymce/langs/zh_CN.js",
        // 语言
        language: "zh_CN",
        // 皮肤
        skin_url:'static/tinymce/skins/ui/oxide',
        // 图片可编辑
        image_dimensions: true,
        // 行内元素
        inline: true,
        // 自定义icon地址
        icons_url:'static/tinymce/icon/index.js',
        // 自定义icons
        icons: 'customIcons',
        setup: (ed) => {
          this.editor = ed||{};
          if (ed&&ed.on) {
            // 监听编辑器失焦事件,触发内容变化
            ed.on("init", () => {
                const container = ed.getContainer();
                container.classList.add('custom_tinymce_box');
            });
            ed.on('focus', function (e) {
              setTimeout(() => {
                const sinkElement = document.querySelector('.tox-silver-sink'); // 获取tox-silver-sink元素
                if (sinkElement) {
                    sinkElement.className += ' custom_tinymce_sink'
                }
              }, 0);
          });
            ed.on("change", () => {
                this.contennt = ed.getContent();
            });
          }
          // 自定义功能按钮
          const addButtonList = [
            {
              name: "A+",
              text: "A+",
              tooltip: "放大字体",
              onAction: () => {
                this.changeFontSize("add");
              },
            },
            {
              name: "A-",
              text: "A-",
              tooltip: "缩小字体",
              onAction: () => {
                this.changeFontSize("minus");
              },
            },
          ];
          // 注册所有自定义按钮到编辑器
          addButtonList.forEach((item) => {
            try {
              ed.ui.registry.addButton(item.name, item);
            } catch (error) {
              console.error(`注册按钮 ${item.name} 失败:`, error);
            }
          });

          // 自定义下拉列表
          const textItems = [
            {
              icon: 'bold',
              action: 'bold'
            },
            {
              icon: 'italic',
              action: 'italic'
            },
            {
              icon: 'underline',
              action: 'underline'
            },
            {
              icon: 'strike-through',
              action: 'strikethrough'
            },
          ];
          this.editor.ui.registry.addMenuButton('textStyle', {
            icon: 'bold',
            tooltip: '文字样式',
            fetch: (callback) => {
              const items = [];
              textItems.forEach(item => {
                  items.push({
                    type: 'menuitem',
                    icon: item.icon,
                    onAction: () => {
                      // 执行字体大小命令
                      this.editor.undoManager.transact(() => {
                        this.editor.execCommand(item.action);
                      });
                    }
                  })
              })
              callback(items);
            }
          });
        }
      });
    },
  },
}
</script>
<style scoped>
.editor_box{
  padding: 60px 20px 20px;
}
.editor_content{
  border: 1px solid #333;
  width: 400px;
}
</style>
<style lang="scss">
.custom_tinymce_box{
  border-radius: 4px!important;
  border: 1px solid #ccc!important;
  box-sizing: border-box;
  padding: 6px;
  transform: translateY(-14px);
  .tox-toolbar__primary,.tox-toolbar-overlord,.tox-editor-container,.tox-editor-header{
    border: 0!important;
  }
  .tox-toolbar__group{
    height: 24px;
    .tox-tbtn{
      width: 24px;
      height: 20px;
      line-height: 20px;
      padding: 0;
      margin: 0;
      
    }
    .tox-tbtn.tox-tbtn--select[aria-label="文字样式"]{
      width: 36px;
      
    }
  }
}
.custom_tinymce_sink .tox-collection__item-icon svg{
  fill:#000!important;
}
</style>

总结

踩坑路漫漫长@~@

相关推荐
智码看视界40 分钟前
老梁聊全栈系列:Vue3核心与组合式API深度解析
javascript·vue.js·ecmascript
想吃火锅10058 小时前
【leetcode】405.数字转换为十六进制数js
开发语言·javascript·ecmascript
原则猫10 小时前
HOOKS 背后机制
前端
码语智行10 小时前
首页导航跳转功能深度解析-系统内和系统外
前端
阿猫的故乡11 小时前
Vue过渡动画从入门到装X:淡入淡出、滑动、列表动画、第三方库全搞定
前端·javascript·vue.js
裕波11 小时前
Vue&ViteConf 2026 将于 7 月 18 日在上海举办,尤雨溪将现场发表主题演讲
vue.js·vite
IManiy11 小时前
总结之Vibe Coding前端骨架
前端
小和尚敲木头11 小时前
vue3 vite动态拼接图片路径
javascript
JS菌11 小时前
AI Agent 沙箱双层防护体系:从权限过滤到内核隔离的完整实现
前端·人工智能·后端
Aphasia31112 小时前
从输入URL到页面展示全流程
前端·面试