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同步变量
- 保留组件的
updatedImage方法不变 - 修改Blade中的JavaScript代码,替换原有的
var url = '{{ $url }}';:
// 用@entangle同步组件的$url到前端 const url = @entangle('url');
- 调整上传回调,直接使用同步后的变量:
@this.upload('image', image, () => { insertToEditor(url, quill); })
方案二:直接在上传回调中获取临时URL
- 无需依赖组件的
$url变量,修改Blade中的imageHandler函数:
function imageHandler(image) { @this.upload('image', image, () => { // 调用组件方法获取最新临时URL @this.call('getTemporaryUrl', (tempUrl) => { insertToEditor(tempUrl, quill); }); }) }
- 在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
相关产品推荐
相关产品推荐

