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

如何将数据库值绑定到Chart.js并在Livewire中正常显示图表

问题分析与修复方案

核心问题

你的代码存在两个关键问题:

  1. 变量赋值错误:在foreach循环中创建了局部变量$subs,而非给组件的公共属性$this->subs赋值,导致组件的$subs始终为空数组,视图无法获取数据。
  2. 性能问题:每次循环单独查询Grape模型,造成N+1数据库查询,影响效率。

修复后的Component代码

<?php
namespace App\Livewire\Charts;
use Livewire\Component;
use App\Models\Wine;
use App\Models\WineGrape;

class GrapeCharts extends Component
{
    public $wines;
    public $subs = [];

    public function mount($wine_id)
    {
        $this->wines = Wine::find($wine_id);
        // 预加载Grape关联,避免N+1查询
        $wineGrapes = WineGrape::where('wine_id', $wine_id)->with('grape')->get();
        
        $this->subs = [];
        foreach ($wineGrapes as $wg) {
            // 直接给组件的$subs属性追加元素
            $this->subs[] = [
                'Grape' => $wg->grape->grapename,
                'Value' => $wg->amount
            ];
        }
    }

    public function render()
    {
        return view('livewire.charts.grape-charts');
    }
}

额外配置:WineGrape模型关联

在App\Models\WineGrape.php中添加关联方法,实现预加载:

public function grape()
{
    return $this->belongsTo(Grape::class);
}

修复后的View代码

<style type="text/css">
    .ChartBox {
        height: 600px;
    }
</style>
<div class="row">
    <div class="ChartBox col-6" wire:ignore>
        <canvas id="myChart"></canvas>
    </div>
</div>

@assets
<script type="text/javascript" src="{{ asset('assets/js/chart.min.js') }}"></script>
@endassets

@script
<script>
    let chartInstance = null;

    function renderChart() {
        const ctx = document.getElementById('myChart');
        // 用Blade的@json直接传递初始数据,比$wire.subs更稳定
        const subs = @json($subs);

        if (!subs.length) return;

        const labels = subs.map(item => item.Grape);
        const values = subs.map(item => item.Value);

        // 销毁旧图表实例,避免重复创建
        if (chartInstance) {
            chartInstance.destroy();
        }

        chartInstance = new Chart(ctx, {
            type: 'pie',
            data: {
                labels: labels,
                datasets: [{
                    label: '%',
                    data: values,
                    borderWidth: 1
                }]
            },
            options: {
                responsive: true
            }
        });
    }

    // 页面加载时初始化图表
    document.addEventListener('DOMContentLoaded', renderChart);
    // Livewire组件更新时重新渲染图表
    document.addEventListener('livewire:update', renderChart);
</script>
@endscript

关键优化点

  1. 正确赋值组件属性:使用$this->subs[]替代局部变量,确保数据被存入组件的公共属性,能传递到视图。
  2. Eloquent关联预加载:通过with('grape')一次性加载所有关联的葡萄数据,减少数据库查询次数。
  3. 图表实例管理:添加旧实例销毁逻辑,避免重复创建图表导致的冲突;同时监听Livewire更新事件,确保数据变化时图表同步刷新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 13:40:13