You need to enable JavaScript to run this app. Laravel Livewire动态可加行工时表失焦自动更新合计行实现方法
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Livewire动态可加行工时表失焦自动更新合计行实现方法

Livewire实现工时表失焦逐列自动合计方案

核心逻辑说明

全程不需要引入jQuery,依托Livewire原生的双向绑定、事件钩子机制即可实现「输入框失焦→同步数据到组件→自动逐列累加→视图自动更新合计值」的完整流程,和现有代码结构完全兼容。

组件层(ShowTimesheet.php)改造步骤

  • 统一$entries数组的字段结构,确保每行的周一到周日字段键名固定(如mon/tue/wed/thu/fri/sat/sun),方便循环累加。
  • 新增独立属性存储每日列的合计值,避免临时计算导致的视图刷新问题。
  • 封装通用的列合计计算方法,统一处理空值转数值、累加逻辑。
  • 利用Livewire的更新钩子,在任意行的工时数据变化时自动触发计算,无需在每个输入框单独绑定事件。
namespace App\Http\Controllers\Livewire;

use Livewire\Component;

class ShowTimesheet extends Component
{
    // 动态工时行数组
    public array $entries = [];
    // 每日列合计值
    public array $dayTotals = [
        'mon' => 0,
        'tue' => 0,
        'wed' => 0,
        'thu' => 0,
        'fri' => 0,
        'sat' => 0,
        'sun' => 0,
    ];

    // 初始化页面加载时的逻辑
    public function mount()
    {
        // 从数据库读取已存的工时行时,赋值给$entries后直接计算一次合计
        $this->calculateColumnTotals();
    }

    // 新增动态行
    public function addEntry()
    {
        $this->entries[] = [
            'job_id' => null,
            'worktype_id' => null,
            'mon' => 0,
            'tue' => 0,
            'wed' => 0,
            'thu' => 0,
            'fri' => 0,
            'sat' => 0,
            'sun' => 0,
        ];
    }

    // 逐列计算所有行的工时总和
    protected function calculateColumnTotals()
    {
        // 先重置合计值,避免旧数据残留
        $this->dayTotals = array_map(fn() => 0, $this->dayTotals);
        foreach ($this->entries as $row) {
            foreach ($this->dayTotals as $dayKey => $originalValue) {
                // 兼容空字符串、非数值类型的输入,统一转成浮点型累加
                $this->dayTotals[$dayKey] += (float)($row[$dayKey] ?? 0);
            }
        }
    }

    // 钩子:只要$entries数组内的任意字段被更新,就自动触发合计计算
    public function updatedEntries()
    {
        $this->calculateColumnTotals();
    }

    public function render()
    {
        return view('livewire.timesheet');
    }
}

视图层(timesheet.blade.php)改造步骤

  • 调整每个动态行的工时输入框的绑定规则,使用*.blur*修饰符实现「输入完成、点击离开输入框时才同步数据到后端」的触发逻辑,避免每敲一个字符就发起不必要的请求。
  • 在表格底部的合计区域直接输出预先计算好的$dayTotals值,不需要手动操作DOM更新文本。
<table>
  <thead>
    <tr>
      <th>关联任务</th>
      <th>工作类型</th>
      <th>周一</th>
      <th>周二</th>
      <th>周三</th>
      <th>周四</th>
      <th>周五</th>
      <th>周六</th>
      <th>周日</th>
    </tr>
  </thead>
  <tbody>
    @foreach($entries as $index => $entry)
    <tr>
      <td>
        <select wire:model="entries.{{ $index }}.job_id">
          <!-- 任务选项 -->
        </select>
      </td>
      <td>
        <select wire:model="entries.{{ $index }}.worktype_id">
          <!-- 工作类型选项 -->
        </select>
      </td>
      <!-- 天工时输入框,用.blur修饰符实现失焦才同步 -->
      <td><input type="number" step="0.5" wire:model.blur="entries.{{ $index }}.mon"></td>
      <td><input type="number" step="0.5" wire:model.blur="entries.{{ $index }}.tue"></td>
      <td><input type="number" step="0.5" wire:model.blur="entries.{{ $index }}.wed"></td>
      <td><input type="number" step="0.5" wire:model.blur="entries.{{ $index }}.thu"></td>
      <td><input type="number" step="0.5" wire:model.blur="entries.{{ $index }}.fri"></td>
      <td><input type="number" step="0.5" wire:model.blur="entries.{{ $index }}.sat"></td>
      <td><input type="number" step="0.5" wire:model.blur="entries.{{ $index }}.sun"></td>
    </tr>
    @endforeach
    <!-- 底部合计行,对应标注的红色区域 -->
    <tr class="total-row">
      <td colspan="2" class="text-right font-bold">列合计</td>
      <td>{{ number_format($dayTotals['mon'], 1) }}</td>
      <td>{{ number_format($dayTotals['tue'], 1) }}</td>
      <td>{{ number_format($dayTotals['wed'], 1) }}</td>
      <td>{{ number_format($dayTotals['thu'], 1) }}</td>
      <td>{{ number_format($dayTotals['fri'], 1) }}</td>
      <td>{{ number_format($dayTotals['sat'], 1) }}</td>
      <td>{{ number_format($dayTotals['sun'], 1) }}</td>
    </tr>
  </tbody>
</table>
<button wire:click="addEntry">新增工时行</button>

关键注意点

  • 触发逻辑完全匹配需求:.wire:model.blur是Livewire提供的原生修饰符,专门在输入框失焦时才将最新值同步到组件,和“输入完成、点击离开才计算”的逻辑完全一致,不会出现输入过程中频繁请求的问题。
  • 无需手动操作DOM:Livewire的响应式渲染机制会在后端合计值更新后,自动把视图里对应位置的数字替换成最新值,不需要写任何jQuery或原生JS的DOM操作代码。
  • 边界兼容:计算环节统一将空值、字符串类型的输入转成浮点型,避免出现累加结果为NaN的问题。
  • 若后续新增删除行的逻辑,只要删除操作修改了$entries数组,updatedEntries钩子会自动触发重新计算,不需要额外修改合计逻辑。
  • 相比jQuery实现方式,这套逻辑不需要手动绑定多个输入框的事件、不需要手动遍历DOM取单元格值、不需要手动修改合计文本,和动态新增/删除行的逻辑完全打通。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.08 09:15:03