vue实现本地使用tinymce富文本编辑器

 

最终效果:

第一步:

tinymce官网下载地址:Self Hosted WYSIWYG HTML Editor | Trusted Rich Text Editor | TinyMCE

 

 2.建立公共页面trnymce.vue

<template>
  <div :class="{fullscreen:fullscreen}" class="tinymce-container" :style="{width:containerWidth}">
    <textarea :id="tinymceId" class="tinymce-textarea" />
    <div class="editor-custom-btn-container"></div>
  </div>
</template>

<script>
const plugins = [
  "advlist anchor  autolink autosave  colorpicker colorpicker contextmenu directionality fullscreen hr  insertdatetime  lists  nonbreaking noneditable pagebreak paste preview  save searchreplace spellchecker tabfocus  template textcolor textpattern visualblocks visualchars",
];

const toolbar = [
  "searchreplace bold italic underline strikethrough alignleft aligncenter alignright outdent indent  blockquote undo redo removeformat  numlist",
  "hr bullist styleselect fontsizeselect  fontselect charmap preview   insertdatetime   emoticons forecolor backcolor fullscreen",
];
const 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;";

export default {
  name: "Tinymce",
  props: {
    id: {
      type: String,
      default: function () {
        return (
          "vue-tinymce-" +
          +new Date() +
          ((Math.random() * 1000).toFixed(0) + "")
        );
      },
    },
    value: {
      type: String,
      default: "",
    },
    isTextNum:{
      type: Boolean,
      default: false,
    },
    toolbar: {
      type: Array,
      required: false,
      default() {
        return [];
      },
    },
    menubar: {
      type: String,
      default: "",
    },
    height: {
      type: [Number, String],
      required: false,
      default: 210,
    },
    width: {
      type: [Number, String],
      required: false,
      default: "auto",
    },
  },
  data() {
    return {
      hasChange: false,
      hasInit: false,
      tinymceId: this.id,
      fullscreen: false,
      languageTypeList: {
        en: "en",
        zh: "zh_CN",
        es: "es_MX",
        ja: "ja",
      },
    };
  },
  computed: {
    containerWidth() {
      const width = this.width;
      if (/^[\d]+(\.[\d]+)?$/.test(width)) {
        // matches `100`, `'100'`
        return `${width}px`;
      }
      return width;
    },
  },
  watch: {
    value(val) {
      if(this.hasChange){
        tinymce.activeEditor.setContent(val || "");
      }
      this.hasChange = true;
      if(this.isTextNum){
        let str = tinymce.activeEditor.getContent();
        let num = this.removeHTMLTag(str);
        this.$emit('num', num.length)
      }
    },
  },
  mounted() {
    this.initTinymce()
  },
  activated(){
    if(tinymce){
      this.initTinymce();
    }
  },
  deactivated() {
    this.destroyTinymce();
  },
  destroyed() {
    this.destroyTinymce();
  },
  methods: {

    removeHTMLTag: function (str) {
      str = str.replace(/^(([^<>()\\[\]\\.,;:\s@"]+(\.[^<>()\\[\]\\.,;:\s@"]+)*)|(".+"))*>/g, '');
      str = str.replace(/<\/?[^>]*>/g, '');
      str = str.replace(/[ | ]*\n/g, '\n');
      str = str.replace(/&nbsp;/ig, '');
      str = str.replace(/,/g, '');
      str = str.replace(/。/g, '');
      str = str.replace(/\s/g, '');
      return str;
    },

    initTinymce() {
      const _this = this;
      tinymce.init({
        selector: `#${this.tinymceId}`,
        branding: false, //(隐藏右下角技术支持)
        fontsize_formats: "10px 12px 14px 16px 24px 36px 48px",
        lineheight_formats: "8pt 9pt 10pt 11pt 12pt 14pt 16pt 18pt 20pt 22pt 24pt 26pt 36pt",
        language: this.languageTypeList["zh"],
        height: this.height,
        body_class: "panel-body ",
        object_resizing: false,
        toolbar: this.toolbar.length > 0 ? this.toolbar : toolbar,
        menubar: false,
        plugins: plugins,
        end_container_on_empty_block: true,
        powerpaste_word_import: "clean",
        code_dialog_height: 600,
        code_dialog_width: 1000,
        advlist_bullet_styles: "square",
        advlist_number_styles: "default",
        imagetools_cors_hosts: ["www.tinymce.com", "codepen.io"],
        default_link_target: "_blank",
        link_title: false,
        font_formats: font_formats,
        style_formats: [
          {
            title: "行高",
            items: [
              { title: "1", block: "p", styles: { "line-height": "1.0" } },
              { title: "1.5", block: "p", styles: { "line-height": "1.5" } },
              { title: "1.75", block: "p", styles: { "line-height": "1.75" } },
              { title: "2", block: "p", styles: { "line-height": "2" } },
              { title: "3", block: "p", styles: { "line-height": "3" } },
            ],
          },
        ],
        style_formats_merge: true,
        style_formats_autohide: true,
        nonbreaking_force_tab: true, // inserting nonbreaking space &nbsp; need Nonbreaking Space Plugin
        setup: function(editor) {
          editor.on('input undo redo execCommand', function(e) {
            _this.hasChange = false;
            _this.$emit("echo", editor.getContent());
          })
        },
        init_instance_callback: (editor) => {
          if (_this.value) {
            editor.setContent(_this.value);
          }
          editor.on("NodeChange Change KeyUp SetContent", () => {
            _this.hasChange = true;
            _this.$emit("echo", editor.getContent());
          });
        },
        convert_urls: false,
      });
    },
    destroyTinymce() {
      const tinymce1 = tinymce.get(this.tinymceId);
      if (this.fullscreen) {
        tinymce1.execCommand("mceFullScreen");
      }
      if (tinymce1) {
        tinymce1.destroy();
      }
    },
    setContent(value) {
      tinymce.get(this.tinymceId).setContent(value);
    },
    getContent() {
      tinymce.get(this.tinymceId).getContent();
    },
  },
};
</script>

<style lang="scss" scoped>
.tinymce-container {
  position: relative;
  line-height: normal;
  padding: 0 3px 0 0;
}

.tinymce-container {
  ::v-deep {
    .mce-fullscreen {
      z-index: 10000;
    }
  }
}

.tinymce-textarea {
  visibility: hidden;
  z-index: -1;
}

.editor-custom-btn-container {
  position: absolute;
  right: 4px;
  top: 4px;
  /*z-index: 2005;*/
}

.fullscreen .editor-custom-btn-container {
  z-index: 10000;
  position: fixed;
}

.editor-upload-btn {
  display: inline-block;
}
</style>

3.页面引用

 <quillEditor isTextNum="true" :value="form.cooking" @echo="echoCooking" @num="getNum"></quillEditor>

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值