依赖安装:
npm i @tinymce/tinymce-vue -S
<template>
<editor id="tinymce" :init="init" v-model="content"></editor>
</template>
<script setup>
import { computed, onMounted } from "vue";
import Editor from "@tinymce/tinymce-vue";
import Http from "@/utils/Http"; // 项目请求工具方法
defineOptions({ name: "XEditor" });
const props = defineProps({
value: {
type: String,
default: ""
},
tool: {
type: String,
default: "basic"
},
width: {
type: [String, Number],
default: "100%"
},
height: {
type: [String, Number],
default: 500
},
uploadUrl: {
type: String,
default: ""
}
});
const emits = defineEmits(["update:value"]);
const content = computed({
get: () => props.value,
set: (value) => emits("update:value", value)
});
const tool = {
basic: "undo redo | removeformat | fontsize | bold italic underline | alignleft aligncenter alignright alignjustify | table link image "
};
const init = {
selector: "#tinymce",
license_key: "gpl",
language: "zh_CN",
skin: "tinymce-5",
branding: false,
promotion: false,
width: props.width,
height: props.height,
resize: false,
menubar: false, //菜单
plugins: ["table", "link", "image"], //插件
toolbar: tool[props.tool], //工具
convert_urls: false, //绝对路径转化为相对路径
images_upload_url: props.uploadUrl,
// 手动创建表格时注入样式
setup: function (editor) {
editor.on("ExecCommand", function (e) {
if (e.command === "mceInsertTable") {
setTimeout(() => {
const tables = editor.dom.select("table");
const latestTable = tables[tables.length - 1];
// 强制为所有 td/th 添加内联样式
editor.dom.select("td, th", latestTable).forEach((cell) => {
editor.dom.setStyles(cell, {
"border-style": "solid",
"border-width": "1px",
"border-color": "#000",
padding: "5px"
});
});
}, 10);
}
});
},
// 粘贴表格时注入样式
paste_postprocess: function (plugin, args) {
const elements = args.node.querySelectorAll("table, td, th");
elements.forEach((el) => {
// 强制添加内联样式
el.style.border = "1px solid #000";
el.style.padding = "5px";
el.style.textAlign = "center";
el.style.borderCollapse = "collapse";
if (el.tagName === "TABLE") {
el.style.width = "100%";
el.setAttribute("border", "1"); // 确保属性存在
}
});
},
images_upload_handler: (blobInfo) =>
new Promise(async (resolve, reject) => {
const formData = new FormData();
formData.append("file", blobInfo.blob());
const url = props.uploadUrl
const rs = await Http.post(url, formData);
if (rs.status === 0) {
resolve("/" + rs.data.path);
} else {
reject(rs.msg);
}
})
};
</script>