ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

vue使用 Tinymce富文本编辑器

2022-01-21 09:31:59  阅读:148  来源: 互联网

标签:文本编辑 vue default Tinymce image tinymce upload data mce


1,目录结构
在这里插入图片描述
2.index.vue

<template>
  <div :class="{fullscreen:fullscreen}" class="tinymce-container editor-container">
    <textarea :id="tinymceId" class="tinymce-textarea" />
    <div class="editor-custom-btn-container">
      <editorImage color="#1890ff" class="editor-upload-btn" @successCBK="imageSuccessCBK" />
      <editorVideo color="#1890ff" class="editor-upload-btn" @successCBK="VideoSuccessCBK" />
    </div>
  </div>
</template>

<script>
import editorImage from './components/EditorImage'
import editorVideo from './components/EditorVideo'
import plugins from './plugins'
import toolbar from './toolbar'

export default {
  name: 'Tinymce',
  components: { editorImage,editorVideo},
  props: {
    id: {
      type: String,
      default: function() {
        return 'vue-tinymce-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '')
      }
    },
    value: {
      type: String,
      default: ''
    },
    toolbar: {
      type: Array,
      required: false,
      default() {
        return []
      }
    },
    menubar: {
      type: String,
      default: 'file edit insert view format table'
    },
    height: {
      type: Number,
      required: false,
      default: 360
    }
  },
  data() {
    return {
      hasChange: false,
      hasInit: false,
      tinymceId: this.id,
      fullscreen: false,
      languageTypeList: {
        'en': 'en',
        'zh': 'zh_CN'
      }
    }
  },
  computed: {
    language() {
      return this.languageTypeList[this.$store.getters.language]
    }
  },
  watch: {
    value(val) {
      if (!this.hasChange && this.hasInit) {
        this.$nextTick(() =>
          window.tinymce.get(this.tinymceId).setContent(val || ''))
      }
    },
    language() {
      this.destroyTinymce()
      this.$nextTick(() => this.initTinymce())
    }
  },
  mounted() {
    this.initTinymce()
  },
  activated() {
    this.initTinymce()
  },
  deactivated() {
    this.destroyTinymce()
  },
  destroyed() {
    this.destroyTinymce()
  },
  methods: {
    initTinymce() {
      const _this = this
      window.tinymce.init({
        language: this.language,
        selector: `#${this.tinymceId}`,
        height: this.height,
        body_class: 'panel-body ',
        object_resizing: false,
        toolbar: this.toolbar.length > 0 ? this.toolbar : toolbar,
        menubar: this.menubar,
        plugins: plugins,
        fontsize_formats: "8px 9px 10px 11px 12px 13px 14px 15px 16px 17px 18px 19px 20px 21px 22px 23px 24px 25px 26px 27px 28px 29px 30px 31px 32px 33px 34px 35px 36px 37px 38px",
        end_container_on_empty_block: true,
        powerpaste_word_import: 'clean',
        code_dialog_height: 400,
        code_dialog_width: 1000,
        advlist_bullet_styles: 'square',
        advlist_number_styles: 'default',
        imagetools_cors_hosts: ['www.tinymce.com', 'codepen.io'],
        default_link_target: '_blank',
        link_title: false,
        nonbreaking_force_tab: true, // inserting nonbreaking space &nbsp; need Nonbreaking Space Plugin
        init_instance_callback: editor => {
          if (_this.value) {
            editor.setContent(_this.value)
          }
          _this.hasInit = true
          editor.on('NodeChange Change KeyUp SetContent', () => {
            this.hasChange = true
            this.$emit('input', editor.getContent())
          })
        },
        setup(editor) {
          editor.on('FullscreenStateChanged', (e) => {
            _this.fullscreen = e.state
          })
        }
        // 整合七牛上传
        // images_dataimg_filter(img) {
        //   setTimeout(() => {
        //     const $image = $(img);
        //     $image.removeAttr('width');
        //     $image.removeAttr('height');
        //     if ($image[0].height && $image[0].width) {
        //       $image.attr('data-wscntype', 'image');
        //       $image.attr('data-wscnh', $image[0].height);
        //       $image.attr('data-wscnw', $image[0].width);
        //       $image.addClass('wscnph');
        //     }
        //   }, 0);
        //   return img
        // },
        // images_upload_handler(blobInfo, success, failure, progress) {
        //   progress(0);
        //   const token = _this.$store.getters.token;
        //   getToken(token).then(response => {
        //     const url = response.data.qiniu_url;
        //     const formData = new FormData();
        //     formData.append('token', response.data.qiniu_token);
        //     formData.append('key', response.data.qiniu_key);
        //     formData.append('file', blobInfo.blob(), url);
        //     upload(formData).then(() => {
        //       success(url);
        //       progress(100);
        //     })
        //   }).catch(err => {
        //     failure('出现未知问题,刷新页面,或者联系程序员')
        //     console.log(err);
        //   });
        // },
      })
    },
    destroyTinymce() {
      const tinymce = window.tinymce.get(this.tinymceId)
      if (this.fullscreen) {
        tinymce.execCommand('mceFullScreen')
      }
      if (tinymce) {
        tinymce.destroy()
      }
    },
    setContent(value) {
      window.tinymce.get(this.tinymceId).setContent(value)
    },
    getContent() {
      window.tinymce.get(this.tinymceId).getContent()
    },
    imageSuccessCBK(arr) {
      const _this = this
      arr.forEach(v => {
        window.tinymce.get(_this.tinymceId).insertContent(`<img class="wscnph" style="width:100%;display:block" src="${v.url}" >`)
      })
    },
    VideoSuccessCBK(arr){
        const _this = this
      arr.forEach(v => {
        window.tinymce.get(_this.tinymceId).insertContent(`<span class="mce-preview-object mce-object-video" contenteditable="false" data-mce-object="video" data-mce-p-controls="controls" data-mce-html="<source src='${v.url}' />"><video src="${v.url}" controls="controls" width="100%" height="auto" frameborder="0"></video><span class="mce-shim"></span></span>`)
      })
    }
  }
}
</script>

<style scoped>
.tinymce-container {
  position: relative;
  line-height: normal;
}
.tinymce-container>>>.mce-fullscreen {
  z-index: 10000;
}
.wscnph{
  width: 100%;
}
.tinymce-textarea {
  visibility: hidden;
  z-index: -1;
}
.editor-custom-btn-container {
  position: absolute;
  right: 4px;
  top: 4px;
  /*z-index: 2005;*/
}
.fullscreen .editor-custom-btn-container {
  z-index: 10000;
  position: fixed;
}
.editor-upload-btn {
  display: inline-block;
}
.mce-container{
  white-space: normal !important;
}
.mce-container, .mce-container *, .mce-widget, .mce-widget *, .mce-reset{
  white-space: normal !important;
}
</style>
<style>
.mce-container, .mce-container *, .mce-widget, .mce-widget *, .mce-reset{
  white-space: normal !important;
}
</style>

3,上传视频组件

<template>
  <div class="upload-container">
    <el-button :style="{background:color,borderColor:color}" icon="el-icon-upload" size="mini" type="primary"
      @click=" dialogVisible=true">上传视频</el-button>
    <el-dialog :append-to-body="true" :visible.sync="dialogVisible">
      <div class="dialog-bodyer">
        <upload @getImg="getImg"   accept=".mp4, .ogg" @delImg="delImg" :isVideo="true" :file-list="uploadFileList"
          uploadNotice="请上传视频,上传成功之前请不要关闭此窗口"></upload>
      </div>
      <div class="dialog-footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleSubmit">确认</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>

import upload from "@/components/upload/upload";
  export default {
    name: "EditorSlideUploadVideo",
    props: {
      color: {
        type: String,
        default: "#1890ff",
      },
    },
    components: {
      upload,
    },
    data() {
      return {
        uploadUrl:"/oss/service/upload/imgNoParams",
        dialogVisible: false,
        listObj: {},
        fileList: [],
        uploadFileList: [],
      
        params: {},
      };
    },
    methods: {
      // data为图片地址
      getImg(data) {
        console.log(data, "datadatadatadatadatadatadata")
        this.$message({
          type: "success",
          message: `上传成功`,
        });
        // this.handleSubmit()
      },
      delImg(index) {
        // this.models.picture = "";

      },
      checkAllSuccess() {
        return Object.keys(this.listObj).every(
          (item) => this.listObj[item].hasSuccess
        );
      },
      handleSubmit() {
        if (!this.checkAllSuccess()) {
          this.$message(
            "Please wait for all images to be uploaded successfully. If there is a network problem, please refresh the page and upload again!"
          );
          return;
        }
        this.$emit("successCBK", this.uploadFileList);
        this.uploadFileList = [];
        this.dialogVisible = false;
      },
    },
  };

</script>

<style lang="scss" scoped>
  .dialog-footer {
    padding: 20px;
  }

  .dialog-bodyer {
    padding: 20px;
  }

  .editor-slide-upload {
    margin-bottom: 20px;

    /deep/ .el-upload--picture-card {
      width: 100%;
    }
  }

</style>

4.plugins

// Any plugins you want to use has to be imported
// Detail plugins list see https://www.tinymce.com/docs/plugins/
// Custom builds see https://www.tinymce.com/download/custom-builds/

const plugins = ['advlist anchor autolink autosave code codesample colorpicker colorpicker contextmenu directionality emoticons fullscreen hr image imagetools insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textcolor textpattern visualblocks visualchars wordcount']

export default plugins

5,toolbar

// Here is a list of the toolbar
// Detail list see https://www.tinymce.com/docs/advanced/editor-control-identifiers/#toolbarcontrols

const toolbar = ['fontsizeselect fontselect searchreplace bold italic underline strikethrough alignleft aligncenter alignright outdent indent  blockquote undo redo removeformat subscript superscript code codesample', 'hr bullist numlist link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor fullscreen']

export default toolbar

标签:文本编辑,vue,default,Tinymce,image,tinymce,upload,data,mce
来源: https://blog.csdn.net/m0_49609366/article/details/122614451

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有