简单封装富文本组件5.0-GWangEditor5

简单封装富文本组件5.0-GWangEditor5

<!--
 * @fileName: 富文本组件5.0-GWangEditor5.vue
 * 继承大部分原生组件的树形和事件
 * 支持图片、视频上传,官方文档地址:https://www.wangeditor.com/
 * (v-html预览图片请使用Gvhtml.vue组件)
!-->
<template>
  <a-spin :spinning="loading">
    <div style="border: 1px solid #ccc;">
      <Toolbar style="border-bottom: 1px solid #ccc"
               :editor="editor"
               :defaultConfig="toolbarConfig"
               :mode="state.mode"
               v-bind="$attrs" />
      <Editor :style="{ height: height, overflowY: 'hidden' }"
              v-model="state.html"
              :defaultConfig="state.editorConfig"
              :mode="state.mode"
              v-bind="$attrs"
              @onCreated="onCreated"
              @onChange="onChange"
              v-on="$listeners" />
    </div>
  </a-spin>
</template>
<script lang="ts">
import {
  Component, Vue, Inject, Prop, Watch,
} from 'vue-property-decorator';
import { Interp } from '@antv/x6';
import abpbase from 'geofly-framework-web-common/libs/abpbase';
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
import { IToolbarConfig, DomEditor } from '@wangeditor/editor';
import ChunkUploadRequest from 'geofly-framework-web-common/components/common/forms/impl/ChunkUploadRequest';

import number = Interp.number;

type InsertFnType = (url: string, poster: string) => void;

// 自定义下拉树控件.

@Component({
  name: 'GWangEditor',
  components: {
    Editor,
    Toolbar,
  },
})
export default class GWangEditor extends abpbase {
  @Prop({ default: '' })
  value: string

  /**
   * 'default' or 'simple'
   */
  @Prop({ default: 'default' })
  mode: string

  // 是否允许上传图片
  @Prop({ type: Boolean, default: true })
  enableUploadImg: boolean;

  /**
   * 最大字符串长度
   */
  @Prop({ type: Number, default: -1 })
  maxCharacterSize;

  /**
   * 内容区域高度
   */
  @Prop({ type: String, default: '500px' })
  height;

  /**
   * 配置工具栏显示哪些菜单-默认显示全部菜单
   */
  @Prop({ type: Array, default: () => [] })
  toolbarKeys;

  /**
   * 工具栏排除菜单组,写菜单组 key 的值即可
   */
  @Prop({ type: Array, default: () => [] })
  excludeKeys;

  loading = false;

  // wangeditor实例
  editor: any;


 toolbarConfig = {
    // 排除菜单组,写菜单组 key 的值即可
    excludeKeys: [],
  }

  editorContent = '';

  headers = {};

  token = `Bearer ${window.abp.auth.getToken()}`;

  state = {
    html: '',
    editorConfig: {
      placeholder: '请输入内容...',
      MENU_CONF: {
        // 图片上传配置
        uploadImage: {
          server: '/yg-system-api/file',
          // 小于该值就插入 base64 格式(而不上传),默认为 0
          base64LimitSize: 1024 * 1024 * 2, // 2M
          // 单个文件的最大体积限制,默认为 2M
          maxFileSize: 1024 * 1024 * 2, // 2M
          // 选择文件时的类型限制,默认为 ['image/*'] 。如不想限制,则设置为 []
          allowedFileTypes: ['image/*'],
          // 上传之前触发
          onBeforeUpload: (file: File) => {
            console.log('file:', file);
            return file;
          },
        },
        // 上传视频配置
        uploadVideo: {
          server: '/yg-system-api/file',
          // 单个文件的最大体积限制,默认为 10M
          maxFileSize: 1024 * 1024 * 500, // 500M
          // 自定义增加 http  header
          headers: {
            'content-type': 'multipart/form-data',
            Authorization: this.token,
          },
          // 超时时间,默认为 30 秒
          timeout: 60 * 1000 * 60, // 60 分钟
          // 上传之前触发
          onBeforeUpload: (file: File) => {
            console.log('file:', file);
            return file;
          },
          // 自定义文件上传
          customUpload: (file: File, insertFn: InsertFnType) => {
            // console.log('customUpload:', file);
            this.customRequest(file, insertFn);
          },
        },
      },
      toolbarKeys: [], // 默认显示全部菜单
      excludeKeys: [], // 排除菜单组,写菜单组 key 的值即可
    },
    mode: 'simple', // 'default' or 'simple'
  }

  getEditor() {
    return this.editor;
  }

  async customRequest(options, insertFn: InsertFnType) {
    const config = {
      headers: { 'content-type': 'multipart/form-data', ...this.headers },
    };
    this.loading = true;
    const chunkUploadRequest = new ChunkUploadRequest();
    chunkUploadRequest.uploadUrl = '/yg-system-api/file/chunk';
    chunkUploadRequest.uploadConfig = config;
    chunkUploadRequest.message = this.$message;
    // chunkUploadRequest.onProgress = 100;
    chunkUploadRequest.fileType = 0;
    chunkUploadRequest.uploadChunks(options).then((res: any) => {
      this.loading = false;
      if (res.code == 0) {
        const fileUrl = `/yg-system-api/file/file/${res.result}?preview=1`; // 视频 src ,必须
        const poster = ''; // 视频封面图片 url ,可选
        options.status = 'done';
        this.$message.success('上传成功!');
        // 最后插入视频
        insertFn(fileUrl, poster);
      } else {
        this.$message.error('上传失败!');
      }
    }, (err) => {
      this.loading = false;
      this.$message.error('上传失败!');
      console.log('err:', err);
    });
  }

  onCreated(editor) {
    this.editor = Object.seal(editor);
  }

  onChange(editor) {
    let html = null;
    const isEmpty = editor.isEmpty();
    if (!isEmpty) {
      html = editor.getHtml();
    }
    this.$emit('change', html);
  }

  @Watch('value')
  valueChanged(e) {
    this.editorContent = this.getFinalString(e);
    this.state.html = this.editorContent;
  }

  /**
   * 获取最终的字符串
   */
  getFinalString(e): string {
    return e && this.maxCharacterSize > 0 ? e.substring(0, this.maxCharacterSize) : e;
  }

  mounted() {
    this.state.editorConfig.toolbarKeys = this.toolbarKeys;
    this.state.editorConfig.excludeKeys = this.excludeKeys;
    this.state.mode = this.mode;
  }

  beforeDestroy() {
    const { editor } = this;
    if (editor == null) return;
    editor.destroy(); // 组件销毁时,及时销毁编辑器
  }
}
</script>
<style src="@wangeditor/editor/dist/css/style.css"></style>
<style></style>

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

星月前端

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值