vue使用tinymce富文本框组件,实现了上传和复制粘贴,包括处理Placeholder鼠标点击后不显示
<template><div><editor id='tinymce' v-model='tinymceHtml' :placeholder="placeholderHtml" :init='editorInit'></editor></div&
·
<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>
更多推荐
已为社区贡献2条内容
所有评论(0)