vue3 script setup 使用tinymce富文本编辑器-f

简介

本文就是对于tinymce在vue3中的组件化封装进行的总结,便于大家直接上手使用

作者环境配置

大环境

node 16.9.0

package.json配置

“dependencies”: {
“@element-plus/icons-vue”: “^2.0.6”,
“@tinymce/tinymce-vue”: “^5.0.0”,
“Base64”: “^1.1.0”,
“axios”: “^0.27.2”,
“element-plus”: “^2.2.12”,
“normalize.css”: “8.0.1”,
“path-browserify”: “^1.0.1”,
“pinia”: “^2.0.17”,
“pinia-plugin-persistedstate”: “^2.1.0”,
“qs”: “^6.11.0”,
“tinymce”: “5.10.0”,
“vue”: “^3.2.37”,
“vue-router”: “^4.1.3”,
“vue-schart”: “^2.0.0”
},
“devDependencies”: {
“@babel/core”: “^7.18.10”,
“@babel/eslint-parser”: “^7.18.9”,
“@vitejs/plugin-vue”: “^3.0.1”,
“@vue/compiler-sfc”: “^3.2.37”,
“@vue/eslint-config-prettier”: “^7.0.0”,
“autoprefixer”: “^10.4.8”,
“eslint”: “^8.21.0”,
“eslint-plugin-vue”: “^9.3.0”,
“postcss”: “^8.4.14”,
“prettier”: “^2.7.1”,
“sass”: “^1.54.1”,
“tailwindcss”: “^3.1.7”,
“vite”: “3.0.4”
},

本文相关环境或依赖版本

node 16.9.0
@tinymce/tinymce-vue 5.0.0
tinymce 5.10.0

环境注意项:

tinymce 4版本以下是vue2.0使用,6版本作者开发时不好用,原因不明

组件目录结构

|----------
|–index 主组件入口
|–sideEffects 副作用文件,所有副作用通过此文件进行引入
|–init 初始化文件,默认初始化配置在此文件处理

组件暴露emit或prop

  v-modex:富文本输入内容
  props:
    disabled:禁用状态
    plugins:插件 默认配置在init:    'print image preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template code codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount textpattern autosave ', //插件配置
    toolbar:工具栏 默认配置在init: 'fullscreen undo redo restoredraft | forecolor backcolor bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify outdent indent | styleselect  fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | table image media charmap emoticons hr pagebreak insertdatetime print preview | code selectall | indent2em lineheight formatpainter axupimgs'
    height:高度,默认配置在init:500

前置条件

  • 安完依赖后,需要进入tinymce
    依赖(node_modules\tinymce),将依赖内的文件复制到public文件夹内,作者是将相关文件放入public\lib\tinymce 文件夹内,此处根据实际变更init.js代码内容
  • 中文需要去官网下载语言包,下载后和public文件夹内的tinymce放一起即可,同样根据实际变更init.js代码内容

组件代码

index.vue

<!--
 * @Author: 计算机名不透露\用户名不透露 邮箱不透露
 * @Date: 2022-08-15 13:07:35
 * @LastEditors: 计算机名不透露\用户名不透露 邮箱不透露
 * @LastEditTime: 2022-08-17 08:49:27
 * @FilePath: \项目名不透露\src\components\Editor\index.vue
 * @Description: 富文本编辑器主组件 =>tinymce组件封装
  |----------
    |--index 主组件入口  
    |--sideEffects 副作用文件,所有副作用通过此文件进行引入
    |--init 初始化文件,默认初始化配置在此文件处理
  
  图片上传均通过uploadAPI接口进行上传

  v-modex:富文本输入内容
  props:
    disabled:禁用状态
    plugins:插件 默认配置在init:    'print image preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template code codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount textpattern autosave ', //插件配置
    toolbar:工具栏 默认配置在init: 'fullscreen undo redo restoredraft | forecolor backcolor bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify outdent indent | styleselect  fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | table image media charmap emoticons hr pagebreak insertdatetime print preview | code selectall | indent2em lineheight formatpainter axupimgs'
    height:高度,默认配置在init:500
    
  	store:useBaseDataStore 基础数据:获取minioServerURL服务地址
-->
<template>
  <TEditor v-model="content" :init="init" tag-name="div" :disabled="disabled" />
</template>

<script setup>
  //引入tinymce编辑器
  import TEditor from '@tinymce/tinymce-vue'

  //引入方式引入node_modules里的tinymce相关文件文件
  import tinymce from 'tinymce/tinymce' //tinymce默认hidden,不引入则不显示编辑器
  import { computed } from 'vue-demi'
  import './sideEffects'
  import defaultInit from './init'
  import { uploadAPI } from '@/api/base'
  import { useBaseDataStore } from '@/store/baseData'
  const baseDataStore = useBaseDataStore()
  let minioServerURL = ''
  baseDataStore.getMinioServer().then((res) => {
    minioServerURL = res
  })
  const props = defineProps({
    modelValue: {
      type: String,
      default: ''
    },
    disabled: Boolean,
    plugins: [String, Array],
    toolbar: [String, Array],
    height: Number
  })
  const emit = defineEmits(['update:modelValue'])
  const init = computed(() => {
    const plugins = props.plugins || defaultInit.plugins
    const toolbar = props.plugins || defaultInit.toolbar
    const height = props.plugins || defaultInit.height
    return {
      ...defaultInit,
      plugins,
      toolbar,
      height,
      images_upload_handler: (blobInfo, success, failure) => {
        uploadGetUrl(blobInfo.blob(), success, failure)
      },
      file_picker_callback: (callback, value, meta) => {
        console.log('file_picker_callback', callback, value, meta)
      }
    }
  })
  tinymce.init
  const content = computed({
    get() {
      return props.modelValue
    },
    set(val) {
      emit('update:modelValue', val)
    }
  })
 /**
   * @description: 上传图片事件,通过formData携带文件上传给业务接口
   * @param {*} blob 图片blob对象
   * @param {*} success 成功事件回调,接收url
   * @param {*} failure 失败事件回调
   * @return {*}
   */
  function uploadGetUrl(blob, success, failure) {
    const formData = new FormData() //
    formData.append('file', blob)
    uploadAPI(formData)
      .then((res) => {
        success(minioServerURL + res.content)
      })
      .catch((e) => {
        failure(e)
      })
  }
</script>

因业务需要

  • 有store 为获取服务地址的相关处理,因根据各公司实际设计不同而不同,故不暴露该文件做参考
  • 图片上传需要经过images_upload_handler将图片上传给uploadAPI接口,此处可以根据各位业务配置进行修改uploadGetUrl接口

init.js

/*
 * @Author: DESKTOP-NRAJN91\14382 00000000@qq.com
 * @Date: 2022-08-15 16:22:32
 * @LastEditors: DESKTOP-NRAJN91\14382 00000000@qq.com
 * @LastEditTime: 2022-08-15 18:06:57
 * @FilePath: \LNZhiAn\src\components\Editor\init.js
 * @Description: tinymce 富文本默认配置
 */
const defaultInit = {
  language_url: '/lib/tinymce/langs/zh_CN.js', //引入语言包文件
  language: 'zh_CN', //语言类型

  skin_url: '/lib/tinymce/skins/ui/oxide', //皮肤:浅色
  // skin_url: '/lib/tinymce/skins/ui/oxide-dark',//皮肤:暗色

  plugins:
    'print image preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template code codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount textpattern autosave ', //插件配置
  toolbar:
    'fullscreen undo redo restoredraft | forecolor backcolor bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify outdent indent | \
  styleselect  fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | \
  table image media charmap emoticons hr pagebreak insertdatetime print preview | code selectall | indent2em lineheight formatpainter axupimgs', //工具栏配置,设为false则隐藏
  toolbar_mode: 'sliding',
  // menubar: 'file edit insert view format table tools', //菜单栏配置,设为false则隐藏,不配置则默认显示全部菜单,也可自定义配置--查看 http://tinymce.ax-z.cn/configure/editor-appearance.php --搜索“自定义菜单”
  menu: {
    // file: { title: '文件', items: 'newdocument' },
    edit: { title: '编辑', items: 'undo redo | cut copy paste pastetext | selectall' },
    insert: { title: '插入', items: 'link image  |  hr' },
    view: { title: '查看', items: 'visualaid' }
    // format: {
    //   title: '格式',
    //   items:
    //     'bold italic underline strikethrough superscript subscript | formats | removeformat',
    // },
    // table: { title: '表格', items: 'inserttable tableprops deletetable | cell row column' },
    // tools: { title: '工具', items: 'spellchecker code' },
  },
  fontsize_formats: '12px 14px 16px 18px 20px 22px 24px 28px 32px 36px 48px 56px 72px', //字体大小
  font_formats:
    '微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;',

  height: 500, //注:引入autoresize插件时,此属性失效
  placeholder: '在这里输入文字',
  branding: false, //tiny技术支持信息是否显示
  resize: false, //编辑器宽高是否可变,false-否,true-高可变,'both'-宽高均可,注意引号
  statusbar: false, //最下方的元素路径和字数统计那一栏是否显示
  elementpath: false, //元素路径是否显示

  content_style: 'img {max-width:100%;}' //直接自定义可编辑区域的css样式
  // content_css: '/tinycontent.css',  //以css文件方式自定义可编辑区域的css样式,css文件需自己创建并引入
}
export default defaultInit

tinymce 富文本默认配置文件,因作者认为,此处无需暴露给业务,且功能单一,故单立文件便于维护
可参考TinyMCE中文文档中文手册

sideEffects.js

/*
 * @Author: DESKTOP-NRAJN91\14382 00000000@qq.com
 * @Date: 2022-08-15 16:48:06
 * @LastEditors: DESKTOP-NRAJN91\14382 00000000@qq.com
 * @LastEditTime: 2022-08-15 17:09:14
 * @FilePath: \LNZhiAn\src\components\TEditor\sideEffects.js
 * @Description: tinymce 副作用引入
 */
import 'tinymce/themes/silver' //编辑器主题,不引入则报错
import 'tinymce/icons/default' //引入编辑器图标icon,不引入则不显示对应图标

// 引入编辑器插件
import 'tinymce/plugins/advlist' //高级列表
import 'tinymce/plugins/anchor' //锚点
import 'tinymce/plugins/autolink' //自动链接
import 'tinymce/plugins/autoresize' //编辑器高度自适应,注:plugins里引入此插件时,Init里设置的height将失效
import 'tinymce/plugins/autosave' //自动存稿
import 'tinymce/plugins/charmap' //特殊字符
import 'tinymce/plugins/code' //编辑源码
import 'tinymce/plugins/codesample' //代码示例
import 'tinymce/plugins/directionality' //文字方向
import 'tinymce/plugins/emoticons' //表情
import 'tinymce/plugins/fullpage' //文档属性
import 'tinymce/plugins/fullscreen' //全屏
import 'tinymce/plugins/help' //帮助
import 'tinymce/plugins/hr' //水平分割线
import 'tinymce/plugins/image' //插入编辑图片
import 'tinymce/plugins/importcss' //引入css
import 'tinymce/plugins/insertdatetime' //插入日期时间
import 'tinymce/plugins/link' //超链接
import 'tinymce/plugins/lists' //列表插件
import 'tinymce/plugins/media' //插入编辑媒体
import 'tinymce/plugins/nonbreaking' //插入不间断空格
import 'tinymce/plugins/pagebreak' //插入分页符
import 'tinymce/plugins/paste' //粘贴插件
import 'tinymce/plugins/preview' //预览
import 'tinymce/plugins/print' //打印
import 'tinymce/plugins/quickbars' //快速工具栏
import 'tinymce/plugins/save' //保存
import 'tinymce/plugins/searchreplace' //查找替换
import 'tinymce/plugins/spellchecker' //拼写检查,暂未加入汉化,不建议使用
import 'tinymce/plugins/tabfocus' //切入切出,按tab键切出编辑器,切入页面其他输入框中
import 'tinymce/plugins/table' //表格
import 'tinymce/plugins/template' //内容模板
import 'tinymce/plugins/textcolor' //文字颜色
import 'tinymce/plugins/textpattern' //快速排版
import 'tinymce/plugins/toc' //目录生成器
import 'tinymce/plugins/visualblocks' //显示元素范围
import 'tinymce/plugins/visualchars' //显示不可见字符
import 'tinymce/plugins/wordcount' //字数统计

副作用文件,太长了且与业务弱关联,单立文件便于维护

Vue2 中使用 TinyMCE 富文本编辑器确实支持粘贴图片功能。TinyMCE 提供了丰富的文本处理能力,包括图片上传、粘贴等。要在 Vue 组件中集成 TinyMCE 并允许用户粘贴图片,你可以按照以下步骤操作: 1. 安装依赖:首先需要安装 tiny-mce-vue 包,可以通过 npm 或者 yarn 进行安装: ```bash npm install @tinymce/tinymce-vue ``` 2. 配置 TinyMCE:在 Vue 文件中初始化 TinyMCE,设置插件配置,包括图片相关选项: ```html <template> <div ref="tinymce"> <!-- 你的富文本编辑区域 --> </div> </template> <script> import { createTinymce } from '@tinymce/tinymce-vue' export default { setup() { const editorOptions = { plugins: 'image', // 必须包含 image 插件 images_upload_url: '/api/upload-image', // 图片上传的服务器端地址 image_insertion_allow_types: ['image/png', 'image/jpeg'], // 允许的图片类型 paste_data_images: true, // 允许粘贴数据图片 } const editor = createTinymce(editorOptions) return { editor } }, } </script> ``` 3. 注册组件事件监听:为了让用户能在组件外部触发粘贴事件,你需要监听浏览器的 `paste` 事件,并将粘贴的内容传递给 TinyMCE 的 `insertContent` 方法,以便插入图片。 4. 监听粘贴并处理图片: ```javascript mounted() { document.addEventListener('paste', (event) => { if (!event.clipboardData || !event.clipboardData.items) { return; } event.preventDefault(); event.stopPropagation(); const items = event.clipboardData.items; for (let i = 0; i < items.length; i++) { const item = items[i]; if (item.type === 'text/html') { // 解析 HTML 获取图片数据 let imageData = item.getAsHTML(); this.editor.insertContent(imageData); break; } } }); }, ``` 现在,当用户在 TinyMCE 编辑区域粘贴图片时,它会被正确地插入到编辑器中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_默_

别打赏了,点点赞,点点关注就行

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值