美文网首页
Tinymce6+tinymce-vue5+vue3+ts

Tinymce6+tinymce-vue5+vue3+ts

作者: 三没产品 | 来源:发表于2023-08-30 16:34 被阅读0次

    相关包

     "tinymce": "^6.3.1"
     "@tinymce/tinymce-vue": "^5.0.0"
     "element-plus": "^2.2.28"
    

    复制icons、skins

    安装完成后,在 public文件夹 下创建 tinymce文件夹,然后在node_modules下找到 tinymce,注意不是 @tinymce,复制 icons、skins 文件夹到 public/tinymce6

    下载中文语言包

    下载地址:https://www.tiny.cloud/get-tiny/language-packages/,下载 zh_CN,下载后,把解压后的 langs文件夹 放到 public/tinymce6

    组件代码

    <template>
      <div>
        <Editor v-model="myValue" :init="init" :disabled="disabled"/>
        <input type="file" hidden :id="id" :accept="imgAccept"/>
        <div class="oe-editor-del-btn" v-if="showDel">
          <img src="../assets/img/editor_del.png" alt="">
        </div>
      </div>
    </template>
    
    <script lang="ts" setup>
    import {computed, onMounted, reactive, ref} from "vue"
    import tinymce from 'tinymce/tinymce'
    import Editor from '@tinymce/tinymce-vue'
    import 'tinymce/themes/silver/theme'
    import 'tinymce/icons/default'
    import 'tinymce/models/dom'
    import 'tinymce/plugins/advlist'
    import 'tinymce/plugins/autolink'
    import 'tinymce/plugins/lists'
    import 'tinymce/plugins/link'
    import 'tinymce/plugins/image'
    import 'tinymce/plugins/charmap'
    import 'tinymce/plugins/preview'
    import 'tinymce/plugins/anchor'
    import 'tinymce/plugins/searchreplace'
    import 'tinymce/plugins/visualblocks'
    import 'tinymce/plugins/code'
    import 'tinymce/plugins/fullscreen'
    import 'tinymce/plugins/insertdatetime'
    import 'tinymce/plugins/media'
    import 'tinymce/plugins/table'
    import 'tinymce/plugins/help'
    import 'tinymce/plugins/wordcount'
    import {editUploadFile} from "../api/common";
    import {ElMessage} from "element-plus";
    
    interface Props {
      id?: string,
      modelValue?: string,
      height?: string | number,
      width?: string | number,
      disabled?: boolean,
      showDel?: boolean
    }
    
    const props = withDefaults(defineProps<Props>(), {
      modelValue: '',
      id: 'vue-tinymce-' + +new Date() + ((Math.random() * 1000).toFixed(0) + ''),
      height: 200,
      width: 'auto',
      disabled: false,
      showDel: false
    })
    
    const emits = defineEmits<{
      (e: 'update:modelValue', value: string): void
    }>()
    
    const myValue = computed({
      get() {
        return props.modelValue
      },
      set(value) {
        emits('update:modelValue', value);
      },
    });
    
    const oldValue = ref<string>()
    const imgAccept = ref<string>('.bmp,.jpg,.png,.tif,.gif,.pcx,.tga,.exif,.fpx,.svg,.psd,.cdr,.pcd,.dxf,.ufo,.eps,.ai,.raw,.WMF,.webp,.avif,.apng')
    
    const example_image_upload_handler = (blobInfo: any, progress: any) => new Promise((resolve, reject) => {
      let fd = new FormData();
      fd.append('file', blobInfo.blob(), blobInfo.filename());
      editUploadFile(fd).then((res: any) => {
        if (res.code === 1) {
          resolve(res.data)
        } else {
          resolve('')
        }
      })
    })
    
    const setup = (editor: any) => {
      editor.ui.registry.addButton('imageUpload', {
        tooltip: '图片',
        icon: 'image',
        onAction: (api: any) => {
          //点击按钮后执行
          oldValue.value = props.modelValue;
          const input: any = document.getElementById(props.id);
          input.click();
          input.onchange = function () {
            let file = input.files[0];
            let fd = new FormData();
            fd.append('file', file);
            if (!imgAccept.value.includes(file.name.substring(file.name.indexOf('.')))) {
              ElMessage.warning('请选择图片上传')
              input.value = '';
              return
            }
            editUploadFile(fd).then((res: any) => {
              if (res.code === 1) {
                editor.insertContent("<img src='" + res.data + "' alt=''/>");
                input.value = '';
              } else {
                editor.setContent(oldValue.value as string);
              }
            })
          }
        }
      });
    }
    
    const init = reactive({
      selector: `#${props.id}`,
      content_style: "p {margin: 0; border:0; padding: 0;}",
      content_css: '/tinymce6/skins/content/default/content.css',
      language_url: '/tinymce6/langs/zh-Hans.js', // https://www.tiny.cloud/get-tiny/language-packages/
      language: 'zh-Hans',
      skin_url: '/tinymce6/skins/ui/oxide',
      height: props.height,
      promotion: false, //隐藏右上角upgrade按钮
      branding: false, //隐藏右下角由TINY驱动
      menubar: false, // 是否隐藏顶部菜单
      contextmenu_never_use_native: true, //防止浏览器上下文菜单出现在编辑器中
      elementpath: false, //隐藏底栏的元素路径(隐藏右下角元素显示)
      object_resizing: true,//是否允许调整图像大小.
      toolbar: 'undo redo | blocks | fontfamily forecolor |' +
        'bold italic backcolor | alignleft aligncenter ' +
        'alignright alignjustify | bullist numlist outdent indent | ' +
        'removeformat | table | imageUpload | help',
      plugins: ['advlist', 'autolink', 'lists', 'link', 'image', 'charmap', 'preview',
        'anchor', 'searchreplace', 'visualblocks', 'code', 'fullscreen',
        'insertdatetime', 'media', 'table', 'help', 'wordcount'],
      // paste_data_images: false, //此选项指定是否应从粘贴的内容中删除图像
      paste_webkit_styles: 'all', //此选项允许您指定粘贴到 WebKit 中时要保留的样式 'none' 或者 'all'
      // paste_merge_formats: true, //此选项在粘贴内容时启用合并格式功能。这将合并相同的文本格式元素,以减少生成的 HTML 元素的数量
      advlist_bullet_styles: 'default,circle,disc,square',
      // advlist_number_styles: 'default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman',
      link_default_target: '_blank',
      link_title: false, //此选项允许您禁用对话框中的链接输入字段
      nonbreaking_force_tab: true, //tab键插入三个&nbsp;
      images_upload_handler: example_image_upload_handler,
      setup: setup
    })
    
    onMounted(() => {
      tinymce.init({})
    })
    
    </script>
    
    <style scoped>
    
    </style>
    <style>
    .tox-tinymce-aux {
      z-index: 3035 !important;
    }
    
    .tox .tox-toolbar__group {
      padding: 0 3px 0 5px !important;
    }
    </style>
    

    vue2+tinymce5+tinymce-vue3 - 简书 (jianshu.com)

    相关文章

      网友评论

          本文标题:Tinymce6+tinymce-vue5+vue3+ts

          本文链接:https://www.haomeiwen.com/subject/ipkamdtx.html