vue2 renrne 引入tinymce[通俗易懂]

vue2 renrne 引入tinymce[通俗易懂]tinymce1.引入和原始使用下载地址:https://www.tiny.cloud/get-tiny/self-hosted/语言包地址:https://www.tiny.clou

大家好,又见面了,我是你们的朋友全栈君。

tinymce

1.引入和原始使用

下载 地址 : https://www.tiny.cloud/get-tiny/self-hosted/

语言包 地址: https://www.tiny.cloud/get-tiny/language-packages/

# vue2.0版本应该使用
npm install --save "@tinymce/tinymce-vue@^3"


# vue3.0版本应该使用
npm install --save "@tinymce/tinymce-vue@^4"


# 再运行 
npm install tinymce -S

安装之后,在 node_modules 中找到 tinymce/skins 目录,然后将 skins 目录拷贝到 static 目录下

结构 如:
static

tinymce
skins
zh_CN.js

在页面中引入以下文件


import tinymce from "tinymce/tinymce";
import "tinymce/themes/silver/theme";
import Editor from "@tinymce/tinymce-vue";
import "tinymce/icons/default/icons";
import "tinymce/plugins/media"; // 插入视频插件
import "tinymce/plugins/image";
import "tinymce/plugins/link";
import "tinymce/plugins/code";
import "tinymce/plugins/table";
import "tinymce/plugins/lists";
import "tinymce/plugins/contextmenu";
import "tinymce/plugins/wordcount";
import "tinymce/plugins/colorpicker";
import "tinymce/plugins/textcolor";

tinymce-vue 是一个组件,需要在 components 中注册,

 components: { Editor },

然后直接使用

<Editor id="tinymce" v-model="tinymceHtml" :init="editorInit"></Editor>

编辑器需要一个 skin 才能正常工作,所以要设置一个 skin_url 指向之前复制出来的 skin 文件

editorInit: {
    language_url: '/static/tinymce/zh_CN.js',
    language: 'zh_CN',
    skin_url: '/static/tinymce/skins/ui/oxide', // skin路径
    height: 300, // 编辑器高度
    branding: false, // 是否禁用“Powered by TinyMCE”
    menubar: true, // 顶部菜单栏显示
    plugins: this.plugins,
    toolbar: this.toolbar,
}

同时在 mounted 中也需要初始化一次:

mounted (){
	tinymce.init({});
},

如果在这里传入上面的 init 对象,并不能生效,但什么参数都不传也会报错,所以这里传入一个空对象

https://blog.csdn.net/zjiang1994/article/details/79880806

https://blog.csdn.net/zjiang1994/article/details/79856058

完成了上面的初始化之后,就已经能正常运行编辑器了,但只有一些基本功能

tinymce 通过添加插件 plugins 的方式来添加功能

比如要添加一个上传图片的功能,就需要用到 image 插件,添加超链接需要用到 link 插件

<template>
  <div class='tinymce'>
    <h1>tinymce</h1>
    <editor id='tinymce' v-model='tinymceHtml' :init='init'></editor>
    <div v-html='tinymceHtml'></div>
  </div>
</template>

<script>
import tinymce from "tinymce/tinymce";
import "tinymce/themes/silver/theme";
import Editor from "@tinymce/tinymce-vue";
import "tinymce/icons/default/icons";
import "tinymce/plugins/media"; // 插入视频插件
import "tinymce/plugins/image";
import "tinymce/plugins/link";
import "tinymce/plugins/code";
import "tinymce/plugins/table";
import "tinymce/plugins/lists";
import "tinymce/plugins/contextmenu";
import "tinymce/plugins/wordcount";
import "tinymce/plugins/colorpicker";
import "tinymce/plugins/textcolor";
  
export default {
  name: 'tinymce',
  data () {
    return {
      tinymceHtml: '请输入内容',
      init: {
          language_url: '/static/tinymce/zh_CN.js',
          language: 'zh_CN',
          skin_url: '/static/tinymce/skins/ui/oxide', // skin路径
          content_css:'/static/tinymce/skins/content/default/content.css',
          height: 300, // 编辑器高度
          branding: false, // 是否禁用“Powered by TinyMCE”
          menubar: true, // 顶部菜单栏显示
          font_formats: '微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif',
          fontsize_formats:'12px 14px 16px 18px 20px 22px 24px 26px 28px 30px 32px 34px 36px 38px 40px 50px 60px 70px 80px 90px 100px 120px 140px 160px 180px 200px',
          plugins: 'link lists image code table colorpicker textcolor wordcount contextmenu',
          toolbar:'bold italic underline strikethrough | fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist | outdent indent blockquote | undo redo | link unlink image code | removeformat',
      }
    }
  },
  mounted () {
    tinymce.init({})
  },
  components: {Editor}
}
</script>

但是当富文本在某一个弹窗上使用时,

工具栏会出现下拉选择时的层级比弹窗的小,所以,选项会被弹窗遮挡。

而解决这个问题,需要把工具栏的下拉框的层级提高,

找到static/tinymce/skins/ui/oxide/skin.min.css文件

把class名为tox-tinymce-aux的第一个的z-index属性变大即可

tinymce 提供了 images_upload_url 等 api 让用户配置上传图片的相关参数

但为了在不麻烦后端的前提下适配自家的项目,还是得用 images_upload_handler 来自定义一个上传方法

     images_upload_handler: (blobInfo, success, failure) => {
       // const img = 'data:image/jpeg;base64,' + blobInfo.base64();
      // success(img);
       this.handleImgUpload(blobInfo, success, failure);
     }

这个方法会提供三个参数:blobInfo, success, failure

其中 blobinfo 是一个对象,包含上传文件的信息

successfailure 是函数,上传成功的时候向 success 传入一个图片地址,失败的时候向 failure 传入报错信息

handleImgUpload (blobInfo, success, failure) {
      // 上传的文件信息
        let fd = new FormData();
        fd.append("file", blobInfo.blob());
        fd.append("type","tinymec")
        this.$http({
          url: this.$http.adornUrl(
            "/localUpload/uploadForType" 
          ),
          method: "post",
          data: fd,
          headers: {
            "Content-Type":
              "multipart/form-data;boundary=" + new Date().getTime(),
            "token": this.$cookie.get('token')
          },
        }).then(({ data }) => {
          if (data && data.code === 0) {
            this.$message({
              message: data.path + ",操作成功",
              type: "success",
              duration: 1500,
              onClose: () => {
                 success(data.path)
              },
            });
          } else {
            failure('error')
          }
        });
}

2.模块封装

<template>
  <Editor id="tinymce" v-model="editHtml" :init="editorInit" @change="changeEdit" ></Editor>
</template>

<script>
import tinymce from "tinymce/tinymce";
import "tinymce/themes/silver/theme";
import Editor from "@tinymce/tinymce-vue";
import "tinymce/icons/default/icons";
import "tinymce/plugins/media"; // 插入视频插件
import "tinymce/plugins/image";
import "tinymce/plugins/link";
import "tinymce/plugins/code";
import "tinymce/plugins/table";
import "tinymce/plugins/lists";
import "tinymce/plugins/contextmenu";
import "tinymce/plugins/wordcount";
import "tinymce/plugins/colorpicker";
import "tinymce/plugins/textcolor";

export default {
  props: {
    value: {
      //父组件传进来的默认值
      default: "",
    },
  },
  components: { Editor },

  Myeditmounted() {
    tinymce.init({});
  },
  created() {},
  data() {
    return {
      editHtml: "",
      editorInit: {
        language_url: "/static/tinymce/zh_CN.js",
        language: "zh_CN",
        skin_url: "/static/tinymce/skins/ui/oxide", // skin路径
        content_css: "/static/tinymce/skins/content/default/content.css",
        height: 300, // 编辑器高度
        branding: false, // 是否禁用“Powered by TinyMCE”
        menubar: true, // 顶部菜单栏显示
        font_formats:
          "微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif",
        fontsize_formats:
          "12px 14px 16px 18px 20px 22px 24px 26px 28px 30px 32px 34px 36px 38px 40px 50px 60px 70px 80px 90px 100px 120px 140px 160px 180px 200px",
        plugins:
          "link lists image code table colorpicker textcolor wordcount contextmenu",
        toolbar:
          "bold italic underline strikethrough | fontsizeselect | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist | outdent indent blockquote | undo redo | link unlink image code | removeformat",
        images_upload_handler: (blobInfo, success, failure) => {
          // const img = "data:image/jpeg;base64," + blobInfo.base64();
          // success(img);
           this.handleImgUpload(blobInfo, success, failure);
          
        },
      },
    };
  },
  watch: {
    value: {
      //data改变的时候同步到子组件
      deep: true,
      handler(value) {
        this.editHtml = value;
        // console.log(value);
      },
      
    },
    editHtml: {
      //data改变的时候同步到子组件
      deep: true,
      handler(val) {
        this.$emit('update:value', val);
        console.log(val);
        // console.log(this.value);
      },
      
    },
  },
  methods: {
    handleImgUpload (blobInfo, success, failure) {
      // 上传的文件信息
        let fd = new FormData();
        fd.append("file", blobInfo.blob());
        fd.append("type","tinymec")
        this.$http({
          url: this.$http.adornUrl(
            "/file/uploadForType" 
          ),
          method: "post",
          data: fd,
          headers: {
            "Content-Type":
              "multipart/form-data;boundary=" + new Date().getTime(),
            "token": this.$cookie.get('token')
          },
        }).then(({ data }) => {
          if (data && data.code === 0) {
            this.$message({
              message: data.path + ",操作成功",
              type: "success",
              duration: 1500,
              onClose: () => {
                 success(data.path)
              },
            });
          } else {
            failure('error')
          }
        });
},
    changeEdit(){
        console.log(1111);
    },
  },
};
</script>

<style>
</style>

<custom1>
  This could be e.g. documentation for the component.
</custom1>
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/155091.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号