You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
4.5 KiB
131 lines
4.5 KiB
/* eslint-disable */
|
|
<template>
|
|
<textarea :id="tinymceId" style="visibility: hidden;" />
|
|
</template>
|
|
|
|
<script>
|
|
import loadTinymce from '@/utils/loadTinymce'
|
|
import {plugins, toolbar} from './config'
|
|
import {debounce} from 'throttle-debounce'
|
|
import constants from '@/utils/constants'
|
|
|
|
let num = 1
|
|
|
|
export default {
|
|
name: 'Tinymce',
|
|
props: {
|
|
id: {
|
|
type: String,
|
|
default: () => {
|
|
num === 10000 && (num = 1)
|
|
return `tinymce${+new Date()}${num++}`
|
|
}
|
|
},
|
|
value: {
|
|
default: ''
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
tinymceId: this.id
|
|
}
|
|
},
|
|
mounted() {
|
|
|
|
loadTinymce(tinymce => {
|
|
let token = this.getUserToken()
|
|
let uploadUrl = constants.userUploadUrl
|
|
// eslint-disable-next-line global-require
|
|
require('./zh_CN')
|
|
let conf = {
|
|
selector: `#${this.tinymceId}`,
|
|
language: 'zh_CN',
|
|
menubar: 'false',
|
|
skin_url: '/'+process.env.VUE_APP_PUBLIC_PATH+'/tinymce/skins/ui/tduck',
|
|
content_css: '/'+process.env.VUE_APP_PUBLIC_PATH +'/tinymce/skins/content/tduck',
|
|
cache_suffix: '?v=0.0.1',
|
|
plugins,
|
|
toolbar,
|
|
toolbar_drawer: 'sliding',
|
|
toolbar_mode: 'sliding',
|
|
height: 200,
|
|
// fontsize_formats: "8pt 10pt 12pt 14pt 18pt 24pt 36pt",
|
|
branding: false,
|
|
object_resizing: false,
|
|
end_container_on_empty_block: true,
|
|
powerpaste_word_import: 'clean',
|
|
code_dialog_height: 450,
|
|
code_dialog_width: 1000,
|
|
advlist_bullet_styles: 'square',
|
|
advlist_number_styles: 'default',
|
|
default_link_target: '_blank',
|
|
link_title: false,
|
|
statusbar: false,
|
|
nonbreaking_force_tab: true,
|
|
images_upload_handler: function(blobInfo, succFun, failFun) {
|
|
var xhr, formData
|
|
var file = blobInfo.blob()// 转化为易于理解的file对象
|
|
xhr = new XMLHttpRequest()
|
|
xhr.withCredentials = false
|
|
xhr.open('POST', uploadUrl)
|
|
xhr.setRequestHeader('token', token)
|
|
xhr.onload = function() {
|
|
var json
|
|
if (xhr.status != 200) {
|
|
failFun('HTTP Error: ' + xhr.status)
|
|
return
|
|
}
|
|
json = JSON.parse(xhr.responseText)
|
|
if (!json || typeof json.data != 'string') {
|
|
failFun('Invalid JSON: ' + xhr.responseText)
|
|
return
|
|
}
|
|
succFun(json.data)
|
|
}
|
|
formData = new FormData()
|
|
formData.append('file', file, file.name)// 此处与源文档不一样
|
|
xhr.send(formData)
|
|
}
|
|
}
|
|
conf = Object.assign(conf, this.$attrs)
|
|
conf.init_instance_callback = editor => {
|
|
if (this.value) editor.setContent(this.value)
|
|
this.vModel(editor)
|
|
}
|
|
tinymce.init(conf)
|
|
})
|
|
},
|
|
destroyed() {
|
|
this.destroyTinymce()
|
|
},
|
|
methods: {
|
|
vModel(editor) {
|
|
// 控制连续写入时setContent的触发频率
|
|
const debounceSetContent = debounce(250, editor.setContent)
|
|
this.$watch('value', (val, prevVal) => {
|
|
if (editor && val !== prevVal && val !== editor.getContent()) {
|
|
if (typeof val !== 'string') val = val.toString()
|
|
debounceSetContent.call(editor, val)
|
|
}
|
|
})
|
|
|
|
editor.on('change keyup undo redo', () => {
|
|
this.$emit('input', editor.getContent())
|
|
})
|
|
editor.on('blur', () => {
|
|
this.$emit('blur')
|
|
})
|
|
},
|
|
getUserToken() {
|
|
return this.$store.getters['user/isLogin']
|
|
},
|
|
destroyTinymce() {
|
|
if (!window.tinymce) return
|
|
const tinymce = window.tinymce.get(this.tinymceId)
|
|
if (tinymce) {
|
|
tinymce.destroy()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|