请注意,本文编写于 371 天前,最后修改于 371 天前,其中某些信息可能已经过时。
前言
使用方式不通过api-key
,而是直接使用,但是报错,因为Nuxt3默认为ssr模式,即服务端渲染,TinyMce-Vue无法兼容服务端渲染。
报错
[Vue Router warn]: uncaught error during route navigation:
ReferenceError: navigator is not defined
at D:\project\cpa-read-nuxt3-h5\node_modules\tinymce\tinymce.js:961:23
at Object.<anonymous> (D:\project\cpa-read-nuxt3-h5\node_modules\tinymce\tinymce.js:31513:3)
at Module._compile (node:internal/modules/cjs/loader:1241:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1295:10)
at Module.load (node:internal/modules/cjs/loader:1091:32)
at Module._load (node:internal/modules/cjs/loader:938:12)
at cjsLoader (node:internal/modules/esm/translators:284:17)
at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:234:7)
at ModuleJob.run (node:internal/modules/esm/module_job:217:25)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
原因
服务端渲染无法访问游览器的navigator
解决方法
参考:stackoverflow的描述,使用nuxt3的ClientOnly
加载tinymce组件
ClientOnly:https://nuxt.com.cn/docs/api/components/client-only
源码
关于源码之前的文章有介绍
CustomTinymce.vue
<template>
<div style="width: 100%">
<editor v-model="editorValue" :init="initOptions"></editor>
</div>
</template>
<script setup>
import {onBeforeUnmount, onMounted, ref, toRefs, unref, watch} from "vue";
import 'tinymce/tinymce';
import Editor from '@tinymce/tinymce-vue';
import 'tinymce/models/dom';
// 外觀
import 'tinymce/skins/ui/oxide/skin.css';
import 'tinymce/themes/silver';
// Icon
import 'tinymce/icons/default';
// 語言包
import 'tinymce-i18n/langs6/zh-Hans.js';
// 引入插件
// 源代码
import 'tinymce/plugins/code'
import 'tinymce/plugins/image'
const emit = defineEmits(['update:modelValue']);
const props = defineProps({
modelValue: {
type: String,
default: '',
},
plugins: {
type: [String, Array],
default: 'code image',
},
toolbar: {
type: [String, Array],
default: 'undo redo | styles | bold italic image cut copy paste forecolor removeformat code',
},
});
const initOptions = ref({
language: 'zh-Hans',
height: 500,
skin: false,
menubar: false,
content_css: false,
plugins: props.plugins,
toolbar: props.toolbar,
// 禁止url自动转化处理
convert_urls: false,
toolbar_mode: 'sliding',
...setPasteOption(),
...setImageOption()
})
const { modelValue } = toRefs(props);
const editorValue = ref(modelValue.value);
watch(modelValue, (newValue) => {
editorValue.value = newValue;
});
watch(editorValue, (newValue) => {
emit('update:modelValue', newValue);
});
onMounted(() => {
console.log('初始化tinymce')
})
/*
* 图片上传 配置项
* */
function setImageOption() {
return {
images_upload_handler: (blobInfo, progress) => new Promise(async (resolve, reject) => {
// console.log(blobInfo.blobUri())
const formData = new FormData();
formData.append('file', blobInfo.blob(), blobInfo.filename());
// console.log(formData)
const res = {}
console.log(res)
if (res.code === 200 && res.data.url) {
resolve(res.data.url)
} else {
reject({ message: '上传图片失败', remove: true })
}
})
}
}
/*
* 复制粘贴插件 配置项
* https://www.tiny.cloud/docs/tinymce/6/copy-and-paste/
* */
function setPasteOption() {
return {
paste_preprocess: (editor, args) => {
console.log(args.content);
},
// paste_remove_styles_if_webkit: false,
/*
* 此选项允许您指定在 WebKit 中粘贴时要保留的样式。WebKit 有一个怪癖,
* 它将获取元素的所有计算 CSS 属性并将它们添加到编辑器中的 span 中。由于大多数用户不希望在整个文档中添加随机跨度,
* 因此我们需要手动清理它,直到修复错误。此选项默认为'none'但可以设置为'all'或要保留的特定样式列表。
* */
paste_webkit_styles: 'color'
}
}
</script>
<style lang="less" scoped>
</style>
<style>
.tox-tinymce-aux {
z-index: 3000 !important;
}
</style>
tinymce.vue
使用组件
<script setup lang="ts">
const data = reactive({
tinymce: ''
})
</script>
<template>
<ClientOnly fallback-tag="span" fallback="加载评论中...">
<custom-tinymce v-model="data.tinymce"/>
</ClientOnly>
</template>
<style scoped lang="scss">
</style>
end
最后结果如图所示
还有一种方式是按照tinymce官网文档使用,申请apikey加载,尝试了存在加载中文js报错问题,未再继续研究。
2 条评论
好兄弟写的很好,帮了很大忙。谢谢了
不客气