ICode9

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

Vue中使用tinymce富文本编辑器

2021-07-15 17:05:13  阅读:352  来源: 互联网

标签:文本编辑 Vue false media tinymce activeEditor file store


效果
在这里插入图片描述
“@tinymce/tinymce-vue”: “^3.2.3”,
“tinymce”: “^5.5.0”,

一、安装

npm install tinymce -S

npm install @tinymce/tinymce-vue -S

二、下载资源

将下面两个资源下载下载,放到资源文件里面。下载tinymce文件的目的是解决加载缓慢,白屏问题

中文包下载地址

在这里插入图片描述
tinymce资源文件下载地址
根据相应的版本下载
在这里插入图片描述

三、创建组件开始使用

  • 1、解决加载缓慢,白屏问题
    把上面下载的tinymce文件放在资源文件后,需要在index.html中引入使用tinymce.min.js
<script src="/static/tinymce/tinymce.min.js"></script>
  • 2、组件完整代码

    html

    <editor :init="editorInit" v-model="contentHtml" :disabled="disabled" :autoresize="autoresize" />
    <!-- 上传视频没有一个正在上传的遮罩,那么就需要自己写一个遮罩,就如下面的div,我这里只做展示,样式没有写 -->
    <div v-if="loading" />

js

import Editor from "@tinymce/tinymce-vue";
  // import 'tinymce/plugins/media'
  // 后端上传接口,按照需求而定
  import {
    upload,
  } from "../api/api";
  import request from "../api/request";
  import store from '../store/index'
  import util from '../Util'
var util={}
  export default {
    name: "TinyMceEditor",
    model: {
      prop: "content",
      event: "change",
    },
    props: {
      // 绑定的文本内容
      content: {
        type: String,
        default: "",
      },
      // 是否禁止输入
      disabled: {
        type: Boolean,
        default: false,
      },
      // true则自适应高
      autoresize: {
        type: Boolean,
        default: false,
      },
    },
    components: {
      Editor,
    },

    data: () => ({
      // 编辑器配置
      editorInit: {
        language_url: "/static/zh_CN.js", //汉化文件的路径, 这里的原始路径是'/public/zh_CN.js'
        language: "zh_CN",

        height: 500,
        menubar: true,
        plugins: [
          "advlist autolink lists link image charmap print preview anchor",
          "searchreplace visualblocks code fullscreen",
          "insertdatetime media table paste code help wordcount",
          "image media",
        ],
        toolbar: "undo redo | formatselect | bold italic underline strikethrough superscript subscript codeformat forecolor backcolor removeformat| \
           alignleft aligncenter alignright alignjustify  outdent indent lineheight| \
           bullist numlist  | link image media template codesample inserttable table    | \
           charmap emoticons hr insertdatetime | cut copy newdocument print | \
           spellchecker |searchreplace preview fullscreen | help | ",
        file_picker_types: ' media',
        content_css: 'css/content.css',
        // 自定义视频上传
        file_picker_callback: function (cb, value, meta) {
          if (meta.filetype == 'media') {
            //创建一个隐藏的type=file的文件选择input
            let input = document.createElement('input');
            input.setAttribute('type', 'file');
            input.onchange = function (e) {
              let file = e.target.files[0]; //只选取第一个文件。如果要选取全部,后面注意做修改
              store.commit('setParam', {
                loading: true
              })
              const formData = new FormData();
              formData.append("file", file);
              request(upload, formData)
                .then((res) => {
                  store.commit('setParam', {
                    loading: false
                  })
                  if (res.code === 0) {
                    let fileUrl = res.data.url;
                    cb(fileUrl, {
                      title: file.name
                    });
                    return;
                  }
                  util.message("err", "上传失败")
                })
                .catch(() => {
                  store.commit('setParam', {
                    loading: false
                  })
                  util.message("err", "上传失败")
                });
            }
            //触发点击
            input.click();

          }
        },
        //自定义逻辑替换 Tinymce 的默认媒体嵌入逻辑 --处理添加视频显示问题
        media_url_resolver: function (data, resolve) {
          try {
            let videoUri = encodeURI(data.url);
            let embedHtml
            if (videoUri) {
              embedHtml = `<p>
                    <span
                        class="mce-object mce-object-video"
                        data-mce-selected="1"
                        data-mce-object="video"
                        data-mce-p-width="100%"
                        data-mce-p-height="auto"
                        data-mce-p-controls="controls"
                        data-mce-p-controlslist="nodownload"
                        data-mce-p-allowfullscreen="true"
                        data-mce-p-src=${videoUri} >
                        <video src=${data.url} width="100%" height="auto" controls="controls" controlslist="nodownload">
                        </video>
                    </span>
                </p>
                <p style="text-align: left;"></p>`;
            } else {
              embedHtml = ""
            }
            resolve({
              html: embedHtml
            });
          } catch (e) {
            resolve({
              html: ""
            });
          }
        },

        branding: false,

        // 自定义图片上传
        images_upload_handler: (blobInfo, success, failure) => {
          const formData = new FormData();
          formData.append("file", blobInfo.blob());
          request(upload, formData)
            .then((res) => {
              if (res.code === 0) {
                let file = res.data.url;
                success(file);
                return;
              }
              failure("上传失败");
            })
            .catch(() => {
              failure("上传出错");
            });
        },

      },

      contentHtml: "",
      updateTimer: null, //防抖
    }),
    computed: {
      loading() {
        return store.state.loading
      }
    },
    watch: {
      content(valueFromParent) {
        // 由父组件自动修改的内容,同步到子组件
        if (valueFromParent !== this.contentHtml) {
          this.contentHtml = valueFromParent;
        }
      },

      contentHtml(valueFromChild = "") {
        // 向父组件派发change事件
        if (valueFromChild !== this.content) {
          this.$emit("change", valueFromChild);
        }
      },
    },
    created() {
      store.commit('setParam', {
        loading: false
      })
    },
    beforeDestroy() {
      this.updateTimer && clearTimeout(this.updateTimer);
    },
  };

pluginstoolbar是成对存在的,plugins必不可少,

在这里插入图片描述
toolbar是页面中操作栏导航的排列在这里插入图片描述

四、一些需求实现

1、在光标处插入内容

在光标处插入内容,此方法会有插入后立即删除却删不掉的问题

 tinyMCE.activeEditor.selection.setContent(`<span style="color:red">{total_score}</span>`)

在光标处插入内容,这个比较完美

tinyMCE.activeEditor.execCommand('mceInsertContent',false,`<span style="color:red">{total_score}</span>`);

2、获取内容、设置内容

  • 如果当前页面只有一个编辑器
tinyMCE.activeEditor.getContent() //获取内容

tinyMCE.activeEditor.setContent('需要设置的编辑器内容') //设置内容
  • 如果当前页面有多个编辑器
tinyMCE.editors[0].getContent() //获取第一个编辑器的内容

tinyMCE.editors[0].setContent('需要设置的编辑器内容') //设置第一个编辑器的内容
  • 获取不带HTML标记的纯文本内容
    取到的 text 即为纯文本内容
 var activeEditor = tinymce.activeEditor;
 var editBody = activeEditor.getBody();
 activeEditor.selection.select(editBody);
 var text = activeEditor.selection.getContent({'format': 'text'});

标签:文本编辑,Vue,false,media,tinymce,activeEditor,file,store
来源: https://blog.csdn.net/weixin_45048913/article/details/118462277

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

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

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

ICode9版权所有