第三方中文文档

    首先不建议直接使用官方的 cdn 链接,因为操作起来很麻烦:

    1. 需要在他们官方注册账户,然后才可以拿到一串你账户专属的 cdn tinymce.min.js
    2. 默认这个 tinymce.min.js 只能在 localhost 域名使用,需要在账户里面设置允许使用的域名

    基于以上两点,所以建议直接下载后放到项目中,或则自己部署在服务器上使用,就没有以上限制了:

    1. tinymce.min.js 下载地址
    2. language 语言包 下载页面:挑选你需要的语言,下载后放到 第一步下载解压后的 langs 目录中

    下面来看下如何实现一个下图的富文本编辑器
    image.png
    第 0 步:导入 tinymce js

    1. <script src="/tinymce/js/tinymce/tinymce.min.js"></script>

    第 1 步:定义一个 textarea ,并给定一个唯一 ID;需要注意的是:textarea 里面的内容就是初始内容,想要文本编辑器有初始内容的话,就需要先写到 textarea 中

    1. <textarea id="basic-example">
    2. {{form.html}}
    3. </textarea>

    第 2 步:初始化 tinymce ,配置所需功能

    1. data(){
    2. retruen {
    3. editor: null,
    4. form: {
    5. html: ''
    6. }
    7. }
    8. },
    9. mounted () {
    10. this.$nextTick(() => {
    11. this.initTinymce()
    12. })
    13. },
    14. methods:{
    15. initTinymce () {
    16. const _this = this
    17. const form = this.form
    18. const handleImgUpload = this.handleImgUpload
    19. tinymce.init({
    20. language: 'zh_CN', // 定义语言
    21. inline: false,
    22. selector: 'textarea#basic-example', // 设置绑定哪一个 textarea
    23. height: 500,
    24. // 解决保存时,上传的图片是相对路径问题
    25. // 上传图片如果你后端返回的是 全路径,这里一定要设置成 false,否则在保存的时候,就会变成相对路径
    26. relative_urls : false,
    27. remove_script_host : false,
    28. menubar: false,
    29. fontsize_formats: "8px 10px 12px 14px 16px 18px 20px 24px 36px 40px 50px 60px 70px 80px 90px 100px",
    30. // 定义需要的插件,这些插件都必须存在你的下载的 tinymcejs 目录中的 plugins 目录
    31. plugins: [
    32. 'advlist autolink lists link image charmap print preview anchor',
    33. 'searchreplace visualblocks code fullscreen',
    34. 'insertdatetime media table paste code wordcount'
    35. ],
    36. // 定义工具类的功能区域如何排列
    37. toolbar: 'undo redo | fontsizeselect | fontselect | formatselect | ' +
    38. 'bold italic forecolor backcolor | alignleft aligncenter ' +
    39. 'alignright alignjustify | bullist numlist outdent indent | ' +
    40. 'removeformat | image | link',
    41. content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:14px }',
    42. images_upload_handler (blobInfo, success, failure) {
    43. handleImgUpload(blobInfo, success, failure)
    44. },
    45. // 当文本编辑器初始化后,需要做的事情,传递给你的是当前文本编辑器的实例
    46. setup (editor) {
    47. // 在这里使用 this 不能获取到 vue 实例,需要在外部定义好再使用
    48. _this.editor = editor
    49. // 注意这个实例:这里的 on 事件,支持的是 jquery 的用法
    50. // 如 change: 编辑器失去焦点,才会触发事件
    51. // input 就是实时触发的,可以通过监听 input 事件实时拿到编辑器中的 html
    52. editor.on('change', () => {
    53. form.html = editor.getContent()
    54. })
    55. }
    56. })
    57. },
    58. // 文件上传组件,
    59. handleImgUpload (blobInfo, success, failure) {
    60. let formdata = new FormData()
    61. formdata.set('file', blobInfo.blob())
    62. // 你自己的请求工具,往后端上传图片
    63. this.appCommDefaultExpandRes(app.axios.post('/api/file/upload', formdata))
    64. .then(res => {
    65. success(res)
    66. })
    67. .catch(error => {
    68. failure('error')
    69. })
    70. }
    71. },
    72. // 组件销毁时,移除编辑器
    73. beforeDestroy () {
    74. // 解决编辑器二次打开渲染失效的问题
    75. if (this.editor) {
    76. this.editor.remove()
    77. }
    78. }

    以上代码有几个点需要注意:

    1. 如果是在 vue 中使用,在 setup 中使用 this 的时候一定要注意,作用域拿不到 vue 的 this
    2. 就是一定要不用 这个文本编辑器的时候,手动将它移除,因为它使用 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

    1. /* 解决在弹框中编辑器的所有下拉框都失效的问题 */
    2. .tox-tinymce-aux {
    3. z-index: 9999 !important;
    4. }