首先不建议直接使用官方的 cdn 链接,因为操作起来很麻烦:
- 需要在他们官方注册账户,然后才可以拿到一串你账户专属的 cdn tinymce.min.js
- 默认这个 tinymce.min.js 只能在 localhost 域名使用,需要在账户里面设置允许使用的域名
基于以上两点,所以建议直接下载后放到项目中,或则自己部署在服务器上使用,就没有以上限制了:
- tinymce.min.js 下载地址
- language 语言包 下载页面:挑选你需要的语言,下载后放到 第一步下载解压后的 langs 目录中
下面来看下如何实现一个下图的富文本编辑器
第 0 步:导入 tinymce js
<script src="/tinymce/js/tinymce/tinymce.min.js"></script>
第 1 步:定义一个 textarea ,并给定一个唯一 ID;需要注意的是:textarea 里面的内容就是初始内容,想要文本编辑器有初始内容的话,就需要先写到 textarea 中
<textarea id="basic-example">
{{form.html}}
</textarea>
第 2 步:初始化 tinymce ,配置所需功能
data(){
retruen {
editor: null,
form: {
html: ''
}
}
},
mounted () {
this.$nextTick(() => {
this.initTinymce()
})
},
methods:{
initTinymce () {
const _this = this
const form = this.form
const handleImgUpload = this.handleImgUpload
tinymce.init({
language: 'zh_CN', // 定义语言
inline: false,
selector: 'textarea#basic-example', // 设置绑定哪一个 textarea
height: 500,
// 解决保存时,上传的图片是相对路径问题
// 上传图片如果你后端返回的是 全路径,这里一定要设置成 false,否则在保存的时候,就会变成相对路径
relative_urls : false,
remove_script_host : false,
menubar: false,
fontsize_formats: "8px 10px 12px 14px 16px 18px 20px 24px 36px 40px 50px 60px 70px 80px 90px 100px",
// 定义需要的插件,这些插件都必须存在你的下载的 tinymcejs 目录中的 plugins 目录
plugins: [
'advlist autolink lists link image charmap print preview anchor',
'searchreplace visualblocks code fullscreen',
'insertdatetime media table paste code wordcount'
],
// 定义工具类的功能区域如何排列
toolbar: 'undo redo | fontsizeselect | fontselect | formatselect | ' +
'bold italic forecolor backcolor | alignleft aligncenter ' +
'alignright alignjustify | bullist numlist outdent indent | ' +
'removeformat | image | link',
content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:14px }',
images_upload_handler (blobInfo, success, failure) {
handleImgUpload(blobInfo, success, failure)
},
// 当文本编辑器初始化后,需要做的事情,传递给你的是当前文本编辑器的实例
setup (editor) {
// 在这里使用 this 不能获取到 vue 实例,需要在外部定义好再使用
_this.editor = editor
// 注意这个实例:这里的 on 事件,支持的是 jquery 的用法
// 如 change: 编辑器失去焦点,才会触发事件
// input 就是实时触发的,可以通过监听 input 事件实时拿到编辑器中的 html
editor.on('change', () => {
form.html = editor.getContent()
})
}
})
},
// 文件上传组件,
handleImgUpload (blobInfo, success, failure) {
let formdata = new FormData()
formdata.set('file', blobInfo.blob())
// 你自己的请求工具,往后端上传图片
this.appCommDefaultExpandRes(app.axios.post('/api/file/upload', formdata))
.then(res => {
success(res)
})
.catch(error => {
failure('error')
})
}
},
// 组件销毁时,移除编辑器
beforeDestroy () {
// 解决编辑器二次打开渲染失效的问题
if (this.editor) {
this.editor.remove()
}
}
以上代码有几个点需要注意:
- 如果是在 vue 中使用,在 setup 中使用 this 的时候一定要注意,作用域拿不到 vue 的 this
- 就是一定要不用 这个文本编辑器的时候,手动将它移除,因为它使用 jquery 开发的,不移除的话,会一直存留在内存中,下一次继续初始化就会失效
下面是一些常用的 api
editor.mode.set(str)
: 设置编辑模式,可选有design
(编辑模式) 、readonly
(只读模式)editor.setContent(str)
: 设置编辑器的内容,注意:在 setup 中使用无效editor.on('input')
:监听事件,这里是它支持的事件
:::tips
有了以上的基础,其实你就可以将这个原生的封装成一个 vue 组件了。不过在 vue-cli 中使用的话,官方准备了一个已经封装好的 vue 组件
所以:以上适合没有使用 vue-cli 的场景中使用。
:::
一些问题:
在 element-ui 的 弹框(el-dialog
)中使用这个编辑器的话,工具栏里面的所有下拉框都无法正常工作,原因是他们的 css 层级比弹框的层级底,找到一个比较靠谱的方法就是全局覆盖它的一个 css
/* 解决在弹框中编辑器的所有下拉框都失效的问题 */
.tox-tinymce-aux {
z-index: 9999 !important;
}