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

Livewire集成Quill Editor图片上传:临时URL无法插入编辑器求助

问题:Livewire + Quill编辑器无法插入图片临时URL

在Livewire中使用Quill编辑器,通过Livewire JavaScript Upload API上传编辑器内图片时,出现以下问题:

  • 图片可正常上传至livewire-tmp目录
  • 在编辑器外调用$image->temporaryUrl()或$url能正常获取临时URL并显示图片
  • 但无法将临时URL插入到Quill编辑器内

现有代码

Blade视图代码

<script>
    var quill = null;

    function selectLocalImage() {
        const input = document.createElement('input');
        input.setAttribute('type', 'file');
        input.click();

        // Listen upload local image and save to server
        input.onchange = () => {
            const file = input.files[0];

            // file type is only image.
            if (/^image\//.test(file.type)) {
                imageHandler(file);
            } else {
                console.warn('You could only upload images.');
            }
        };
    }

    function imageHandler(image) {
        var formData = new FormData();
        var url = '{{ $url }}';
        formData.append('image', image);
        formData.append('_token', '{{ csrf_token() }}');
        formData.append('pageId', '{{ $page->id }}');
        @this.upload('image', image, (uploadedFilename) => {
            insertToEditor(url, quill);
        })
    }

    function insertToEditor(url, editor) {
        // push image url to rich editor.
        const range = editor.getSelection();
        editor.insertEmbed(range.index, 'image', url);
    }

    $(document).ready(function() {
        var options = {
            modules: {
                syntax: true,
                toolbar: [
                    [{
                        'font': []
                    }, {
                        'size': []
                    }],
                    ['bold', 'italic', 'underline', 'strike'],
                    [{
                        'color': []
                    }, {
                        'background': []
                    }],
                    [{
                        'script': 'super'
                    }, {
                        'script': 'sub'
                    }],
                    [{
                        'header': '1'
                    }, {
                        'header': '2'
                    }, 'blockquote', 'code-block'],
                    [{
                        'list': 'ordered'
                    }, {
                        'list': 'bullet'
                    }, {
                        'indent': '-1'
                    }, {
                        'indent': '+1'
                    }],
                    ['direction', {
                        'align': []
                    }],
                    ['link', 'image', 'video', 'formula'],
                    ['clean']
                ]
            },
            placeholder: 'Content...',
            theme: 'snow'
        };
        quill = new Quill('#editor', options);

        quill.getModule('toolbar').addHandler('image', () => {
            selectLocalImage();
        });

        quill.on('text-change', function() {
            @this.set('pageBody', quill.root.innerHTML);
        });
    });
</script>

Livewire组件代码

public $image;
public $url;
public function updatedImage()
{
    if ($this->image) {
        $this->url = $this->image->temporaryUrl();
        // dd($this->url); <---- Showing temporary url
    }
}

问题原因

核心问题在于JavaScript中var url = '{{ $url }}';的执行时机:这行代码是页面首次渲染时生成的静态值,而Livewire上传图片后更新$url是异步操作,前端的url变量不会自动同步最新值,导致插入编辑器时使用的是初始空值或旧值。

解决方案

方案一:用Livewire的@entangle同步变量

  1. 保留组件的updatedImage方法不变
  2. 修改Blade中的JavaScript代码,替换原有的var url = '{{ $url }}';:
// 用@entangle同步组件的$url到前端
const url = @entangle('url');
  1. 调整上传回调,直接使用同步后的变量:
@this.upload('image', image, () => {
    insertToEditor(url, quill);
})

方案二:直接在上传回调中获取临时URL

  1. 无需依赖组件的$url变量,修改Blade中的imageHandler函数:
function imageHandler(image) {
    @this.upload('image', image, () => {
        // 调用组件方法获取最新临时URL
        @this.call('getTemporaryUrl', (tempUrl) => {
            insertToEditor(tempUrl, quill);
        });
    })
}
  1. 在Livewire组件中添加获取临时URL的方法:
public function getTemporaryUrl()
{
    return $this->image->temporaryUrl();
}

额外优化:处理Quill选中范围为空的情况

如果用户未选中编辑器位置,默认将图片插入到内容末尾,修改insertToEditor函数:

function insertToEditor(url, editor) {
    let range = editor.getSelection();
    // 无选中范围时,插入到内容末尾
    if (!range) {
        range = { index: editor.getLength() - 1 };
    }
    editor.insertEmbed(range.index, 'image', url);
}

内容的提问来源于stack exchange,提问作者Okan K

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 08:48:21