首页 > 其他分享 >vue2 使用tinymce编辑器实现上传图片及粘贴word文本保留格式并粘贴图片自动上传

vue2 使用tinymce编辑器实现上传图片及粘贴word文本保留格式并粘贴图片自动上传

时间:2023-09-17 12:33:57浏览次数:45  
标签:type default data tinymce plugins import 上传 粘贴 图片

下载对应的版本

 

npm install @tinymce/[email protected] -S
npm install [email protected] -S

然后在node_modules中找到tinymce把整个文件复制下来粘到public中

 

在组件页面使用

根据自己需求进行注释或添加功能

<template>
<div class="tinymce-editor">
<Editor
:id="tinymceId"
:init="init"
:disabled="disabled"
v-model="myValue"
@input="tinymcechange"
></Editor>
</div>
</template>

<script>
import tinymce from "tinymce/tinymce"; //tinymce默认hidden,不引入不显示
import Editor from "@tinymce/tinymce-vue"; //编辑器引入
import "tinymce/themes/silver/theme"; //编辑器主题
import "tinymce/icons/default"; //引入编辑器图标icon,不引入则不显示对应图标
// 引入编辑器插件(基本免费插件都在这儿了)
import "tinymce/plugins/advlist"; //高级列表
import "tinymce/plugins/autolink"; //自动链接
import "tinymce/plugins/link"; //超链接
import "tinymce/plugins/image"; //插入编辑图片
import "tinymce/plugins/lists"; //列表插件
import "tinymce/plugins/charmap"; //特殊字符
import "tinymce/plugins/media"; //插入编辑媒体
import "tinymce/plugins/wordcount"; // 字数统计
import "tinymce/plugins/colorpicker"; //选择颜色插件
import "tinymce/plugins/textcolor"; //文本颜色插件
import "tinymce/plugins/print"; //打印
import "tinymce/plugins/preview"; //预览
import "tinymce/plugins/paste";
import "tinymce/plugins/fullscreen";
import "tinymce/plugins/searchreplace";
import "tinymce/plugins/save";
import "tinymce/plugins/autosave";
import "tinymce/plugins/imagetools";
import "tinymce/plugins/table";
import "tinymce/plugins/codesample";
import "tinymce/plugins/hr";
import "tinymce/plugins/emoticons";
import "tinymce/plugins/anchor";
import "tinymce/plugins/directionality";
import "tinymce/plugins/pagebreak";
import "tinymce/plugins/quickbars";
import "tinymce/plugins/nonbreaking";
import "tinymce/plugins/visualblocks";
import "tinymce/plugins/visualchars";
// import "tinymce/plugins/powerpaste"; //粘贴图片
import "tinymce/plugins/emoticons/js/emojis";
// import "tinymce/plugins/uploadImg"; //这里需要将插件引入
import "tinymce/plugins/autoresize"; //编辑器高度自适应,注:plugins里引入此插件时,Init里设置的height将失效
import store from "@/store";
// import api from "@/api/";
import axios from "axios";
// import "tinymce/plugins/powerpaste/";
export default {
components: {
Editor
},
props: {
reportIndex: {
type: Number,
default: null
},
//内容
value: {
type: String,
default: ""
},
// 用于区分单个tinymce
tinymceId: {
type: String,
default: "tinymce"
},
disabled: {
type: Boolean,
default: false
},
//插件
plugins: {
type: [String, Array],
default: "myimg table advlist lists image"
},
//工具栏
toolbar: {
type: [String, Array],
default:
"myimg | code | forecolor backcolor bold italic underline strikethrough | formatselect | align | bullist numlist | table image"
},
// 隐藏菜单栏
menubar: {
type: Boolean,
default: false
},
// 最下方的元素路径和字数统计那一栏是否显示
statusbar: {
type: Boolean,
default: false
},
// 元素路径是否显示
elementpath: {
type: Boolean,
default: false
},
// 设置为“true”即允许粘贴图像,而将其设置为“false”则不允许粘贴图像。
paste_data_images: {
type: Boolean,
default: true
},
// 编辑器宽高是否可变,false-否,true-高可变,'both'-宽高均可,注意引号
resize: {
type: [Boolean, String],
default: "both"
},
// 高度
height: {
type: [Number, String],
default: 200
},
// 插入word文档需要该属性
paste_convert_word_fake_lists: {
type: Boolean,
default: true
},
placeholder: {
type: String,
default: "在这里输入内容"
},
// 双向绑定并触发change事件
model: {
prop: "value",
event: "tinymcechange"
},
// 上传图片地址
imgUploadUrl: {
type: String,
default: ""
}
},
data() {
return {
//初始化配置
myValue: this.value,
init: {
selector: "#" + this.tinymceId,
language_url: "/tinymce/langs/zh_CN.js", //汉化路径是自定义的,一般放在public或static里面
language: "zh_CN",
skin_url: "/tinymce/skins/ui/oxide", //皮肤:浅色
// skin_url: "/tinymce/skins/ui/oxide-dark", //皮肤:暗色
plugins: this.plugins, //插件
toolbar: this.toolbar,
plugin_preview_width: 375, // 预览宽度
plugin_preview_height: 668,
toolbar_location: "/",
content_style: "img {max-width:100%;}", // 直接自定义可编辑区域的css样式
toolbar_drawer: "sliding",
menubar: this.menubar, //隐藏菜单栏
statusbar: this.statusbar, // 最下方的元素路径和字数统计那一栏是否显示
elementpath: this.elementpath, //元素路径是否显示
branding: false, // 隐藏品牌标识
paste_data_images: this.paste_data_images, // 设置为“true”即允许粘贴图像,而将其设置为“false”则不允许粘贴图像。
resize: this.resize, //编辑器宽高是否可变,false-否,true-高可变,'both'-宽高均可,注意引号
height: this.height, //高度
paste_retain_style_properties: "all",
paste_word_valid_elements: "*[*]", //word需要它
paste_convert_word_fake_lists: this.paste_convert_word_fake_lists, // 插入word文档需要该属性
paste_webkit_styles: "all",
paste_merge_formats: true,
nonbreaking_force_tab: false,
paste_auto_cleanup_on_paste: false,
placeholder: this.placeholder,
//链接打开方式
default_link_target: "_blank",
// 图片上传三个参数,图片数据,成功时的回调函数,失败时的回调函数
images_upload_handler: (blobInfo, success, failure) => {
this.handleImgUpload(blobInfo, success, failure);
},
init_instance_callback: editor => {
if (this.value) {
editor.setContent(this.value);
}
this.hasInit = true;

editor.on("NodeChange Change KeyUp SetContent", () => {
this.hasChange = true;
// const val = editor.getContent().replace(/<p><img\s?src="data.*?<\/p>/g, '')
this.$emit("input", editor.getContent());
});

editor.on("paste", evt => {
// 监听粘贴事件
console.log("监听粘贴事件", evt);
this.onPaste(evt);
});
},
// 自定义工具栏功能
setup: function(editor) {
editor.ui.registry.addButton("myimg", {
// text: "插入推荐的商品链接",
icon: "image",
onAction: () => {
console.log("插入推荐的商品链接");
}
});
}
},
uploadTimeOut: null,
removeFn: null
};
},

mounted() {
tinymce.init({});
},
methods: {
onPaste(event, success, failure) {
// let _this = this;
let self = this;

// 实现图⽚粘贴上传
const items = (event.clipboardData || window.clipboardData).items;
// items为伪数组微信/QQ截图以及此富⽂本区域内复制粘贴的length为1,⿏标右键复制粘贴图⽚以及⽂本的复制粘贴的length为2;
let len = items.length;
for (let i = 0; i < len; i++) {
if (items[i].kind == "file" && items[i].type.indexOf("image") != -1) {
// 判断是否为图⽚类型
event.preventDefault(); // 如果是图⽚阻⽌⾃动粘贴到富⽂本编辑器
let file = items[i].getAsFile(); // 获取⽂件数据
let blob = new Blob([file], { type: file.type }); //实例化⼀个blob 将图⽚⼤⼩以及类型初始化到blob⾥
// let index = file.name.lastIndexOf(".");
// let fileName =
// Date.now() + file.name.substring(index, file.name.length);
// fileName --- 图⽚名称可⾃⾏处理
console.log("粘贴的是图⽚类型", blob, file);
// let file = blobInfo.blob();
let CancelToken = axios.CancelToken;
const isLt2M = file.size / 1024 < 500;
if (!isLt2M) {
failure("上传失败,图片不可超过500KB!");
return false;
}
const formdate = new FormData();
formdate.append("file", file); //imageFile文件名和后端统一
axios({
url: this.imgUploadUrl,
method: "post",
data: formdate,
headers: {
"Content-Type": "multipart/form-data",
Authorization: `Bearer${store.state.login.login.access_token}`
},
cancelToken: new CancelToken(function executor(c) {
self.cancel = c;
})
})
.then(response => {
let { code } = response.data;
if (code == 200) {
let { filePath } = response.data.data; //"http://127.0.0.1:8080/fileUpload/20220609/998e9ea0-8f00-42f8-9a71-901e81855921.png"
// 图⽚上传成功,插⼊到富⽂本编辑器
if (filePath) {
// let url =
// filePath.indexOf("http://") != -1
// ? filePath.replace("http://", "https://")
// : filePath;
tinymce.execCommand(
"mceReplaceContent",
false,
`<img class="wscnph" src="${filePath}" >`
);
}
} else {
this.$message.error(response.data.msg);
}
})
.catch(function(err) {
// 上传错误可⾃⾏给出提⽰
this.$message.error(err);
});
} else {
// 不是图⽚类型直接粘贴, 跳过oss上传处理
console.log("粘贴的不是图⽚");
}
}
},
// change触发事件
tinymcechange(e) {
this.$emit("eventHandle", {
type: "change",
data: e,
reportIndex: this.reportIndex
});
},
//可以添加一些自己的自定义事件,如清空内容
clear() {
this.myValue = "";
},
handleImgUpload(blobInfo, success, failure) {
console.log("我要上传");
let self = this;
let file = blobInfo.blob();
let CancelToken = axios.CancelToken;
const isLt2M = file.size / 1024 < 500;
// var testmsg = file.name.substring(file.name.lastIndexOf(".") + 1);
// const extension = testmsg === "jpg";
// const extension2 = testmsg === "png";
// if (!extension && !extension2) {
// failure("上传文件只能是 jpg、png格式!");
// return false;
// }
if (!isLt2M) {
failure("上传失败,图片不可超过500KB!");
return false;
}
const formdate = new FormData();
formdate.append("file", blobInfo.blob()); //imageFile文件名和后端统一
axios({
url: this.imgUploadUrl,
method: "post",
data: formdate,
headers: {
"Content-Type": "multipart/form-data",
Authorization: `Bearer${store.state.login.login.access_token}`
},
cancelToken: new CancelToken(function executor(c) {
self.cancel = c;
})
// onUploadProgress: progressEvent => {
// this.uploadPercent = Math.round(
// (progressEvent.loaded / progressEvent.total) * 100
// );
// }
}).then(response => {
console.log("response", response.data);
if (response.data.code == 200) {
let url = response.data.data.filePath;
console.log("成功了", url);
success(url); //回显url
} else {
failure(response.data.msg);
this.$message.error(response.data.msg);
}
});
}
},
watch: {
//监听内容变化
value(newValue) {
this.myValue = newValue == null ? "" : newValue;
},
myValue(newValue) {
if (this.triggerChange) {
this.$emit("change", newValue);
} else {
this.$emit("input", newValue);
}
}
}
};
</script>

页面使用

<div
v-for="(item, index) in quillList"
:key="index + '8'"
:slot="item.slotName"
>
<Tinymce
v-if="pageNum == item.pageNumID"
v-model="item.standardSlotValue"
:imgUploadUrl="imgUploadUrl"
:reportIndex="index"
@eventHandle="standardSlotChange"
/>

</div>
<script>
import Tinymce from "@/components/Tinymce.vue";
components: {
Tinymce
},

// 标准要求富文本值改变
standardSlotChange(obj) {
// console.log("标准要求富文本值改变", obj);
if (obj.type == "change" && String(obj.reportIndex)) {
this.quillList[obj.reportIndex].standardSlotValue = obj.data;
this.formData.form[this.quillList[obj.reportIndex].key] = obj.data;
}
},
</script>

 

参考文章:http://blog.ncmem.com/wordpress/2023/09/17/vue2-%e4%bd%bf%e7%94%a8tinymce%e7%bc%96%e8%be%91%e5%99%a8%e5%ae%9e%e7%8e%b0%e4%b8%8a%e4%bc%a0%e5%9b%be%e7%89%87%e5%8f%8a%e7%b2%98%e8%b4%b4word%e6%96%87%e6%9c%ac%e4%bf%9d%e7%95%99%e6%a0%bc%e5%bc%8f/

欢迎入群一起讨论

 

 

标签:type,default,data,tinymce,plugins,import,上传,粘贴,图片
From: https://www.cnblogs.com/songsu/p/17708208.html

相关文章

  • tinymce实现从word直接粘贴并自动上传图片
    背景介绍:tinymce是一款优秀的富文本编辑器。powerpaste是其一款收费插件,能实现word内容无缝粘贴入网页的tinymce中,可保留word的格式以及自动将word中的图片上传至服务器端。使用说明:我默认你们都能在官网下载到tinymce,鉴于部分同学是通过npm安装的,要注意了:npm安装的不行!!!!不能用......
  • jquery设置图片可手动拖拽
    JQuery是一款流行的JavaScript框架,可以轻松实现网页交互效果。而其中一种常见效果是图片手动拖拽。以下是设置图片手动拖拽的JQuery代码。$(document).ready(function(){varisDragging=false;varmousePos={x:0,y:0};varelemPos={x:0,y:0};var$elem=$......
  • 带附件和图片的邮件发送脚本
    1importsmtplib2fromemail.mime.textimportMIMEText3fromemail.mime.multipartimportMIMEMultipart4fromemail.mime.imageimportMIMEImage5fromemail.headerimportHeader67#第三方SMTP服务器8mail_host="mail.163.com"#服务器9mai......
  • WSI病理图片的Level和放大倍数的对应关系以及获取代码
    WSI病理图片的Level信息获取,以及和放大倍数的对应关系的获取代码:importopenslideimportnumpyasnpfromIPython.displayimportdisplaydefdisplay_wsi_info_and_level(wsi_path,level):#打开WSI文件slide=openslide.open_slide(wsi_path)#获取......
  • 华为应用市场上架 视频介绍上传 遇到的问题解决
    昨天在华为应用市场上架应用, 视频介绍上传时, 一直是视频加载中,百思不得其解. 虽然不是第一次上传视频了,怎么这次遇到这个问题.偶然发现在视频介绍上传时, 选择海报后,一定要下划,点击确认,才能完成上传!否则一直是视频加载中............
  • 解决wangEditor从word复制粘贴图片,带有页眉页脚的问题
    话不多说,直接贴代码。rtf数据能提取到页眉页脚图片的原因:提取Word文档中包含的所有图像数据,包括页眉和页脚中的图像数据。这是因为RTF(RichTextFormat)是一种标记语言,可以在其中嵌入文本、图像和其他媒体类型的数据。在Word中,页眉和页脚的内容也可以通过RTF格式进行描述......
  • 镜像图片复原
    镜像图片复原一、示例图 二、复原步骤1、工具:光影魔术手2、“打开”功能:导入图片3、“旋转”功能:3.1左右镜像 3.2向左旋转 三、保存......
  • 帝国CMS 7.5编辑器从WORD中粘贴过来无法保留格式和图片的解决办法
     1.配置过滤js文件 首先打开 \e\admin\ecmseditor\infoeditor\plugins\pastefromword\filter\default.js 在文件的最后部分又如下代码(修改前的代码),也可以搜索CKEDITOR.cleanWord进行定位。 修改前: CKEDITOR.cleanWord=function(a,c){       CKEDITOR......
  • 如何使用华为云对象存储OBS托管Discuz!论坛图片和附件
    Discuz!论坛默认支持通过FTP的方式上传远程附件,自然能够想到在S3fs的基础上,加上一个简单的FTP服务器(无须对公网开放FTP端口)。总体是这么个架构:这里以CentOS7下的vsftpd为例安装vsftpd:-------------这里是重点------------为了让桶中的文件可以让用户直接访问到,需要修改桶......
  • springmvc中设置文件的上传与下载,首先需要导入依赖,之后需要在springmvc.xml中配置问价
    2023-09-16导入依赖<dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.4</version></dependency>设置文件上传解析器springmvc.xml<?xml......