• 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
    
    • 1
    • 2
    • 3

    环境注意项:

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    前置条件

    • 安完依赖后,需要进入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>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100

    因业务需要

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

    init.js

    /*
     * @Author: DESKTOP-NRAJN91\14382 1438251088@qq.com
     * @Date: 2022-08-15 16:22:32
     * @LastEditors: DESKTOP-NRAJN91\14382 1438251088@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
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

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

    sideEffects.js

    /*
     * @Author: DESKTOP-NRAJN91\14382 1438251088@qq.com
     * @Date: 2022-08-15 16:48:06
     * @LastEditors: DESKTOP-NRAJN91\14382 1438251088@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' //字数统计
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

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

  • 相关阅读:
    【纯感性】【无数学公式】关于状态估计的总结和一点思考
    虚幻5框架GamePlay全图
    HTML5语义化标签 header 的详解
    Android 平台 metaRTC使用源码调试
    spfa算法_C++详解
    线程之线程池
    three.js实现管道漫游
    独一无二:探索单例模式的现代化创造之道
    使用CURAND在GPU和CPU上生成随机数的示例
    CRC8算法的解读,以及在E2E通信保护的应用
  • 原文地址:https://blog.csdn.net/weixin_44599143/article/details/126378652