vue2使用TinyMCE7富文本编辑器实现拖拽插入内容功能

引入的方法步骤

vue2引入tinymce7最简单的方法

实现拖拽借鉴的思路

实现内容拖拽或添加 HTML 到 Tinymce 富文本编辑器的高级功能详解
需求场景:
请添加图片描述
从列表项拖拽进编辑器实现思路:

  1. 页面元素添加拖拽属性和拖拽事件, 利用 event.dataTransfer.setData 方法传递数据
<div
     draggable="true"
     @dragstart="(event) => onDragStart(event)"
   >
    onDragStart(event) {
      const html = `<span class="mceNonEditable field">[${event.target.lastChild.innerText}]</span>`
      event.dataTransfer.setData('text/html', html)
    },
  1. 在编辑器组件的 setup 配置项中, 注册 drop 事件, 在该事件中接收传递的数据, 并将数据内容插入编辑器中
const opts = {
    setup: (editor) => {
            editor.on('drop', function (event) {
	            event.preventDefault()
	            var htmlContent = event.dataTransfer.getData('text/html')
	            editor.insertContent(htmlContent)
          })
	}
}

去除菜单栏工具栏

 menubar: '',
 plugins: '',
 toolbar: [],
 elementpath: false,
 resize: 'false',

修改编辑器内部样式 (包括placeholder)

content_style:
  'p { margin:10px 0; color:#333; fontSize:15px; }' +
  'body { margin:10px; }' +
  '.mce-content-body:not([dir=rtl])[data-mce-placeholder]:not(.mce-visualblocks)::before { color:#96a1af;font-size:13px; }', // 修改 placeholder 样式

坑: editor.insertContent 失效
原因: 当调用子组件的 getValue 方法时, 该方法中的 this.editor.selection.select(editBody) 会导致 insertContent 方法失效
解决: 监听 editor 的变动, 更新父组件的数据

获取编辑器纯文本

思路: 利用 getContent 方法进行纯文本格式化

getValue() {
  const text = this.editor.getContent({
  format: 'text',
  })
  return text
},

遇到的问题: 编辑器在激活之后, 光标会跑到最前端

解决方法:

    endCommand() {
      this.editor.selection.select(this.editor.getBody(), true)
      this.editor.selection.collapse(false)
      this.editor.focus()
    }, 

在点击计算字段列表项后, 调用 endCommand 方法, 即可使光标在最后端
请添加图片描述
参考:
在tinyMCE中, 如何设置以及获取光标位置

组件代码:

<template>
  <div style="height: 100%">
    <textarea ref="textarea" id="tinymce-editor"></textarea>
  </div>
</template>

<script>
import tinymce from 'tinymce/tinymce'
import 'tinymce/skins/ui/oxide/skin'
import 'tinymce/themes/silver/theme'
import 'tinymce/icons/default/icons'
import 'tinymce/models/dom/model'

export default {
  name: 'TinyEditor',
  components: {},
  props: {
    // value: String,
  },
  data() {
    return {
      editor: null,
      bookmark: null,
    }
  },
  watch: {
    // value: {
    //   handler() {
    //     this.setContent(this.value)
    //   },
    //   immediate: true,
    // },
  },
  mounted() {
    this.initializeEditor()
  },
  beforeDestroy() {
    this.editor?.destroy()
  },
  methods: {
    initializeEditor() {
      ;``
      const defaultOptions = {
        target: this.$refs.textarea,
        content_css: '/tinymce/skins/ui/oxide/content.css',
        menubar: '',
        plugins: '',
        toolbar: [],
        statusbar: false,
        // elementpath: false,
        // resize: false,
        resize: false,
        height: '100%',
        promotion: false,
        placeholder: '请选择计算函数或输入自定义计算方式',
        content_style:
          'p { margin:10px 0; color:#333; fontSize:15px; }' +
          'body { margin:10px; }' +
          '.mce-content-body:not([dir=rtl])[data-mce-placeholder]:not(.mce-visualblocks)::before { color:#96a1af;font-size:13px; }',
        // 初始化前执行
        setup: (editor) => {
          this.editor = editor
          editor.on('input', () => {
            // console.log('触发了 input')
            this.$emit('handleContentChange', editor.getContent())
          })

          editor.on('change', () => {
            // console.log('触发了 change')
            this.$emit('handleContentChange', editor.getContent())
          })

          editor.on('blur', () => {
            // console.log('触发了 blur')
          })

          editor.on('dragover', function (event) {
            // console.log('dragover')
            event.preventDefault()
          })

          editor.on('drop', function (event) {
            // console.log('drop')
            event.preventDefault()
            var htmlContent = event.dataTransfer.getData('text/html')
            editor.insertContent(htmlContent)
          })
        },
        // 初始化结束后执行
        init_instance_callback: function (editor) {},
        save_onsavecallback: () => {
          // console.log('Saved')
        },
      }
      
      tinymce
        .init({
          ...defaultOptions,
        })
        .then(([editor]) => {
          this.editor = editor
          this.setContent(this.value)
          // editor.on('change keyup undo redo', () => {
          //   this.$emit('input', editor.getContent())
          // })
        })
    },
    // 获取编辑器纯文本
    getValue() {
      return this.editor.getContent({
        format: 'text',
      })
    },
    // 设置内容
    setContent(val) {
      const oldValue = this.editor?.getContent()
      if (typeof val === 'string' && val !== oldValue) {
        this.editor?.setContent(val)
        this.$emit('handleContentChange', val)
        this.bookmark = this.editor.selection.getBookmark(2)
      }
    },
    // 插入内容
    insertContent(val) {
      this.editor.insertContent(val)
    },
    // 将光标移至末端
    endCommand() {
      this.editor.selection.select(this.editor.getBody(), true)
      this.editor.selection.collapse(false)
      this.editor.focus()
    },
    // 聚焦
    focus() {
      this.editor.focus()
    },
  },
}
</script>

<style>
.tox-tinymce-aux {
  z-index: 10000 !important;
}
.tox .tox-number-input .tox-input-wrapper {
  display: none !important;
}
.tox-statusbar__branding {
  display: none !important;
}
.tox-editor-header {
  display: none !important;
}
.tox-tinymce {
  border: 1px solid #d5e1f7 !important;
  border-radius: 4px !important;
}

/* .mce-content-body *[contentEditable='false'][data-mce-selected] {
  outline: 3px solid #b4d7ff8c;
  border-radius: 4px;
  background: #b4d7ff8c;
} */
</style>


### TinyMCE 富文本编辑器使用指南 #### 安装与引入 为了在项目中集成 TinyMCE 编辑器,需先安装对应的 npm 包。通过命令行工具执行如下指令完成安装: ```bash npm install @tinymce/tinymce-vue --save ``` 接着,在 Vue 组件内导入并注册该组件。 #### 基本配置 创建一个简单的单文件 Vue 组件来承载 TinyMCE 实例。此实例允许用户编写 HTML 文档,并支持多种格式化选项[^1]。 ```html <template> <div> <h1>我的文章</h1> <!-- 使用 v-model 双向绑定数据 --> <TinymceEditor v-model="articleContent"/> </div> </template> <script> import TinymceEditor from '@tinymce/tinymce-vue'; export default { name: 'MyArticle', components: { TinymceEditor }, data() { return { articleContent: '<p>在此撰写您的文章...</p>' }; } }; </script> ``` 上述代码展示了如何在一个 Vue 应用程序中嵌入 TinyMCE 编辑器,并初始化其默认内容为一段提示文字。 #### 插件增强功能 除了基础的功能外,还可以利用官方提供的插件进一步提升用户体验。例如,`image`, `link`, 或者自定义开发的插件都可以被加载进来以满足特定需求[^2]。 要启用这些附加特性,可以在初始化时传递相应的配置参数给编辑器实例: ```javascript data() { return { initOptions: { plugins: ['advlist autolink lists link image charmap print preview'], toolbar: 'undo redo | formatselect | bold italic backcolor | \ alignleft aligncenter alignright alignjustify | \ bullist numlist outdent indent | removeformat | help' }, articleContent: '' }; } ``` 这段 JavaScript 配置使得编辑区域具备更多实用按钮,如撤销重做、加粗斜体等常用样式设置以及链接和图片插入功能。 #### 图片处理能力 对于经常涉及图文混排场景的应用来说,良好的图像管理机制不可或缺。TinyMCE 支持直接拖拽上传图片到编辑区内;同时也可通过 API 接口实现更复杂的逻辑控制,比如裁剪压缩后再保存至服务器端[^3]。 ```html <!-- 添加对本地资源的支持 --> <input type="file" id="uploadImage"> <button onclick="insertImage()">插入图片</button> ``` 配合后台服务端脚本可以轻松构建完整的多媒体素材管理系统。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值