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

Laravel Livewire复选框更新时未正确移除选项价格计算问题

问题:Livewire复选框价格累加异常(取消后重新勾选仍持续累加)

复现代码

前端复选框渲染:

@foreach ($product->productOptions as $productOption)
  <input class="form-check-input" wire:model.live="productOptionPriceId" type="checkbox" value="{{ $productOption->id }}">
@endforeach

Livewire组件updated方法:

public function updated()
{
   
    $basePrice = (float)$this->basePrice;
    $selectedSizePrice = (float)$this->selectedSizePrice;
    if ($this->productSizeId > 0) {
        $model = ProductSize::select('price')->findOrFail($this->productSizeId);
        $this->selectedSizePrice = number_format($model->price, 2);
    }
    if (count($this->productOptionPriceId) > 0) {
        $option = ProductOption::select('price')->where('id', $this->productOptionPriceId)->get();
        foreach ($option as $item) {
            $this->selectedOptionPrice[] = number_format($item->price, 2);
        }
        $selectedOptionPrice = array_sum($this->selectedOptionPrice);
    } else {
        $selectedOptionPrice = 0;
    }
    $this->totalPrice = $basePrice + $selectedSizePrice + $selectedOptionPrice;

}

问题原因

  1. selectedOptionPrice数组未重置:每次执行updated方法时,都往$this->selectedOptionPrice数组追加新值,取消选项后旧数据仍留在数组中,再次勾选时重复累加。
  2. 多选查询逻辑错误:用where('id', $this->productOptionPriceId)查询多选选项,productOptionPriceId是数组时该语法不生效,应使用whereIn。
  3. 价格存储类型问题:用number_format返回字符串类型的价格,数组求和时可能出现异常。
  4. 尺寸未选择时未重置价格:取消尺寸选择后,selectedSizePrice仍保留旧值,导致总价计算错误。

修复方案

1. 组件属性初始化

确保绑定复选框的变量为数组类型:

public $productOptionPriceId = [];
public $selectedOptionPrice = [];

2. 修正updated方法

public function updated()
{
    $basePrice = (float)$this->basePrice;
    $selectedSizePrice = 0;

    // 处理尺寸价格:选中则赋值,未选中则重置为0
    if ($this->productSizeId > 0) {
        $model = ProductSize::select('price')->findOrFail($this->productSizeId);
        $selectedSizePrice = (float)$model->price;
    }

    // 关键:每次计算前重置选项价格数组,清空旧数据
    $this->selectedOptionPrice = [];
    $selectedOptionPrice = 0;

    // 处理选项价格:多选查询用whereIn
    if (!empty($this->productOptionPriceId)) {
        $options = ProductOption::select('price')->whereIn('id', $this->productOptionPriceId)->get();
        foreach ($options as $item) {
            $this->selectedOptionPrice[] = (float)$item->price; // 存储浮点型价格,避免字符串求和问题
        }
        $selectedOptionPrice = array_sum($this->selectedOptionPrice);
    }

    // 计算最终总价,如需保留两位小数可在此格式化
    $this->totalPrice = $basePrice + $selectedSizePrice + $selectedOptionPrice;
}

关键修复点

  • 每次进入updated方法先重置$this->selectedOptionPrice = [],彻底清除旧的选项价格数据。
  • 用whereIn替代where查询多个选中的选项,符合多选场景的数据库查询语法。
  • 统一用浮点型处理价格,避免字符串类型导致的求和异常,如需展示格式化后的价格,可在最后对totalPrice进行number_format处理。
  • 新增尺寸未选择时的价格重置逻辑,确保总价计算准确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 22:08:17