From 089bf5d2378b3c4a61d795b2a92bede2c193b771 Mon Sep 17 00:00:00 2001
From: admin <344137771@qq.com>
Date: Tue, 06 Jan 2026 11:22:58 +0800
Subject: [PATCH] 1
---
src/components/tiny-mce/index.vue | 260 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 260 insertions(+), 0 deletions(-)
diff --git a/src/components/tiny-mce/index.vue b/src/components/tiny-mce/index.vue
new file mode 100644
index 0000000..7fdfd51
--- /dev/null
+++ b/src/components/tiny-mce/index.vue
@@ -0,0 +1,260 @@
+<template>
+ <div :class="{fullscreen:fullscreen}" class="tinymce-container" :style="{width:containerWidth}">
+ <textarea :id="tinymceId" class="tinymce-textarea" />
+ </div>
+</template>
+
+<script>
+/**
+ * docs:
+ * https://panjiachen.github.io/vue-element-admin-site/feature/component/rich-editor.html#tinymce
+ */
+import plugins from './plugins'
+import toolbar from './toolbar'
+import load from './dynamicLoadScript'
+
+// why use this cdn, detail see https://github.com/PanJiaChen/tinymce-all-in-one
+const resourceCdn1 = 'https://cdn.jsdelivr.net/npm/tinymce-all-in-one@4.9.3/tinymce.min.js'
+const resourceCdn2 = 'https://unpkg.zhimg.com/tinymce-all-in-one@4.9.3/tinymce.min.js'
+const resourceCdn3 = 'https://unpkg.com/tinymce-all-in-one@4.9.3/tinymce.min.js'
+
+export default {
+ name: 'Tinymce',
+ props: {
+ id: {
+ type: String,
+ default: function () {
+ return 'vue-tinymce-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '')
+ }
+ },
+ value: {
+ type: String,
+ default: ''
+ },
+ toolbar: {
+ type: Array,
+ required: false,
+ default () {
+ return []
+ }
+ },
+ menubar: {
+ type: String,
+ default: 'file edit insert view format table'
+ },
+ height: {
+ type: [Number, String],
+ required: false,
+ default: 360
+ },
+ width: {
+ type: [Number, String],
+ required: false,
+ default: 'auto'
+ }
+ },
+ data () {
+ return {
+ hasChange: false,
+ hasInit: false,
+ tinymceId: this.id,
+ fullscreen: false
+ }
+ },
+ computed: {
+ language () {
+ return localStorage.getItem('lang') || 'zh_CN'
+ },
+ containerWidth () {
+ const width = this.width
+ if (/^[\d]+(\.[\d]+)?$/.test(width)) { // matches `100`, `'100'`
+ return `${width}px`
+ }
+ return width
+ }
+ },
+ watch: {
+ value (val) {
+ if (!this.hasChange && this.hasInit) {
+ this.$nextTick(() =>
+ window.tinymce.get(this.tinymceId).setContent(val || ''))
+ }
+ },
+ language () {
+ this.destroyTinymce()
+ this.$nextTick(() => this.initTinymce())
+ }
+ },
+ mounted () {
+ this.init()
+ },
+ activated () {
+ if (window.tinymce) {
+ this.initTinymce()
+ }
+ },
+ deactivated () {
+ this.destroyTinymce()
+ },
+ destroyed () {
+ this.destroyTinymce()
+ },
+ methods: {
+ init () {
+ // dynamic load tinymce from cdn
+ load(resourceCdn1, (err) => {
+ if (!err) {
+ this.initTinymce()
+ return
+ }
+ load(resourceCdn2, (err2) => {
+ if (!err2) {
+ this.initTinymce()
+ return
+ }
+ load(resourceCdn3, (err3) => {
+ if (!err3) {
+ this.initTinymce()
+ return
+ }
+ this.$message.error(err.message)
+ })
+ })
+ })
+ },
+ initTinymce () {
+ const _this = this
+ window.tinymce.init({
+ language: this.language,
+ selector: `#${this.tinymceId}`,
+ height: this.height,
+ body_class: 'panel-body ',
+ object_resizing: false,
+ toolbar: this.toolbar.length > 0 ? this.toolbar : toolbar,
+ menubar: this.menubar,
+ plugins: plugins,
+ end_container_on_empty_block: true,
+ 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, // inserting nonbreaking space need Nonbreaking Space Plugin
+ init_instance_callback: editor => {
+ if (_this.value) {
+ editor.setContent(_this.value)
+ }
+ _this.hasInit = true
+ editor.on('NodeChange Change KeyUp SetContent', () => {
+ this.hasChange = true
+ this.$emit('input', editor.getContent())
+ })
+ },
+ setup (editor) {
+ editor.on('FullscreenStateChanged', (e) => {
+ _this.fullscreen = e.state
+ })
+ },
+ // it will try to keep these URLs intact
+ // https://www.tiny.cloud/docs-3x/reference/configuration/Configuration3x@convert_urls/
+ // https://stackoverflow.com/questions/5196205/disable-tinymce-absolute-to-relative-url-conversions
+ convert_urls: false
+ // 整合七牛上传
+ // images_dataimg_filter(img) {
+ // setTimeout(() => {
+ // const $image = $(img);
+ // $image.removeAttr('width');
+ // $image.removeAttr('height');
+ // if ($image[0].height && $image[0].width) {
+ // $image.attr('data-wscntype', 'image');
+ // $image.attr('data-wscnh', $image[0].height);
+ // $image.attr('data-wscnw', $image[0].width);
+ // $image.addClass('wscnph');
+ // }
+ // }, 0);
+ // return img
+ // },
+ // images_upload_handler(blobInfo, success, failure, progress) {
+ // progress(0);
+ // const token = _this.$store.getters.token;
+ // getToken(token).then(response => {
+ // const url = response.data.qiniu_url;
+ // const formData = new FormData();
+ // formData.append('token', response.data.qiniu_token);
+ // formData.append('key', response.data.qiniu_key);
+ // formData.append('file', blobInfo.blob(), url);
+ // upload(formData).then(() => {
+ // success(url);
+ // progress(100);
+ // })
+ // }).catch(err => {
+ // failure('出现未知问题,刷新页面,或者联系程序员')
+ // console.log(err);
+ // });
+ // },
+ })
+ },
+ destroyTinymce () {
+ const tinymce = window.tinymce.get(this.tinymceId)
+ if (this.fullscreen) {
+ tinymce.execCommand('mceFullScreen')
+ }
+
+ if (tinymce) {
+ tinymce.destroy()
+ }
+ },
+ setContent (value) {
+ window.tinymce.get(this.tinymceId).setContent(value)
+ },
+ getContent () {
+ window.tinymce.get(this.tinymceId).getContent()
+ },
+ imageSuccessCBK (arr) {
+ const _this = this
+ arr.forEach(v => {
+ window.tinymce.get(_this.tinymceId).insertContent(`<img class="wscnph" src="${v}" >`)
+ })
+ }
+ }
+}
+</script>
+
+<style lang="scss" scoped>
+.tinymce-container {
+ position: relative;
+ line-height: normal;
+}
+
+.tinymce-container {
+ ::v-deep {
+ .mce-fullscreen {
+ z-index: 10000;
+ }
+ }
+}
+
+.tinymce-textarea {
+ visibility: hidden;
+ z-index: -1;
+}
+
+.editor-custom-btn-container {
+ position: absolute;
+ right: 4px;
+ top: 4px;
+ /*z-index: 2005;*/
+}
+
+.fullscreen .editor-custom-btn-container {
+ z-index: 10000;
+ position: fixed;
+}
+
+.editor-upload-btn {
+ display: inline-block;
+}
+</style>
--
Gitblit v1.9.3