前端vue-TinyMCE富文本编辑器表情插件报错解决

vue

最近项目中需要使用文本编辑器,比较了下最终选择了TinyMCE这款富文本编辑器
我安装的是TinyMCE v5但是在使用表情插件的时候,表情一直都出不来,报错信息如下:

Uncaught SyntaxError: Unexpected token '<'

Failed to load emoticons: Script at URL

"http://xxxx/static/js/plugins/emoticons/js/emojis.js" did not call

`tinymce.Resource.add('tinymce.plugins.emoticons', data)` within 1 second

  这个是路径出问题了,导致emojis.js没有被正确导入,所以表情也就没有出来。

我们只在用到TinyMce富文本编辑器的组件中,引入表情emojis.js文件即可。

代码是这段。

import 'tinymce/plugins/emoticons/js/emojis';

在我的项目中是有TinyMce的文件夹。

我在src目录下有一个公共组件文件夹components,在这个文件夹下面有一个封装的富文本编辑器组件。看代码----------------------------------

这是HTML部分

<template>

<div class="tinymce-editor">

<editor

v-if="!reloading"

v-model="myValue"

:init="init"

:disabled="disabled"

@onClick="onClick">

</editor>

</div>

</template>

 这是js部分

<script>

import tinymce from 'tinymce/tinymce'

import Editor from '@tinymce/tinymce-vue'

import 'tinymce/themes/silver/theme'

import 'tinymce/plugins/image'

import 'tinymce/plugins/link'

import 'tinymce/plugins/media'

import 'tinymce/plugins/table'

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/icons/default'

import 'tinymce/plugins/emoticons'

import "../../../public/tinymce/plugins/media" /*不显示占位图片的插件*/

import "tinymce/plugins/preview"

import "tinymce/plugins/code"

import "tinymce/plugins/insertdatetime"

import "tinymce/plugins/template"

import 'tinymce/plugins/emoticons/js/emojis';

import { uploadAction,getFileAccessHttpUrl } from '@/api/manage'

import { getVmParentByName } from '@/utils/util'

export default {

components: {

Editor

},

props: {

value: {

type: String,

required:false

},

triggerChange:{

type: Boolean,

default: false,

required:false

},

disabled: {

type: Boolean,

default: false

},

plugins: {

type: [String, Array],

default: 'lists image link media table textcolor wordcount contextmenu fullscreen emoticons preview code insertdatetime '

},

toolbar: {

type: [String, Array],

default: 'undo redo | formatselect | bold italic forecolor backcolor | fontsizeselect | code | emoticons | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | lists link unlink image media table | insertdatetime | removeformat| preview | fullscreen ',

branding:false

}

},

data() {

return {

//初始化配置

init: {

language_url: '/tinymce/langs/zh_CN.js',

language: 'zh_CN',

skin_url: '/tinymce/skins/ui/oxide',

height: 150,

plugins: this.plugins,

toolbar: this.toolbar,

branding: false,

menubar: false,

toolbar_drawer: false,

auto_focus : true,

file_picker_callback:'media',

file_picker_types:'media',

images_upload_handler: (blobInfo, success) => {

let formData = new FormData()

formData.append('file', blobInfo.blob(), blobInfo.filename());

formData.append('biz', "jeditor");

formData.append("jeditor","1");

uploadAction(window._CONFIG['domianURL']+"/sys/common/upload", formData).then((res) => {

if (res.success) {

if(res.message == 'local'){

const img = 'data:image/jpeg;base64,' + blobInfo.base64()

success(img)

}else{

let img = getFileAccessHttpUrl(res.message)

success(img)

}

}

})

},

},

myValue: this.value,

reloading: false,

}

},

mounted() {

this.initATabsChangeAutoReload()

},

methods: {

file_picker_callback: function (cb, value, meta) {

if (meta.filetype === 'media'){

//模拟上传视频

let input = document.createElement('input')

input.setAttribute('type','file')

input.onchange = function (){

let file = this.files[0]

_this.uploadMv(file)

if(_this.uploaded){

cb(_this.mvUrl)

}else {

setTimeout(()=>{

//设置几秒之后再取数据

cb(_this.mvUrl)

},1000)

}

}

//触发点击

input.click()

}

},

uploadMv(file){

let content = file;

let formData = new FormData();

formData.append('mv',content);

},

reload() {

this.reloading = true

this.$nextTick(() => this.reloading = false)

},

onClick(e) {

this.$emit('onClick', e, tinymce)

},

//可以添加一些自己的自定义事件,如清空内容

clear() {

this.myValue = ''

},

/**

* 自动判断父级是否是 <a-tabs/> 组件,然后添加事件监听,自动触发reload()

*

* 由于 tabs 组件切换会导致 tinymce 无法输入,

* 只有重新加载才能使用(无论是vue版的还是jQuery版tinymce都有这个通病)

*/

initATabsChangeAutoReload() {

// 获取父级

let tabs = getVmParentByName(this, 'ATabs')

let tabPane = getVmParentByName(this, 'ATabPane')

if (tabs && tabPane) {

// 用户自定义的 key

let currentKey = tabPane.$vnode.key

// 添加事件监听

tabs.$on('change', (key) => {

// 切换到自己时执行reload

if (currentKey === key) {

this.reload()

}

})

//update--begin--autor:liusq-----date:20210316------for:富文本编辑器tab父组件可能导致的赋值问题------

this.reload()

//update--end--autor:liusq-----date:20210316------for:富文本编辑器tab父组件可能导致的赋值问题------

}else{

//update--begin--autor:wangshuai-----date:20200724------for:富文本编辑器切换tab无法修改------

let tabLayout = getVmParentByName(this, 'TabLayout')

//update--begin--autor:liusq-----date:20210713------for:处理特殊情况excuteCallback不能使用------

try {

tabLayout.excuteCallback(() => {

this.reload()

})

} catch (error) {

if (tabLayout) {

this.reload()

}

}

//update--end--autor:liusq-----date:20210713------for:处理特殊情况excuteCallback不能使用------

//update--begin--autor:wangshuai-----date:20200724------for:文本编辑器切换tab无法修改------

}

},

},

watch: {

value(newValue) {

this.myValue = (newValue == null ? '' : newValue)

},

myValue(newValue) {

if(this.triggerChange){

this.$emit('change', newValue)

}else{

this.$emit('input', newValue)

}

}

}

}

</script>

这就是封装好的tinyMce,里面包含了,你会用到的所有的功能,对你有帮助的话,不妨点个赞吧。谢谢啦!!!

如果还有哪里不太懂的记得关注私信我。

以上是 前端vue-TinyMCE富文本编辑器表情插件报错解决 的全部内容, 来源链接: utcz.com/z/378435.html

回到顶部