vue使用tinymce富文本框组件,实现了上传和复制粘贴,包括处理Placeholder鼠标点击后不显示

<template>
  <div>
    <editor id='tinymce' v-model='tinymceHtml' :placeholder="placeholderHtml" :init='editorInit'></editor>
  </div>
</template>
<script>
import tinymce from 'tinymce/tinymce'
import 'tinymce/themes/modern/theme'
import Editor from '@tinymce/tinymce-vue'
import 'tinymce/plugins/link'
import 'tinymce/plugins/lists'
import 'tinymce/plugins/image'
import 'tinymce/plugins/media'
import 'tinymce/plugins/paste'
import 'tinymce/plugins/code'
import 'tinymce/plugins/table'
import 'tinymce/plugins/colorpicker'
import 'tinymce/plugins/textcolor'
import 'tinymce/plugins/contextmenu'
import 'tinymce/plugins/wordcount'
import 'tinymce/plugins/fullscreen'
import 'tinymce/plugins/preview'
import 'tinymce/plugins/searchreplace'
import api_file from 'api/api.file'
let that
export default {
  name: 'tinymce',
  components: { Editor },
  props: {
    model: {
      default: ''
    },
    placeholderText: {
      default: ''
    },
    bkeyCode: {
      default: ''
    },
    height: {
      default: 300
    },
    width: {
      default: 800
    }
  },
  data () {
    return {
      tinymceHtml: this.model + '' || '',
      placeholderHtml: this.placeholderText,
      editorInit: {
        branding: false,
        language_url: '/tinymce/lang/zh_CN.js',
        language: 'zh_CN',
        skin_url: '/tinymce/skins/lightgray',
        height: this.height,
        width: this.width,
        theme: 'modern',
        plugins: 'link lists image media paste table colorpicker textcolor contextmenu fullscreen preview searchreplace placeholder',
        toolbar: 'formatselect | bold italic underline strikethrough | fontselect | fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist | blockquote | undo redo | link unlink image media | removeformat fullscreen',
        media_poster: false,
        media_alt_source: false,
        statusbar: false,
        // CONFIG: Paste
        paste_retain_style_properties: 'all',
        paste_word_valid_elements: '*[*]', // word需要它
        paste_data_images: true, // 粘贴的同时能把内容里的图片自动上传,非常强力的功能
        paste_convert_word_fake_lists: false, // 插入word文档需要该属性
        paste_webkit_styles: 'all',
        paste_merge_formats: true,
        nonbreaking_force_tab: false,
        paste_auto_cleanup_on_paste: false,

        // CONFIG: FontSizeSelect
        fontsize_formats: '10px 11px 12px 14px 16px 18px 20px 24px',

        // FontSelect
        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,zapf dingbats`,
        // 文本框内容改变事件
        setup: function(editor) {
          editor.on('input change undo redo execCommand KeyUp', function() {
            that.$emit("validateEditor");
            if (editor.getContent()) {
							tinymce.DOM.setStyle(that.el, 'display', 'none')
						}
          })
        },

        // 图片上传配置
        images_upload_handler: (blobInfo, success, failure) => {
          let xhr, formData
          xhr = new XMLHttpRequest()
          xhr.withCredentials = false
          xhr.open('POST', `${process.env.VUE_APP_API_BASE_URL}/file/doUploadFile`)

          formData = new FormData()
          formData.append('file', blobInfo.blob())
          formData.append('bkeyCode', this.bkeyCode)

          xhr.onload = function () {
            let res

            if (xhr.status !== 200) {
              failure('HTTP Error: ' + xhr.status)
              return
            }
            res = JSON.parse(this.responseText)

            if (!res) {
              failure('Invalid JSON: ' + xhr.responseText)
              return
            }
            let data
            if (process.env.VUE_APP_ENCRYPT === 'true') {
              data = JSON.parse(that.decrypt(res.data))
            } else {
              data = JSON.parse(res.data)
            }
            success(`${process.env.VUE_APP_API_BASE_URL}/file/getPreviewPdfFileByApxId/${data.refcode}`)
          }
          xhr.send(formData)
        },
        // 图片粘贴
        paste_preprocess: function(plugin, args) {
          let imageArray = []
          args.content.replace(/<img [^>]*src=['"]([^'"]+)[^>]*>/gi, function (match, capture) {
            imageArray.push(capture)
          })
          that.uploadRemoteFile(imageArray, 0)
        },
      },
      // 上传远程图片
      uploadRemoteFile (imageArray, n) {
        if (n < imageArray.length) {
          api_file.doUploadRemoteFile({
            url: imageArray[n],
            bkeyCode: this.bkeyCode
          }).then(res => {
            let html = tinymce.activeEditor.getContent()
            html = html.replace(imageArray[n], `${process.env.VUE_APP_API_BASE_URL}/file/getPreviewPdfFileByApxId/${res.data.refcode}`)
            tinymce.activeEditor.setContent(html)
            this.uploadRemoteFile(imageArray, ++n)
          })
        }
      },
    }
  },
  mounted () {
    that = this
		that.initTinymcePlaceholder()
  },
  methods: {
    // 初始化富文本框初始化富文本框Placeholder
    initTinymcePlaceholder() {
      tinymce.PluginManager.add('placeholder', function (editor) {
        editor.on('init', function () {
          let label = new Label()
          onBlur()
          tinymce.DOM.bind(label.el, 'click', onFocus)
          editor.on('focus', onFocus)
          editor.on('blur', onBlur)
          editor.on('change', onBlur)
          editor.on('setContent', onBlur)
          function onFocus() { if (!editor.settings.readonly === true) { label.hide() } editor.execCommand('mceFocus', false) }
          function onBlur() { if (editor.getContent() === '') { label.show() } else { label.hide() } }
        })
        let Label = function () {
					let placeholderText = editor.getElement().getAttribute('placeholder') || editor.settings.placeholder
					let placeholderAttrs = editor.settings.placeholderAttrs || { style: { position: 'absolute', top: '6px', left: 0, color: '#aaaaaa', padding: '.25%', margin: '5px', width: '80%', 'font-size': '17px !important;', overflow: 'hidden', 'white-space': 'pre-wrap' } }
					let contentAreaContainer = editor.getContentAreaContainer()
          tinymce.DOM.setStyle(contentAreaContainer, 'position', 'relative')
          that.el = tinymce.DOM.add(contentAreaContainer, 'label', placeholderAttrs, placeholderText)
        }
        Label.prototype.hide = function () { tinymce.DOM.setStyle(that.el, 'display', 'none') }
        Label.prototype.show = function () { tinymce.DOM.setStyle(that.el, 'display', '') }
      })
    }
  },
}
</script>

猜你喜欢

转载自blog.csdn.net/marke_huang/article/details/86534676