tinymce + vue 实现富文本

相对功能较全的富文本功能,文件,图片上传功能实现,富文本内容较长时,建议内容上传接口以文件形式保存

"@tinymce/tinymce-vue": "^3.2.8",

"tinymce": "^5.7.0",

```

<template>

  <div class="tinymce">

    <!-- <h1>tinymce</h1> -->

    <editor id="tinymce" v-model="tinymceHtml" :init="init" />

  </div>

</template>

<script>

import tinymce from 'tinymce/tinymce'

import 'tinymce/themes/silver/theme'

import Editor from '@tinymce/tinymce-vue'

import 'tinymce/icons/default' // 引入编辑器图标icon,不引入则不显示对应图标

import 'tinymce/plugins/image'

import 'tinymce/plugins/link'

import 'tinymce/plugins/code'

import 'tinymce/plugins/table'

import 'tinymce/plugins/lists'

import 'tinymce/plugins/contextmenu'

import 'tinymce/plugins/wordcount'

import 'tinymce/plugins/colorpicker'

import 'tinymce/plugins/textcolor'

export default {

  name: 'Tinymce',

  // 声明最原始的tinymce组件

  components: { Editor },

  props: {

    // tinyvalue首先在父组件中定义,用于向本子组件mytinymce发送数据

    // 然后在这里声明,用于本子组件接收父组件数据

    tinyvalue: {

      type: String,

      default: ''

    },

    richtextid: {

      type: String,

      required: true

    }

  },

  data() {

    return {

      // 子组件的数据变量,默认未父组件传递过来的数据

      tinymceHtml: this.tinyvalue,

      // tinymce默认配置参数,含插件,请注意插件路径,如果错误容易保unexpect token ','之类错误

      init: {

        relative_urls: true,

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

        language: 'zh_CN',

        skin_url: '../../tinymce/skins/ui/oxide-dark',

        height: 500,

        plugins:

          // 'link lists image code table colorpicker textcolor wordcount contextmenu',

          'link lists image code table colorpicker textcolor wordcount contextmenu',

        toolbar:

          'bold italic underline strikethrough | fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist | outdent indent blockquote | undo redo | link unlink image code | removeformat',

        branding: false,

        paste_data_images: true,

        file_picker_types: 'file',

        file_picker_callback: (callback, value, meta) => {

        // 文件分类

          var filetype = '.pdf, .txt, .zip, .rar, .7z, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .mp3, .mp4'

          var _this = this

          var input = document.createElement('input')

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

          input.setAttribute('accept', filetype)

          input.click()

          input.onchange = function() {

            var file = this.files[0]

            const params = new FormData()

            params.append('file', file)

            params.append('resourceId', _this.richtextid)

            const config = {

              headers: {

                'Content-Type': 'multipart/form-data'

              }

            }

            // // aixo的声明在全局main.js中,这里不粘贴了

            _this.$https

              .post(`${process.env.VUE_APP_BASE_API}/richText/uploadRichEnclFile`, params, config)

              .then((res) => {

                if (res.data.code === 200) {

                  callback(res.data.data, { text: file.name, title: file.name })

                } else {

                  // failure('上传失败')

                }

              })

              .catch(() => {

                // failure('上传出错,服务器开小差了呢')

              })

          }

        },

        // 增加下面的images_upload_handler对象,能够支持上传图片到服务器

        images_upload_handler: (blobInfo, success, failure) => {

          // console.log(blobInfo.blob())

          if (blobInfo.blob().size / 1024 / 1024 > 5) {

            failure('上传失败,图片大小请控制在 5M 以内')

          } else {

            const params = new FormData()

            params.append('file', blobInfo.blob())

            params.append('resourceId', this.richtextid)

            const config = {

              headers: {

                'Content-Type': 'multipart/form-data'

              }

            }

            // aixo的声明在全局main.js中,这里不粘贴了

            this.$https

              .post(`${process.env.VUE_APP_BASE_API}/richText/uploadImg`, params, config)

              .then((res) => {

                if (res.data.code === 200) {

                  // const resp = res.data.data

                  // const url = resp.schemeIpPort + resp.dir + '/' + resp.subDir + '/' + resp.filename

                  const url = res.data.data

                  success(url)

                  // 上传成功,在成功函数里填入图片路径

                  // var img = `<img alt="" src="${url}" />`

                  // this.tinymceHtml += img

                } else {

                  failure('上传失败')

                }

              })

              .catch(() => {

                failure('上传出错,服务器开小差了呢')

              })

          }

        }

      }

    }

  },

  watch: {

    // 监听内容变化,用于辅助父子组件之间的通讯

    tinyvalue(newValue) {

      // tinyvalue是父组件代理人,父组件值一旦变化,推送给子组件

      this.tinymceHtml = newValue

    },

    tinymceHtml(newValue) {

      // tinymceHtml是子组件的值,如果改变,直接反馈给父组件

      //   tinymceinput是父组件中的用于接收子组件的事件(名称写死,用于后面调用)

      this.$emit('tinymceinput', newValue)

    }

  },

  mounted() {

    // 初始化加载配置项

    tinymce.init({})

  },

  methods: {}

}

</script>

```

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容