zoukankan      html  css  js  c++  java
  • 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; 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-100%; display:block;height:auto; }
                  a                         { text-decoration: none; }
                  iframe                    {  100%; }
                  p                         { line-height:1.6; margin: 0px; }
                  table                     { word-wrap:break-word; word-break:break-all; max-100%; border:none; border-color:#999; }
                  .mce-object-iframe        { 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

    梦还远,路还长!
  • 相关阅读:
    事件的解密
    C#世界中的委托
    这次是C#中的接口
    完全二叉树的建立和翻转
    全排列的应用
    网易笔试-按位或运算
    柱状图的最大矩形--单调栈
    Linux将线程绑定到CPU内核运行
    Windows多线程与线程绑定CPU内核
    B+树介绍
  • 原文地址:https://www.cnblogs.com/qujialin/p/12273896.html
Copyright © 2011-2022 走看看