index.vue
3.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<script setup lang="ts">
/**
* 富文本
* @module Tinymce
*/
import { ref, onMounted, onUnmounted } from "vue";
import { uploadPicSource } from "@/api/user/login";
import { toolbar, plugins } from "./settings/index";
import load from "./settings/load";
import { ElMessage, ElLoading } from "element-plus";
/**
* @description 组件属性
* @prop {string | null} moduleName 上传接口需要传的module值
* @prop {string} modelValue 默认内容
* @prop {boolean} readonly 禁用组件
* @prop {string} id tinymce需要用到的id
* @prop {number} height 组件高
* @prop {number} width 组件宽
*/
interface Props {
moduleName?: string;
modelValue?: string;
readonly?: boolean;
id?: string;
height?: number;
width?: number;
}
const props = withDefaults(defineProps<Props>(), {
moduleName: "test",
modelValue: "",
readonly: false,
id: "vue-tinymce-" + +new Date() + ((Math.random() * 1000).toFixed(0) + ""),
height: 404,
width: 600,
});
const emit = defineEmits<{
(e: "update:modelValue", val: string): void;
}>();
const cdnUrl = ref("http://gongongku.cnlive.com/base/tinymce.min.js");
let pageLoading = ref(null);
// 删除tinymce实例
const destroyTinymce = () => {
const tinymce = window.tinymce.get(props.id);
if (tinymce) {
tinymce.destroy();
}
};
// 初始化tinymce实例
const initTinymce = () => {
tinymce.init({
selector: `#${props.id}`, // 组件id
height: props.height, // 自定义高
width: props.width, // 自定义宽
readonly: props.readonly, // 禁用开关
language_url: "http://testweb.community.cnlive.com/languages/zh_CN.js", // 工具栏语言包,需要线上地址
language: "zh_CN", // 中文设置
plugins: plugins, // 插件
toolbar: toolbar, // 工具栏配置
theme_url: "http://gongongku.cnlive.com/base/theme.min.js", // 主题包
powerpaste_word_import: "clean",
code_dialog_height: 450,
code_dialog_width: 1000,
advlist_bullet_styles: "square",
advlist_number_styles: "default",
imagetools_cors_hosts: ["www.tinymce.com", "codepen.io"],
default_link_target: "_blank",
link_title: false,
nonbreaking_force_tab: true,
end_container_on_empty_block: true, // 空元素回车将其拆分
images_upload_url: `${import.meta.env.VITE_BASE_URL}upload/uploadPicSource`, // 图片上传接口地址
// 图片上传
// 注意!!!!!!!
// 以下图片上传逻辑经测试可用,目前该功能没开放。
// 如需启用图片上传功能,移步 settings/index.ts,添加图片上传插件和菜单设置项。
// 为了提升页面资源加载速度,富文本相关js、css依赖部署在公司自有cdn上,如需开启新插件,须联系运维同事上传新插件相关的依赖文件。
images_upload_handler: function (blobInfo, succFun, failFun, progress) {
const files = new window.File([blobInfo.blob()], "图片");
const fd = new FormData();
fd.append("multipartFile", files);
uploadPicSource(
{
module: props.moduleName,
},
fd
)
.then((res) => {
succFun(res.data.data);
})
.catch((error) => {
failFun(error);
});
},
// 内容改变监听
init_instance_callback: (editor) => {
pageLoading.close();
// 赋默认值
if (props.modelValue) {
editor.setContent(props.modelValue);
}
// 监听
editor.on("NodeChange Change KeyUp SetContent", () => {
emit("update:modelValue", editor.getContent());
});
},
});
};
onUnmounted(() => {
destroyTinymce();
});
onMounted(() => {
pageLoading = ElLoading.service({
lock: true,
text: "加载中,请稍候...",
});
load(cdnUrl.value, (err) => {
if (err) {
ElMessage.error(err.message);
return;
}
initTinymce();
});
});
</script>
<template>
<textarea :id="props.id"></textarea>
</template>