You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3下tinymce-vue ^4.0.4对接laravel-filemanager点击确认报错如何解决

问题排查与解决方案

核心问题原因

  • 响应式变量作用域错误:你将tinymce ref声明在onMounted回调内部,外部的file_picker_callback函数无法访问该变量,调用tinymce.activeEditor时会触发未定义报错。
  • TinyMCE实例获取方式错误:@tinymce/tinymce-vue 4.x适配Vue3的版本,需要通过ref的getEditor()方法获取编辑器实例,不能直接调用全局tinymce.activeEditor。
  • 缺少文件选择结果监听:laravel-filemanager选中文件后会通过postMessage传递文件地址,你没有监听该事件,无法将选中的文件路径回传给TinyMCE的文件选择回调。

修复后的完整代码

<template>
    <div>
        <editor
            ref="tinymceRef"
            name="tinymce"
            class="form-control my-editor"
            api-key="api-key"
            v-model="body"
            :init="{
                path_absolute : '/',
                selector: 'textarea.my-editor',
                relative_urls: false,
                plugins: [
                    'advlist autolink lists link image charmap print preview hr anchor pagebreak',
                    'searchreplace wordcount visualblocks visualchars code fullscreen',
                    'insertdatetime media nonbreaking save table directionality',
                    'emoticons template paste textpattern'
                ],
                toolbar: 'insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image media',
                file_picker_callback : filePickerCallback
            }"
        />
    </div>   
</template>
<script>
import { onMounted, ref, onUnmounted } from 'vue';
import Editor from '@tinymce/tinymce-vue';
export default {
    name: 'EventsForm',
    components: {
        Editor
    },
    setup(props, context) {
        const tinymceRef = ref(null);
        const body = ref('');
        // 存储TinyMCE的文件选择回调
        let currentFileCallback = null;

        // 监听laravel-filemanager返回的文件选择结果
        const handleMessage = (e) => {
            if (e.origin !== window.location.origin) return;
            if (e.data && e.data.field_name && currentFileCallback) {
                currentFileCallback(e.data.url);
                currentFileCallback = null;
            }
        }

        onMounted(() => {
            window.addEventListener('message', handleMessage);
        })

        onUnmounted(() => {
            window.removeEventListener('message', handleMessage);
        })

        const filePickerCallback = (callback, value, meta) => {
            currentFileCallback = callback;
            const x = window.innerWidth || document.documentElement.clientWidth || document.getElementsByTagName('body')[0].clientWidth;
            const y = window.innerHeight || document.documentElement.clientHeight || document.getElementsByTagName('body')[0].clientHeight;

            let cmsURL = window.location.origin + '/laravel-filemanager?field_name=' + meta.fieldname;
            cmsURL = meta.filetype == 'image' ? cmsURL + "&type=Images" : cmsURL + "&type=Files";

            // 通过ref获取编辑器实例调用弹窗
            const editor = tinymceRef.value.getEditor();
            editor.windowManager.openUrl({
                url: cmsURL,
                title: 'Filemanager',
                width: x * 0.8,
                height: y * 0.8,
                resizable: "yes",
                close_previous: "no"
            });
        }

        return { tinymceRef, body, filePickerCallback }
    }
}
</script>

关键修改说明

  1. 将tinymce ref移到setup顶层声明,重命名为tinymceRef避免和全局TinyMCE变量混淆,补充了双向绑定需要的body响应式变量。
  2. 新增currentFileCallback变量存储TinyMCE传入的文件选择回调,监听message事件接收laravel-filemanager返回的文件地址后触发回调回传路径。
  3. 调用tinymceRef.value.getEditor()获取编辑器实例,替代原来的全局tinymce.activeEditor调用。
  4. 组件卸载时移除message事件监听,避免内存泄漏。

内容的提问来源于stack exchange,提问作者Jérémie Chazelle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 11:15:03