vue项目中引入tinymce4

Posted qujialin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue项目中引入tinymce4相关的知识,希望对你有一定的参考价值。

上个项目用没记录,这次捣鼓了半天,赶紧拿小本本记下来~

ps:只实现了基本功能,图片上传有点问题,还得捣鼓捣鼓,捣鼓出来了再更新~

  1. 安装:

    npm install @tinymce/tinymce-vue -S
    npm install tinymce -S
  2. 安装之后,在 node_modules 中找到 tinymce/skins目录,然后将 skins 目录拷贝到 static 目录下,下载zh_CN.js文件也放在static/tinymce/

  3. 修改index.html文件:

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <title>graduation-project</title>
        <script src="https://cdn.bootcss.com/tinymce/4.8.4/tinymce.min.js"></script>
      </head>
      <body>
        <div id="app"></div>
        <!-- built files will be auto injected -->
      </body>
    </html>
    
  4. Editor.vue文件

    <template>
      <div style="margin: 20px auto; padding-top:20px;width: 80%;">
        <textarea :id="Id" :value="value"></textarea>
        <el-button @click="getContent">获取内容</el-button>
      </div>
    </template>
    <script>
      require('../../../static/tinymce/zh_CN.js') // 根据自己的组件路径修改
      export default {
        data () {
          const Id = Date.now()
          return {
            Id: Id,
            Editor: null,
            DefaultConfig: {
              // GLOBAL
              height: 900,
              theme: 'modern',
              menubar: false,
              toolbar: `styleselect | fontselect | formatselect | fontsizeselect | forecolor backcolor | bold italic underline strikethrough | image  media | table | alignleft aligncenter alignright alignjustify | outdent indent | numlist bullist | preview removeformat  hr | paste code  link | undo redo | fullscreen `,
              plugins: `
                paste
                importcss
                image
                code
                table
                advlist
                fullscreen
                link
                media
                lists
                textcolor
                colorpicker
                hr
                preview
              `,
              // CONFIG
    
              forced_root_block: 'p',
              force_p_newlines: true,
              importcss_append: true,
    
            // CONFIG: ContentStyle 这块很重要, 在最后呈现的页面也要写入这个基本样式保证前后一致, `table`和`img`的问题基本就靠这个来填坑了
              content_style: `
                *                         { padding:0; margin:0; }
                html, body                { height:100%; }
                img                       { max-width:100%; display:block;height:auto; }
                a                         { text-decoration: none; }
                iframe                    { width: 100%; }
                p                         { line-height:1.6; margin: 0px; }
                table                     { word-wrap:break-word; word-break:break-all; max-width:100%; border:none; border-color:#999; }
                .mce-object-iframe        { width:100%; box-sizing:border-box; margin:0; padding:0; }
                ul,ol                     { list-style-position:inside; }
              `,
              images_upload_url: 'https://sm.ms/api/upload',
              images_upload_base_path: '',
              insert_button_items: 'image link | inserttable',
    
              // CONFIG: Paste
              paste_retain_style_properties: 'all',
              paste_word_valid_elements: '*[*]',        // word需要它
              paste_data_images: true,                  // 粘贴的同时能把内容里的图片自动上传,非常强力的功能
              paste_convert_word_fake_lists: false,     // 插入word文档需要该属性
              paste_webkit_styles: 'all',
              paste_merge_formats: true,
              nonbreaking_force_tab: false,
              paste_auto_cleanup_on_paste: false,
    
              // CONFIG: Font
              fontsize_formats: '10px 11px 12px 14px 16px 18px 20px 24px',
    
              // CONFIG: StyleSelect
              style_formats: [
                {
                  title: '首行缩进',
                  block: 'p',
                  styles: { 'text-indent': '2em' }
                },
                {
                  title: '行高',
                  items: [
                    {title: '1', styles: { 'line-height': '1' }, inline: 'span'},
                    {title: '1.5', styles: { 'line-height': '1.5' }, inline: 'span'},
                    {title: '2', styles: { 'line-height': '2' }, inline: 'span'},
                    {title: '2.5', styles: { 'line-height': '2.5' }, inline: 'span'},
                    {title: '3', styles: { 'line-height': '3' }, inline: 'span'}
                  ]
                }
              ],
    
              // FontSelect
              font_formats: `
                微软雅黑=微软雅黑;
                宋体=宋体;
                黑体=黑体;
                仿宋=仿宋;
                楷体=楷体;
                隶书=隶书;
                幼圆=幼圆;
                Andale Mono=andale mono,times;
                Arial=arial, helvetica,
                sans-serif;
                Arial Black=arial black, avant garde;
                Book Antiqua=book antiqua,palatino;
                Comic Sans MS=comic sans ms,sans-serif;
                Courier New=courier new,courier;
                Georgia=georgia,palatino;
                Helvetica=helvetica;
                Impact=impact,chicago;
                Symbol=symbol;
                Tahoma=tahoma,arial,helvetica,sans-serif;
                Terminal=terminal,monaco;
                Times New Roman=times new roman,times;
                Trebuchet MS=trebuchet ms,geneva;
                Verdana=verdana,geneva;
                Webdings=webdings;
                Wingdings=wingdings,zapf dingbats`,
    
              // Tab
              tabfocus_elements: ':prev,:next',
              object_resizing: true,
    
              // Image
              imagetools_toolbar: 'rotateleft rotateright | flipv fliph | editimage imageoptions'
            }
          }
        },
        props: {
          value: {
            default: '',
            type: String
          },
          config: {
            type: Object,
            default: () => {
              return {
                theme: 'modern',
                height: 600
              }
            }
          },
          url: {
            default: '',
            type: String
          },
          accept: {
            default: 'image/jpeg, image/png',
            type: String
          },
          maxSize: {
            default: 2097152,
            type: Number
          },
          withCredentials: {
            default: false,
            type: Boolean
          }
        },
         headers: {
         'Content-type': 'application/json;charset=UTF-8'
          },
        mounted () {
          this.init()
        },
        beforeDestroy () {
          // 销毁tinymce
          this.$emit('on-destroy')
          window.tinymce.remove(document.getElementById(`{this.Id}`))
        },
    
        methods: {
          // 上传主图
          myFunction (){
            var x=document.getElementById("mainfile")
            var f= document.getElementById("mainfile").files[0]
            var formData=new FormData()
            var xmlhttp
            var self = this
            if (window.XMLHttpRequest)
            {
              //  IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
              xmlhttp=new XMLHttpRequest()
            }
            else
            {
              // IE6, IE5 浏览器执行代码
              xmlhttp=new ActiveXObject("Microsoft.XMLHTTP")
            }
            xmlhttp.onreadystatechange=function()
            {
              if (xmlhttp.readyState==4 && xmlhttp.status==200)
              {
                self.sproduct.pictures=JSON.parse(xmlhttp.responseText).data.url
              }
            }
            formData.append('smfile',f)
            xmlhttp.open('POST', 'https://sm.ms/api/upload',false)
            xmlhttp.send(formData)
          },
           init () {
             const self = this
    
            this.Editor = window.tinymce.init({
              // 默认配置
              ...this.DefaultConfig,
              // 图片上传
              images_upload_handler: function (blobInfo, success, failure) {
                if (blobInfo.blob().size > self.maxSize) {
                  failure('文件体积过大')
                }
    
                if (self.accept.indexOf(blobInfo.blob().type) >= 0) {
                  uploadPic()
                } else {
                  failure('图片格式错误')
                }
                function uploadPic () {
                  const xhr = new XMLHttpRequest()
                  const formData = new FormData()
                  formData.append('smfile', blobInfo.blob())
                  xhr.open('POST', 'https://sm.ms/api/upload')
                  xhr.onload = function () {
    
                    if (xhr.status !== 200) {
                      // 抛出 'on-upload-fail' 钩子
                      self.$emit('on-upload-fail')
                      failure('上传失败: ' + xhr.status)
                      return
                    }
    
                    const json = JSON.parse(xhr.responseText)
                    // 抛出 'on-upload-complete' 钩子
                    console.log(json.data.url)
                    self.$emit('on-upload-complete' , [
                      json.data, success, failure
                    ])
                     success(json.data.url)
                  }
                  formData.append('smfile', blobInfo.blob())
                  xhr.send(formData)
                }
              },
    
              // prop内传入的的config
              ...this.config,
    
              // 挂载的DOM对象
              selector: `#${this.Id}`,
              setup: (editor) => {
                // 抛出 'on-ready' 事件钩子
                editor.on(
                  'init', () => {
                    self.loading = false
                    self.$emit('on-ready')
                    editor.setContent(self.value)
                  }
                )
                // 抛出 'input' 事件钩子,同步value数据
                editor.on(
                  'input change undo redo', () => {
                    self.$emit('input', editor.getContent())
                  }
                )
              }
            })
          },
          getContent () {
            console.log(tinymce.editors[0].getContent())
          }
        }
      }
    </script>
    

    参考链接:

https://www.cnblogs.com/wisewrong/p/8985471.html

http://tinymce.ax-z.cn/advanced/some-example.php

以上是关于vue项目中引入tinymce4的主要内容,如果未能解决你的问题,请参考以下文章

Vue项目增加TinyMec富文本编辑器组件

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

在vue项目中正确的引入jquery

VUE项目引入jquery

Tinymce4 中Ajax多次加载时,会出现菜单在第二次进入时,显示的下拉菜单在左上角

vue工程化之项目引入jquery