zoukankan      html  css  js  c++  java
  • 在vue cli 3脚手架里引入tinymce 5富文本编辑器

    本文主要讲的是在Vue cli 3脚手架搭建的项目里如何引用Tinymce 5富文本编辑器。

    请注意识别“版本号”,不同版本的配置细节有所不同。
    

    tinymce的安装

    安装tinymce-vue

    npm install @tinymce/tinymce-vue -S
    

    安装tinymce

    npm install tinymce -S
    

    下载中文语言包

    tinymce提供的语言包很多,选择下载中文语言包

    使用方法

    文件操作

    • 在项目根目录的public目录下新建tinymce文件夹,将下载的中文语言包解压后放在该文件夹下
    • 在依赖包node_modules里找到tinymce文件夹,将里面的skins文件夹复制到public/tinymce目录下

    目录截图

    tinymce初始化

    引入基本文件

    // 引入组件
    import tinymce from 'tinymce/tinymce'
    import Editor from '@tinymce/tinymce-vue'
    // 引入富文本编辑器主题的js和css
    import 'tinymce/themes/silver/theme.min.js'
    import 'tinymce/skins/ui/oxide/skin.min.css'
    // 扩展插件
    import 'tinymce/plugins/image'
    import 'tinymce/plugins/link'
    import 'tinymce/plugins/code'
    import 'tinymce/plugins/table'
    import 'tinymce/plugins/lists'
    import 'tinymce/plugins/wordcount'
    

    注册组件并使用

    注册组件

    components: { Editor }
    

    使用组件

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

    初始化配置项

    editorInit: {
        selector: '#tinymce',
        language_url: '/tinymce/langs/zh_CN.js',
        language: 'zh_CN',
        skin_url: '/tinymce/skins/ui/oxide',
        height: 300,
        plugins: 'link lists image code table wordcount',
        toolbar: 'bold italic underline strikethrough | fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist | outdent indent blockquote | undo redo | link unlink image code | removeformat',
        images_upload_handler: (blobInfo, success, failure) => {
          this.handleImgUpload(blobInfo, success, failure)
        },
        statusbar: true // 底部的状态栏
        menubar: true, // 最上方的菜单
        branding: false // 水印“Powered by TinyMCE”
    }
    

    简单demo

    <template>
      <div class="activeConfig">
        <div class="activeConfig-container">
          <Editor id="tinymce" v-model="tinymceHtml" :init="editorInit" />
        </div>
      </div>
    </template>
    
    <script>
    // 引入组件
    import tinymce from 'tinymce/tinymce'
    import Editor from '@tinymce/tinymce-vue'
    // 引入富文本编辑器主题的js和css
    import 'tinymce/themes/silver/theme.min.js'
    import 'tinymce/skins/ui/oxide/skin.min.css'
    // 扩展插件
    import 'tinymce/plugins/image'
    import 'tinymce/plugins/link'
    import 'tinymce/plugins/code'
    import 'tinymce/plugins/table'
    import 'tinymce/plugins/lists'
    import 'tinymce/plugins/wordcount'
    // 引入api
    import { uploadImgage } from '@/api/activeConfig'
    
    export default {
      name: 'ActiveConfig',
      components: { Editor },
      data() {
        return {
          // tinymce的绑定值
          tinymceHtml: '',
          // tinymce的初始化配置
          editorInit: {
            selector: '#tinymce',
            language_url: '/tinymce/langs/zh_CN.js',
            language: 'zh_CN',
            skin_url: '/tinymce/skins/ui/oxide',
            height: 300,
            plugins: 'link lists image code table wordcount',
            toolbar: 'bold italic underline strikethrough | fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist | outdent indent blockquote | undo redo | link unlink image code | removeformat',
            // 此处为图片上传处理函数
            images_upload_handler: (blobInfo, success, failure) => {
              this.handleImgUpload(blobInfo, success, failure)
            },
            statusbar: true // 底部的状态栏
            menubar: true, // 最上方的菜单
            branding: false // 水印“Powered by TinyMCE”
          }
        }
      },
      mounted() {
        tinymce.init({})
      },
      methods: {
        // 图片上传
        handleImgUpload(blobInfo, success, failure) {
          this.baseUrl = process.env.VUE_APP_BASE_URL
          const imgBase64 = `data:${blobInfo.blob().type};base64,${blobInfo.base64()}`
          const data = { img: [imgBase64] }
          uploadImgage(data).then(res => {
            // 传入success回调里的数据就是富文本编辑器里插入图片的src的值
            success(`${this.baseUrl}/${res.data[0]}`)
          }).catch(() => { failure('error') })
        }
      }
    }
    </script>
    
    <style lang="scss" scoped>
    .activeConfig {
      &-container {
        margin: 30px;
      }
    }
    </style>
    

    封装组件

    简单封装一下,方便使用

    <template>
      <div class="tinymce-editor">
        <Editor
          :id="editorId"
          v-model="editorValue"
          :init="editorInit"
          :disabled="disabled"
          @onClick="handleClick"
        />
      </div>
    </template>
    
    <script>
    // 引入组件
    import tinymce from 'tinymce/tinymce'
    import Editor from '@tinymce/tinymce-vue'
    // 引入富文本编辑器主题的js和css
    import 'tinymce/themes/silver/theme.min.js'
    import 'tinymce/skins/ui/oxide/skin.min.css'
    // 扩展插件
    import 'tinymce/plugins/image'
    import 'tinymce/plugins/link'
    import 'tinymce/plugins/code'
    import 'tinymce/plugins/table'
    import 'tinymce/plugins/lists'
    import 'tinymce/plugins/wordcount' // 字数统计插件
    
    export default {
      name: 'TinymceEditor'
      components: { Editor },
      props: {
        id: {
          type: String,
          default: 'tinymceEditor'
        },
        value: {
          type: String,
          default: ''
        },
        disabled: {
          type: Boolean,
          default: false
        },
        plugins: {
          type: [String, Array],
          default: 'link lists image code table wordcount'
        },
        toolbar: {
          type: [String, Array],
          default: 'bold italic underline strikethrough | fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist | outdent indent blockquote | undo redo | link unlink image code | removeformat'
        }
      },
      data() {
        return {
          editorInit: {
            language_url: '/tinymce/langs/zh_CN.js',
            language: 'zh_CN',
            skin_url: '/tinymce/skins/ui/oxide',
            height: 300,
            plugins: this.plugins,
            toolbar: this.toolbar,
            statusbar: true, // 底部的状态栏
            menubar: true, // 最上方的菜单
            branding: false, // 水印“Powered by TinyMCE”
            images_upload_handler: (blobInfo, success, failure) => {
              this.$emit('handleImgUpload', blobInfo, success, failure)
            }
          },
          editorId: this.id,
          editorValue: this.value
        }
      },
      watch: {
        editorValue(newValue) {
          this.$emit('input', newValue)
        }
      },
      mounted() {
        tinymce.init({})
      },
      methods: {
        // https://github.com/tinymce/tinymce-vue => All available events
        handleClick(e) {
          this.$emit('onClick', e, tinymce)
        },
        clear() {
          this.editorValue = ''
        }
      }
    }
    </script>
    
    

    封装组件后demo

    使用组件的完整demo示例

    <template>
      <div class="demo">
        <tinymce-editor
          :id="editorId"
          ref="editor"
          v-model="message"
          :disabled="isEditorDisabled"
          @input="handleInput"
          @onClick="handleClick"
          @handleImgUpload="imgUpload"
        />
        <div class="demo-btn">
          <el-button type="primary" @click="clearClick">清空内容</el-button>
          <el-button @click="disableClick">{{ !isEditorDisabled ? '禁用' : '启用' }}</el-button>
        </div>
      </div>
    </template>
    
    <script>
    import TinymceEditor from '@/components/TinymceEditor'
    
    export default {
      components: { TinymceEditor },
      data() {
        return {
          message: '我经常被生活锤得心灰意冷,可我从来都没放弃过。',
          editorId: 'editor-demo',
          isEditorDisabled: false
        }
      },
      methods: {
        // 输入事件
        handleInput(value) {
          console.log(value)
        },
        // 点击事件
        handleClick(e, editor) {
          console.log(e, editor)
        },
        // 上传图片
        imgUpload(blobInfo, success, failure) {
          const imgBase64 = `data:${blobInfo.blob().type};base64,${blobInfo.base64()}`
          success(imgBase64)
        },
        // 清空事件
        clearClick() {
          this.$refs.editor.clear()
        },
        // 禁用事件
        disableClick() {
          this.isEditorDisabled = !this.isEditorDisabled
        }
      }
    }
    </script>
    
    <style lang="scss" scoped>
    .demo {
      margin: 30px;
      &-btn {
        text-align: center;
        margin: 10px;
      }
    }
    </style>
    
    
  • 相关阅读:
    D3.js中对array的使用
    kibana中信息分类查询显示的方法
    JAVA异常机制简述
    Google Web Toolkit(GWT) 在windows下环境搭建
    zico源代码分析(二) 数据读取和解析部分
    zico源代码分析(一) 数据接收和存储部分
    eclipse中导入zico Maven项目
    Zorka和zico实现不同主机之间的交互
    【转载】使用logstash+elasticsearch+kibana快速搭建日志平台
    LA 3644 易爆物 并查集
  • 原文地址:https://www.cnblogs.com/ykCoder/p/12106536.html
Copyright © 2011-2022 走看看