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

Laravel 8 解决Quilljs编辑器内容存库失败及回显问题的方法

Quill编辑器内容存取实现方案

你遇到的拿不到编辑器内容的核心原因是:Quill 初始化后只是在指定的div容器上做富文本渲染,这个div不属于表单的原生可提交元素,所以表单默认提交时根本不会把div里的内容带到后端,自然通过$request取不到值。要实现内容存库、回显,只需要做两层简单适配就行。

第一步:调整Blade模板的表单结构

原来的代码缺少和编辑器一一对应的真实可提交字段,需要给每个Quill渲染容器搭配一个隐藏input,让这个input承担表单值提交的作用。改造后的模板示例:

<!-- 确保所有编辑器区块都在form标签内部 -->
<form method="POST" action="{{ route('test.store') }}">
    @csrf
    <div class="card-body">
        <div class="row">
            <div class="col-md-12">
                <div class="form-group">
                    <label for="test">Information</label>
                    <!-- Quill 富文本渲染容器 -->
                    <div id="test" style="height: 200px;"></div>
                    <!-- 对应编辑器的隐藏提交字段,name 和后端接收字段、数据库字段名完全保持一致 -->
                    <input type="hidden" name="test" id="test_input">
                </div>
            </div>
            <!-- 剩下两个编辑器按照同样逻辑,分别添加独立渲染容器 + 对应name的隐藏input即可 -->
        </div>
    </div>
    <button type="submit" class="btn btn-primary">提交</button>
</form>

第二步:初始化Quill并做内容同步

引入Quill的样式与脚本后,在页面底部编写初始化逻辑,实现两个核心能力:编辑器内容变化时实时同步到隐藏input、表单提交前做一次全量同步兜底,避免内容漏传。
对应的JS代码:

// 配置编辑器映射关系,key是Quill容器的id,value是对应隐藏input的id
const editorMap = {
    'test': 'test_input',
    // 剩下两个编辑器按格式补全,比如 'intro': 'intro_input', 'detail': 'detail_input'
};

// 批量初始化Quill实例
const editorInstances = {};
Object.keys(editorMap).forEach(containerId => {
    const editor = new Quill(`#${containerId}`, {
        theme: 'snow',
        // 按自身需求配置工具栏选项
        modules: {
            toolbar: [
                [{ 'header': [1, 2, false] }],
                ['bold', 'italic', 'underline'],
                ['image', 'code-block']
            ]
        }
    });
    editorInstances[containerId] = editor;

    // 监听编辑器内容变化,实时同步到对应的隐藏input
    editor.on('text-change', () => {
        const inputDom = document.getElementById(editorMap[containerId]);
        // 存轻量的展示用HTML结构,直接取编辑器渲染的HTML就行
        inputDom.value = editor.root.innerHTML;
        // 如果需要后续在同一个Quill实例里精确编辑、保留所有格式位置,换成Quill原生Delta结构存储:
        // inputDom.value = JSON.stringify(editor.getContents());
    });
});

// 表单提交前做兜底同步,避免最后一次内容修改因为事件触发时序问题漏传
document.querySelector('form').addEventListener('submit', () => {
    Object.keys(editorMap).forEach(containerId => {
        const editor = editorInstances[containerId];
        const inputDom = document.getElementById(editorMap[containerId]);
        inputDom.value = editor.root.innerHTML;
    });
});

注意:数据库对应字段要设置为TEXT或者LONGTEXT类型,不能用短字符串类型,否则长内容会被截断无法正常存储。

第三步:后端控制器适配

原有控制器逻辑只需要做少量修正即可正常接收到编辑器内容:

  1. 修正原代码里的语法错误:$request-validate少了箭头操作符,要写成$request->validate()才能正常运行。
  2. 确保验证规则的字段名和隐藏input的name完全匹配。
  3. 对应模型的$fillable属性里加上编辑器对应的字段,避免批量赋值被拦截。
public function store(Request $request)
{
    $validated = $request->validate([
        'test' => 'nullable|string',
        // 其他两个编辑器字段按照同样规则补全
    ]);

    Testtable::create($validated);

    return redirect()->route('home')->with('success', 'You successfully add a new Product!');
}

第四步:已存储内容的回显

打开编辑页面时,把数据库存储的内容传给前端,在Quill初始化完成后填充到对应容器即可:

  1. 控制器返回编辑视图时,把模型数据传给视图:
public function edit(Testtable $testtable)
{
    return view('edit', compact('testtable'));
}
  1. 视图内把初始内容注入到JS中,避免跨域或格式问题:
<script>
const initialContent = {
    'test': @json(old('test', $testtable->test ?? ''))
    // 其他字段按同样逻辑补全
};
</script>
  1. 在Quill初始化完成后,补充内容填充逻辑:
Object.keys(editorMap).forEach(containerId => {
    const editor = editorInstances[containerId];
    const content = initialContent[containerId];
    if (!content) return;

    // 如果存的是HTML结构,用这个方法填充
    editor.clipboard.dangerouslyPasteHTML(content);

    // 如果存的是Delta结构化数据,换这个方法填充
    // const delta = JSON.parse(content);
    // editor.setContents(delta);
});

常见踩坑提醒

  • 不要直接把Quill的渲染容器当成表单提交字段,它只是展示用DOM,本身没有表单值属性。
  • 不要把Quill的工具栏单独拆分到渲染容器外部,否则会出现工具条和编辑区分离的问题。
  • 确保form标签内没有遗漏@csrf指令,否则提交会触发419鉴权错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 23:15:03