安装:
- 我用的是tinymce最新版本v6
npm install tinymce -S
npm install @tinymce/tinymce-vue -S
2.安装语言包:Language Packages | Trusted Rich Text Editor | TinyMCE
3.在项目public文件夹下--新建tinymce文件夹,安装包解压在该文件夹下
封装组件TEditor.vue
<template>
<editor v-model="myValue" :init="init"></editor>
</template>
<script setup lang="ts">
import { uploadImg } from "../api/module/new_news";
//JS部分
//在js中引入所需的主题和组件
import tinymce from "tinymce/tinymce";
import "tinymce/skins/content/default/content.css";
import Editor from "@tinymce/tinymce-vue";
import "tinymce/themes/silver";
import "tinymce/themes/silver/theme";
import "tinymce/icons/default"; //引入编辑器图标icon,不引入则不显示对应图标
import "tinymce/models/dom"; // 这里是个坑 一定要引入
//在TinyMce.vue中接着引入相关插件
import "tinymce/icons/default/icons";
import "tinymce/plugins/image"; // 插入上传图片插件
import "tinymce/plugins/media"; // 插入视频插件
import "tinymce/plugins/table"; // 插入表格插件
import "tinymce/plugins/lists"; // 列表插件
import "tinymce/plugins/wordcount"; // 字数统计插件
import "tinymce/plugins/code"; // 源码
import "tinymce/plugins/fullscreen"; //全屏
import "tinymce/plugins/preview"; //预览
// import 'tinymce/plugins/paste'; //粘贴插件
import "tinymce/plugins/pagebreak"; //插入分页符
import "tinymce/plugins/codesample";
import "tinymce/plugins/searchreplace";
import "tinymce/plugins/link";
import "tinymce/plugins/autosave";
import "tinymce/plugins/autolink";
import "tinymce/plugins/anchor";
import "/public/tinymce/plugins/axupimgs/plugin.js";
// /
// import "tinymce/plugins/fullpage";autolink anchor
//接下来定义编辑器所需要的插件数据
import { reactive, ref } from "vue";
import { onMounted, defineEmits, watch } from "vue";
// import axios from "axios";
import request from "@/utils/axios";
// import { updateImg } from "@/api/order/order";
const emits = defineEmits(["getContent"]);
//这里我选择将数据定义在props里面,方便在不同的页面也可以配置出不同的编辑器,当然也可以直接在组件中直接定义
const props = defineProps({
value: {
type: String,
default: () => {
return "";
},
},
baseUrl: {
type: String,
default: "",
},
disabled: {
type: Boolean,
default: false,
},
plugins: {
type: [String, Array],
// default: "lists image media table wordcount fullscreen",
default:
" wordcount table searchreplace preview pagebreak fullscreen codesample autosave autolink anchor autolink image media lists link code image axupimgs",
},
toolbar: {
type: [String, Array],
default:
" fontsize fontfamily bold italic lineheight underline alignleft aligncenter alignright alignjustify anchor | undo redo | formatselect | forecolor backcolor | bullist numlist outdent indent | lists link image axupimgs media table | removeformat | fullscreen|preview code codesample|searchreplace ",
}, //必填
objId:{
type: Object,
default: {},
}
});
// watch(()=>props.objId,(id,old)=>{
// console.log(id,'xinid')
// id=newId
// })
console.log(props.objId.newId,'++++++++++++++')
//用于接收外部传递进来的富文本
const myValue = ref(props.value);
//定义一个对象 init初始化
const init = reactive({
selector: "textarea",
language_url: "/cms/tinymce/langs/zh_CN.js", // 语言包的路径,具体路径看自己的项目,文档后面附上中文js文件
language: "zh_CN", //语言
//自动聚焦
auto_focus: true,
skin_url: "tinymce/skins/ui/oxide", // skin路径,具体路径看自己的项目
height: 800, //编辑器高度
width: "100%",
branding: false, //是否禁用“Powered by TinyMCE”
menubar: false, //顶部菜单栏显示
image_dimensions: false, //去除宽高属性
plugins: props.plugins, //这里的数据是在props里面就定义好了的
toolbar: props.toolbar, //这里的数据是在props里面就定义好了的
images_upload_url: "/news/picUpload",
// paste_convert_word_fake_lists: true, // 插入word文档需要该属性
font_size_formats: "12px 14px 16px 18px 24px 36px 48px 56px 72px",
font_family_formats:
"微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif",
line_height_formats: "1 1.2 1.4 1.6 2",
paste_webkit_styles: "all",
paste_merge_formats: true,
nonbreaking_force_tab: false,
paste_auto_cleanup_on_paste: false,
file_picker_types: "file image media",
content_css: "tinymce/skins/content/default/content.css", //以css文件方式自定义可编辑区域的css样式,css文件需自己创建并引入
// 文件上传
file_picker_callback: (callback, value, meta) => {
//,,m4v,avi,wmv,rmvb,mov,mpg,mpeg,webm
let filetype =
".pdf, .txt, .zip, .rar, .7z, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .mp3, .mp4,.mkv, .avi,.wmv, .rmvb,.mov,.mpg,.mpeg,.webm, .jpg, .jpeg, .png, .gif"; //限制文件的上传类型
let inputElem = document.createElement("input"); //创建文件选择
inputElem.setAttribute("type", "file");
inputElem.setAttribute("accept", filetype);
inputElem.click();
inputElem.onchange = () => {
let upurl = "";
let file = inputElem.files[0]; //获取文件信息
const ph = import.meta.env.VITE_APP_IMAGE_URL;
let params = new FormData();
if (file.type.slice(0, 5) == "video") {
//判断文件类型
upurl = "/news/videoUpload";
params.append("file", file);
params.append("id", props.objId.newId);
} else if (file.type.slice(0, 5) == "image") {
upurl = "/news/picUpload";
params.append("file", file);
params.append("id", props.objId.newId);
} else {
upurl = "/news/attachUpload";
params.append("file", file);
params.append("siteId", props.objId.siteId);
params.append("newsId", props.objId.newId);
params.append("attachDesc", "");
}
if (file.type.slice(0, 5) == "image" && file.size / 1024 / 1024 > 2) {
alert("上传失败,图片大小请控制在2M以内");
} else if (
file.type.slice(0, 5) == "video" &&
file.size / 1024 / 1024 > 500
) {
alert("上传失败,视频大小请控制在 500M 以内");
} else if (file.size / 1024 / 1024 > 10) {
alert("上传失败,文件大小请控制在 10M 以内");
} else {
let config = {
headers: {
"Content-Type": "multipart/form-data",
},
};
request
.post(upurl, params, config)
.then((res) => {
if (res.code == 200) {
if (res.data.url) {
callback(ph + res.data.url, {
text: res.data.alt,
title: res.data.name,
});
} else {
console.log(res);
//上传成功,在回调函数里填入文件路径
callback(ph + res.data);
}
} else {
alert("上传失败");
}
})
.catch(() => {
alert("上传出错,服务器开小差了呢");
});
}
};
},
});
//监听外部传递进来的的数据变化
watch(
() => props.value,
() => {
myValue.value = props.value;
emits("getContent", myValue.value);
}
);
//监听富文本中的数据变化
watch(
() => myValue.value,
() => {
emits("getContent", myValue.value);
}
);
//在onMounted中初始化编辑器
onMounted(() => {
tinymce.init({});
});
</script>
上传图片
上传附件
上传视频
最终效果如下图
批量上传图片实现
需要安装插件ax多图片批量上传插件 | TinyMCE中文文档中文手册
注意:安装完以后放到最开始新建的tinymce文件夹下
但是在文件里引入的时候会有问题
这里借鉴了在vuecli3.0+中使用tinymce及实现多图上传,文件上传,公式编辑等功能 - huihuihero - 博客园
为什么引入的是plugin.js是因为axupimgs中没有index.js文件,我试了一下写一个index.js 引入的时候还是会报错,具体的原因我也不大明白,(就是菜)..
不报错的引入方式,但是会有下面的提示要使用/tinymce/plugins/axupimgs/plugin.js这种方式,但是按照这个来就会报错
引入完以后最重要的就是去plugin.js文件修改一下路径哦!!!不然就会出现空白的情况
就是你们项目的地址
插件安装好修改完以后其他的就很好实现了,直接看代码吧
多个图片上传主要是基于单个图片上传的,所以方法都是一样的,这里最重要的就是单张图片和多个图片回调传的参数不一样.
最后看一下效果吧!
我也是第一次用这个编辑器,写的不好的地方,大佬们多指正