vue2中使用tinymce

vue2中使用tinymce的记录

本篇文章主要实现的功能:
(1)【查看】时禁用编辑
(2)【编辑】时某些内容是不可编辑的
(3)【内容】前端拼接编辑器模板
(4)【内容】编辑器模板中table样式修改

实现效果图:
在这里插入图片描述

第一个功能的主要代码

disabled属性

 // 使用地地方,传递disabled属性
 <HTinyEditor
 	ref="HTinyEditor"
    :value="editHtml"
    :disabled="isReadonly"
  ></HTinyEditor>     

 // 组件接受,并赋给【`disabled`】属性
 <Editor v-model="myValue" :init="init" :api-key="apiKey" :disabled="disabled" />

第二个功能的主要代码

(1)contenteditable=“false” 禁止编辑
(2)监听删除操作,对有data-protected属性和data-mce-bogus属性的内容不可删除

// 下面为测试数据
<p contenteditable="false" data-protected="protected" style="text-align: center; line-height: 1;"><span style="font-size: 12pt;">通告内容预览</span></p>
<p style="text-align: center; line-height: 1;"><span style="font-family: 隶书; font-size: 24pt;"><strong><span data-edit="edit" style="color: #e03e2d;">XX通告</span></strong></span></p>

// 组件中的方法
setup: (editor) => {
   // 限制有data-protected和data-mce-bogus属性的内容不可删除(应用场景:某些属性是固定不可编辑的)
  editor.on("keydown", (e) => {
  	if (e.keyCode === 46 || e.keyCode === 8) {
         const node = editor.selection.getNode();
          if (node && (node.getAttribute("data-protected") || node.getAttribute("data-mce-bogus"))) {
                e.preventDefault();
           }
         }
      });
  },

使用步骤

下载依赖

npm install tinymce@5.10.3 -S

npm install @tinymce/tinymce-vue@3.0.1 -S

public文件夹下需要的依赖包文件与语言包

执行完上面的两条命令后,在node_modules 中找到 tinymce文件夹,将tinymce目录中的skins文件夹复制到public文件夹下,其他可按需引入。需要汉化的可以在官网下载语言包(汉化包地址),下载完成后将解压后的文件夹存放在与skins文件夹相同的位置。(我这里在最外层包裹了tinymce这一层文件夹方便查找,可不包)
在这里插入图片描述

HTinyEditor组件封装
<template>
  <div class="tinymce-editor">
  	<!-- :api-key="apiKey" -->
    <Editor v-model="myValue"  :init="init" :disabled="disabled" />
    <!-- <button @click="onClick()">测试</button> -->
  </div>
</template>

<script>
import tinymce from "tinymce/tinymce";
import Editor from "@tinymce/tinymce-vue";

// import 'tinymce/themes/modern/theme'
import "tinymce/themes/silver/theme";
import "tinymce/icons/default/icons";
import "tinymce/plugins/image"; // 插入上传图片插件
import "tinymce/plugins/media"; // 插入视频插件
import "tinymce/plugins/table"; // 插入表格插件
import "tinymce/plugins/link"; // 超链接插件
import "tinymce/plugins/code"; // 代码块插件
import "tinymce/plugins/lists"; // 列表插件
import "tinymce/plugins/contextmenu"; // 右键菜单插件
import "tinymce/plugins/wordcount"; // 字数统计插件
import "tinymce/plugins/colorpicker"; // 选择颜色插件
import "tinymce/plugins/textcolor"; // 文本颜色插件
import "tinymce/plugins/fullscreen"; // 全屏
// import 'tinymce/plugins/help' // 帮助
import "tinymce/plugins/charmap";

import "tinymce/plugins/print"; // 打印
import "tinymce/plugins/preview"; // 预览
import "tinymce/plugins/hr"; // 水平线

import "tinymce/plugins/spellchecker";
import "tinymce/plugins/imagetools";
import "tinymce/plugins/noneditable";
// import 'tinymce/plugins/save'
// import 'tinymce/plugins/tabfocus'
// import 'tinymce/plugins/textpattern'
// import 'tinymce/plugins/template'

import "tinymce/icons/default/icons";
import "tinymce/plugins/advlist"; //高级列表
import "tinymce/plugins/anchor"; //锚点
import "tinymce/plugins/autolink"; //自动链接
import "tinymce/plugins/autoresize"; //编辑器高度自适应,注:plugins里引入此插件时,Init里设置的height将失效
import "tinymce/plugins/autosave"; //自动存稿
import "tinymce/plugins/charmap"; //特殊字符
import "tinymce/plugins/code"; //编辑源码
import "tinymce/plugins/codesample"; //代码示例
import "tinymce/plugins/directionality"; //文字方向
import "tinymce/plugins/emoticons"; //表情
import "tinymce/plugins/fullpage"; //文档属性
// import "tinymce/plugins/fullscreen"; //全屏
import "tinymce/plugins/help"; //帮助
// import 'tinymce/plugins/hr' //水平分割线
import "tinymce/plugins/importcss"; //引入css
import "tinymce/plugins/insertdatetime"; //插入日期时间
// import 'tinymce/plugins/link' //超链接
// import 'tinymce/plugins/lists' //列表插件
// import 'tinymce/plugins/media' //插入编辑媒体
// import 'tinymce/plugins/image' // 插入图片
import "tinymce/plugins/nonbreaking"; //插入不间断空格
import "tinymce/plugins/pagebreak"; //插入分页符
import "tinymce/plugins/paste"; //粘贴插件
// import 'tinymce/plugins/preview' //预览
// import 'tinymce/plugins/print' //打印
import "tinymce/plugins/quickbars"; //快速工具栏
import "tinymce/plugins/save"; //保存
import "tinymce/plugins/searchreplace"; //查找替换
// import 'tinymce/plugins/spellchecker'  //拼写检查,未加入汉化,不建议使用
import "tinymce/plugins/tabfocus"; //切入切出,按tab键切出编辑器,切入页面其他输入框中
// import 'tinymce/plugins/table' //表格
import "tinymce/plugins/template"; //内容模板
// import 'tinymce/plugins/textcolor' //文字颜色
import "tinymce/plugins/textpattern"; //快速排版
import "tinymce/plugins/toc"; //目录生成器
import "tinymce/plugins/visualblocks"; //显示元素范围
import "tinymce/plugins/visualchars"; //显示不可见字符
// import 'tinymce/plugins/wordcount' //字数统计

export default {
  name: "HTinyEditor",
  components: {
    Editor,
  },
  props: {
    // 传入的编辑器中的内容,使组件支持v-model绑定
    value: {
      type: String,
      default: "",
    },
    // 是否禁用
    disabled: {
      type: Boolean,
      default: false,
    },
    plugins: {
      type: [String, Array],
      default:
        "lists image media table textcolor wordcount contextmenu preview",
    },
    toolbar: {
      type: [String, Array],
      default:
        "undo redo |  formatselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | lists image media table | removeformat table| fontsizeselect | fontselect'",
    },
  },
  data() {
    return {
      apiKey: "jzlds2e6urz6akm9wxp4f70mnwg83d8fovsialqazxowyity",
      // 配置文件服务器的静态访问路径前缀
      // static_web_preurl: 'http://localhost/files/hxzy_img/',
      // 初始化配置
      init: {
        placeholder: "在这里输入文字",
        language_url: "/tinymce/langs/zh_CN.js", // plugin文件夹下的汉化路径
        language: "zh_CN",
        skin_url: "/tinymce/skins/ui/oxide",
        height: 600, // 编辑器高度,可以考虑获取窗口高度,以适配不同设备屏幕
        end_container_on_empty_block: true,
        powerpaste_word_import: "clean",
        advlist_bullet_styles: "square",
        advlist_number_styles: "default",
        imagetools_cors_hosts: ["www.tinymce.com", "codepen.io"],
        default_link_target: "_blank",
        link_title: false,
        media_live_embeds: true,
        content_style: "img {max-width:100%;} html{background-color: #fff;}", // 直接自定义可编辑区域的css样式
        images_upload_url: "/api/attch/upload",
        nonbreaking_force_tab: true, // inserting nonbreaking space &nbsp; need Nonbreaking Space Plugin
        // plugins: this.plugins,
        // toolbar: this.toolbar,
        // @ts-nocheckplugins: 'link lists image code table colorpicker textcolor wordcount contextmenu',
        plugins:
          "advlist anchor autolink autosave code codesample colorpicker  contextmenu directionality toc  fullscreen hr image imagetools insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount",
        // toolbar:'bold italic underline strikethrough | fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist | outdent indent blockquote | undo redo | link unlink image code | removeformat | table',
        toolbar: [
          "searchreplace bold italic underline strikethrough fontselect fontsizeselect  alignleft aligncenter alignright outdent indent  blockquote undo redo removeformat subscript superscript code codesample",
          "hr bullist numlist link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor fullscreen",
        ],
        fontsize_formats: "8pt 10pt 12pt 14pt 18pt 24pt 36pt", // 第二步
        font_formats:
          "微软雅黑='微软雅黑';宋体='宋体';黑体='黑体';仿宋='仿宋';楷体='楷体';隶书='隶书';幼圆='幼圆';Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings",
        branding: false,
        elementpath: false, //隐藏底栏的元素路径
        // inline: true, //开启内联模式
        // icons: 'custom',
        readonly: true,
        menubar: true, // `是否显示菜单栏(文件、编辑等菜单)`
        file_picker_types: "media",
        setup: (editor) => {
          // 限制有data-protected和data-mce-bogus属性的内容不可删除(应用场景:某些属性是固定不可编辑的)
          editor.on("keydown", (e) => {
            if (e.keyCode === 46 || e.keyCode === 8) {
              const node = editor.selection.getNode();
              if (
                node &&
                (node.getAttribute("data-protected") ||
                  node.getAttribute("data-mce-bogus"))
              ) {
                e.preventDefault();
              }
            }
          });
        },
      },
      myValue: this.value,
    };
  },
  watch: {
    value(newValue) {
      this.myValue = newValue;
    },
    myValue(newValue) {
      this.$emit("input", newValue);
    },
  },
  mounted() {
    tinymce.init({});
  },
  methods: {
    onClick() {
      let editContent = tinymce.editors[0].getContent();
      this.$emit("onClick", editContent);
      console.log("编辑器中的内容:", editContent);
    },
    // 可以添加一些自己的自定义事件,如清空内容
    clear() {
      this.myValue = "";
    },
  },
};
</script>
<style scoped>
.tinymce-editor {
  min-height: 100%;
}
</style>

使用组件
<template>
  <div>
    <PopToggle :title="title" :visible="visible" @close="onClose">
      <template #content v-if="visible">
        <HTinyEditor
          ref="HTinyEditor"
          :value="editHtml"
          :disabled="isReadonly"
        ></HTinyEditor>
      </template>
      <template #footer>
        <div class="bg-white text-right project-popup-bottom">
          <a-button @click="onClose">取消</a-button>
          <a-button
            type="primary"
            v-if="!isReadonly"
            @click="confirm"
            class="m-l-10"
            >确定</a-button
          >
        </div>
      </template>
    </PopToggle>
  </div>
</template>

<script>
import PopToggle from "@com/business/PopToggle"; //弹窗组件
import HTinyEditor from "@/components/business/HTinyEditor";

export default {
  data() {
    return {
      editHtml: "", //编辑器中的内容
    };
  },
  props: {
    visible: {
      type: Boolean,
      required: true,
    },
    title: {
      type: String,
      required: true,
    },
    id: String,
  },
  components: {
    PopToggle,
    HTinyEditor,
  },
  computed: {
    // 操作状态
    operateState() {
      return this.title.includes("编辑");
    },
    // 只读状态
    isReadonly() {
      return this.title.includes("详情");
    },
  },
  watch: {
    visible(val) {
      if (val) {
        
      }
    },
  },
  methods: {
     // 取消
    onClose() {
      this.$emit("toggleVisible");
    },
    // 确定
    confirm() {
      // 获取富文本数据
      console.log(this.$refs.HTinyEditor.myValue);
     },
   },
};
</script>

<style lang="less" scoped></style>
模板中数据动态拼接
  1. 拼接模板数据共用方法
/**
 *
 * @param {Sting} sysHtml 要拼接的数据1
 * @param {Sting} quantityHtml 要拼接的数据2
 * @param {Object} data 内容字段数据
 * @returns
 */
export function editContent(sysHtml, quantityHtml, data) {
  let content = `
    <p style="text-align: center; line-height: 1;" contenteditable="false" data-protected="protected">&nbsp;</p>
    <p style="text-align: center; line-height: 1;"><span style="font-size: 18pt;">通告内容预览</span></p>
    <p style="text-align: center; line-height: 1;">&nbsp;</p>
    <p style="text-align: center; line-height: 1;"><span style="font-family: 楷体; font-size: 36pt;"><strong><span style="color: #e03e2d;">XX通告</span></strong></span></p>
    <p style="text-align: center; line-height: 1;" contenteditable="false" data-protected="protected"><span style="text-decoration: underline;"><span style="font-size: 24pt; color: #e03e2d; text-decoration: underline;"><span style="color: #000000; font-size: 10pt; text-decoration: underline;">&nbsp; &nbsp; &nbsp; &nbsp;<span style="font-size: 14pt;"> XXX部门&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;XXX编号 </span>&nbsp; &nbsp; &nbsp;&nbsp;</span></span></span></p>
    <p style="text-align: center; line-height: 1;">&nbsp;</p>
    <p style="text-align: left; line-height: 1; padding-left: 40px;" contenteditable="false" data-protected="protected"><span style="font-size: 24pt; color: #e03e2d;"><span style="font-size: 10pt;">${data.orgName}<span style="color: #000000;"></span></span></span></p>
    <p style="text-align: left; line-height: 1; padding-left: 40px;" contenteditable="false" data-protected="protected"><span style="font-size: 24pt; color: #e03e2d;"><span style="font-size: 10pt;">你好,XXX:</span></span></p>
    <p style="text-align: left; line-height: 1; padding-left: 40px;" contenteditable="false" data-protected="protected"><span style="font-size: 24pt; color: #000000;"><span style="font-size: 10pt;">(1)XX数据</span></span></p>
    <table style="border-collapse: collapse; width: 99.9552%;" border="1" contenteditable="false" data-protected="protected">
    <tbody>
      <tr style="height: 32.1429px; background-color: rgba(24, 144, 255, 1);">
        <td style="width: 12.1856%; height: 32.1429px; text-align: center;"><strong><span style="color: #ffffff;">XXX</span></strong></td>
        <td style="width: 11.8782%; height: 32.1429px; text-align: center;"><strong><span style="color: #ffffff;">XXX</span></strong></td>
        <td style="width: 11.1064%; height: 32.1429px; text-align: center;"><strong><span style="color: #ffffff;">XXX</span></strong></td>
        <td style="width: 12.3404%; height: 32.1429px; text-align: center;"><strong><span style="color: #ffffff;">XXX</span></strong></td>
        <td style="width: 10.9521%; height: 32.1429px; text-align: center;"><strong><span style="color: #ffffff;">XXX</span></strong></td>
        <td style="width: 13.4202%; height: 32.1429px; text-align: center;"><strong><span style="color: #ffffff;">XXX</span></strong></td>
        <td style="width: 16.9681%; height: 32.1429px; text-align: center;"><strong><span style="color: #ffffff;">XXX</span></strong></td>
        <td style="width: 10.9521%; height: 32.1429px; text-align: center;"><strong><span style="color: #ffffff;">XXX</span></strong></td>
      </tr>`;

  content += sysHtml;
  content += `
      </tbody>
      </table>
      <p style="text-align: left; line-height: 1; padding-left: 40px;"  ><span style="font-size: 24pt; color: #000000;"><span style="font-size: 10pt;">(2)XX数据</span></span></p>
      <table style="border-collapse: collapse; width: 99.9552%;" border="1">
      <tbody>
        <tr style="height: 32.1429px; background-color: rgba(24, 144, 255, 1);">
          <td style="width: 12.5506%; height: 32.1429px; text-align: center;"><strong><span style="color: #ffffff;">XXX</span></strong></td>
          <td style="width: 12.5506%; height: 32.1429px; text-align: center;"><strong><span style="color: #ffffff;">XXX</span></strong></td>
          <td style="width: 12.5506%; height: 32.1429px; text-align: center;"><strong><span style="color: #ffffff;">XXX</span></strong></td>
          <td style="width: 12.5506%; height: 32.1429px; text-align: center;"><strong><span style="color: #ffffff;">XXX</span></strong></td>
          <td style="width: 10.8249%; height: 32.1429px; text-align: center;"><strong><span style="color: #ffffff;">XXX</span></strong></td>
          <td style="width: 11.6093%; height: 32.1429px; text-align: center;"><strong><span style="color: #ffffff;">XXX</span></strong></td>
          <td style="width: 16.0033%; height: 32.1429px; text-align: center;"><strong><span style="color: #ffffff;">XXX</span></strong></td>
          <td style="width: 11.2943%; height: 32.1429px; text-align: center;"><strong><span style="color: #ffffff;">XXX</span></strong></td>
        </tr>`;

  content += quantityHtml;

  content += `
      </tbody>
      </table>
      <p style="text-align: left; line-height: 1; padding-left: 40px;"  ><span class="mce-nbsp-wrap"  >&nbsp;&nbsp;&nbsp;</span></p>
      <p style="text-align: left; line-height: 1; padding-left: 40px;"  ><span style="font-size: 12pt; color: #e03e2d;">XXX</span></p>
      <p style="line-height: 1; text-align: right;"><span style="color: #e03e2d;">${data.orgName}&nbsp; &nbsp; &nbsp;</span></p>
      <p style="line-height: 1; text-align: right;">&nbsp; &nbsp; <span style="color: #e03e2d;">${data.issueTime}&nbsp; &nbsp; &nbsp;</span></p>`;

  return content;
}
  1. 调用模板
this.editHtml = editContent(sysHtml, quantityHtml, otherData);

注意:编辑器模板中不要给table加高度,否则会导致table没有数据时表头会很高

  1. 模板中table表头样式修改
  • 实现效果
    在这里插入图片描述

  • 编辑器模板中table代码

<tbody>
     <tr style="height: 32.1429px; background-color: rgba(24, 144, 255, 1);">
     	 ...
    </tr>
</tbody>

也可使用其他富文本编辑器,像vueup/vue-quill等

Vue2和TinyMCE是两个不同的开发工具。Vue2是一个流行的JavaScript框架,用于构建用户界面。而TinyMCE是一个富文本编辑器,用于在网页实现可编辑的文本区域。 如果你想在Vue2项目使用TinyMCE,可以按照以下步骤进行操作: 1. 首先,在你的Vue项目安装TinyMCE。可以使用npm或yarn进行安装,命令如下: ``` npm install --save tinymce ``` 2. 在需要使用TinyMCEVue组件导入tinymce,并注册为全局变量或者组件内的局部变量。例如: ```javascript import tinymce from 'tinymce/tinymce'; import 'tinymce/themes/silver'; // 根据需求选择主题 import 'tinymce/plugins/lists'; // 根据需求选择插件 export default { data() { return { editor: null }; }, mounted() { tinymce.init({ selector: '#editor', // 绑定编辑器到id为editor的元素 plugins: ['lists'], // 启用插件 toolbar: 'undo redo | bold italic | bullist numlist', // 自定义工具栏按钮 setup: (editor) => { this.editor = editor; editor.on('change', () => { this.$emit('input', editor.getContent()); }); } }); }, beforeDestroy() { if (this.editor) { this.editor.destroy(); } } } ``` 3. 在Vue组件的模板,添加一个用于展示TinyMCE编辑器的元素。例如: ```html <template> <div> <textarea id="editor" v-model="content"></textarea> </div> </template> ``` 4. 最后,你可以在Vue组件的data定义一个名为content的变量,用于存储编辑器的内容。 这样就可以在Vue2项目使用TinyMCE了。请根据你的需求和实际情况,适当调整TinyMCE的配置和样式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值