vue3使用Tinymce编辑器
首先去官网获取免费的key 获取地址,需要注册登录。 获取后还须将使用该编辑器的域名添加到 这里,默认有只有localhost。
在项目中获取依赖 npm install "@tinymce/tinymce-vue"
在页面或组件中引用 import Editor from "@tinymce/tinymce-vue";
封装成组件
<template>
<div class="tinymce-editor">
<Editor
apiKey="获取的key"
:init="editorInit"
:value="contentValue"
/>
</div>
</template>
<script setup> import { ref, watch, shallowRef } from "vue"; import Editor from "@tinymce/tinymce-vue"; const props = defineProps({ modelValue: { type: String, default: "", }, height: { type: Number, default: 500, }, plugins: { type: [String, Array], default: "preview image link media table help", }, toolbar: { type: [String, Array], default: "undo redo | bold italic underline strikethrough | fontselect fontsizeselect formatselect | image media link | alignleft aligncenter alignright alignjustify | numlist bullist | forecolor backcolor removeformat | charmap emoticons | fullscreen preview save", }, }); const emit = defineEmits(["update:modelValue", "change", "blur"]); const contentValue = ref(props.modelValue); const editorInstance = ref(null); const showEditor = ref(false); // 编辑器初始化配置 const editorInit = { language: "zh-CN", height: props.height, plugins: props.plugins, toolbar: props.toolbar, branding: false, promotion: false, elementpath: false, content_style: "body {font-size: 14px }", skin: "oxide", icons: "default", toolbar_mode: "wrap", contextmenu: "link image table", powerpaste_word_import: "clean", powerpaste_html_import: "clean", paste_data_images: true, images_upload_handler: handleImageUpload, file_picker_callback: handleFilePicker, setup: (editor) => { console.log("editor:", editor); editorInstance.value = editor; editor.on("init", () => { // 设置初始内容 showEditor.value = true; if (props.modelValue) { editor.setContent(props.modelValue); } }); // 监听内容变化事件 editor.on("input", () => { const content = editor.getContent(); console.log("input:", content); contentValue.value = content; emit("update:modelValue", content); }); // 监听内容变化事件(更全面) editor.on("change", () => { const content = editor.getContent(); console.log("内容变化:", content); contentValue.value = content; emit("update:modelValue", content); }); }, }; // 处理图片上传 function handleImageUpload(blobInfo, progress) { return new Promise((resolve, reject) => { // 将 blob 转换为 File 对象 const file = new File([blobInfo.blob()], blobInfo.filename(), { type: blobInfo.blob().type, }); console.log("上传图片:", file); }); } // 处理视频上传 function handleFilePicker(callback, value, meta) { if (meta.filetype === "media") { // 视频上传逻辑 const input = document.createElement("input"); input.type = "file"; input.accept = "video/*"; input.onchange = (e) => { const file = e.target.files[0]; // 上传视频到服务器 }; input.click(); } } // 初始化 TinyMCE const editorRef = shallowRef(); // 监听外部值变化 watch( () => props.modelValue, (val) => { if (val !== contentValue.value) { console.log("外部值变化:", val); contentValue.value = val || ""; console.log(editorInstance.value, "editorInstance"); if (editorInstance.value) { editorInstance.value.setContent(val || ""); } } } ); defineExpose({ editorRef, }); </script>
父组件中引用
<Editor :modelValue="content" @update:modelValue="editorChange" /> import Editor from "@/components/Editor.vue"; const content = ref(''); const editorChange = (val) => { console.log(val, "val"); };
代码中有上传图片和视频的方法,只用在对应代码位置写上传到服务器逻辑即可。
若遇到编辑器弹框被Element Plus弹框盖住的情况,可在app.vue中设置
.tox {
z-index: 3050 !important;
}

浙公网安备 33010602011771号