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

如何在JavaScript脚本中使用Laravel Blade的@money指令?

解决Laravel @money指令无法在JavaScript中使用的问题

这个问题我之前也碰到过,核心原因是Blade指令是服务器端渲染时执行的,而你的JavaScript变量是AJAX请求完成后才在客户端生成的,两者的执行时机完全错开,所以直接写@money(${paymentTotal})肯定无效。下面给你几个可行的解决方案:

方案1:把货币格式化逻辑封装成JavaScript函数

既然Blade的@money本质是服务器端的格式化规则,我们可以把相同的逻辑搬到客户端,写一个对应的JS函数,这样就能在AJAX回调里直接调用了。

实现步骤:

  1. 在你的Blade模板里,添加一个全局的JavaScript格式化函数(可以放在页面底部或者<head>里):

    <script>
    // 根据你Laravel Trait里的格式化规则来写,这里假设是印尼盾格式(千分位用.,小数位用,,保留2位小数)
    function formatMoney(amount) {
        // 如果需要和Laravel的本地化完全一致,可以从配置里取分隔符
        const decimalSeparator = '{{ config('app.decimal_separator', ',') }}';
        const thousandSeparator = '{{ config('app.thousand_separator', '.') }}';
        const decimalPlaces = 2;
    
        // 先转成保留指定小数位的字符串,再替换分隔符
        return amount.toFixed(decimalPlaces)
            .replace('.', decimalSeparator)
            .replace(/\B(?=(\d{3})+(?!\d))/g, thousandSeparator);
    }
    </script>
    

    如果你想用更优雅的本地化实现,也可以用浏览器原生的Intl.NumberFormat:

    <script>
    // 替换成你的本地化标识,比如id-ID对应印尼盾,zh-CN对应人民币
    const currencyFormatter = new Intl.NumberFormat('id-ID', {
        style: 'currency',
        currency: 'IDR',
        minimumFractionDigits: 2,
    });
    
    function formatMoney(amount) {
        return currencyFormatter.format(amount);
    }
    </script>
    
  2. 在AJAX的回调里调用这个函数:

    $.ajax({
        method: 'get',
        url: `${url}/${due_date}`,
    }).done((data) => {
        let { totalInterest, totalPrincipal, paymentTotal, due_date, loanNumber, borrowerFullname } = data;
        $('#simulation-table').show();
        // 直接调用JS的格式化函数
        $('#totalbayar').append(formatMoney(paymentTotal));
    }).fail((err) => {
        console.log(err, 'error coy');
    });
    

方案2:服务器端返回已格式化好的货币字符串

另一种更简单的方式是,在AJAX接口的控制器里,直接用你的Money Trait把需要格式化的字段处理好,然后和原始数据一起返回给前端,前端直接使用即可。

实现步骤:

  1. 修改你的控制器方法,添加格式化后的字段:

    <?php
    
    namespace App\Http\Controllers;
    
    use App\Traits\MoneyFormatter; // 引入你的货币格式化Trait
    use Illuminate\Http\Request;
    
    class SimulationController extends Controller
    {
        use MoneyFormatter;
    
        public function getSimulation($due_date)
        {
            // 这里是你原本获取数据的逻辑
            $paymentTotal = 10000;
            $totalInterest = 500;
            $totalPrincipal = 9500;
            // ...其他逻辑
    
            // 生成格式化后的字段
            $formattedPaymentTotal = $this->formatMoney($paymentTotal); // 调用Trait里的方法
            $formattedTotalInterest = $this->formatMoney($totalInterest);
    
            // 返回包含原始数据和格式化后数据的JSON
            return response()->json([
                'totalInterest' => $totalInterest,
                'formattedTotalInterest' => $formattedTotalInterest,
                'totalPrincipal' => $totalPrincipal,
                'paymentTotal' => $paymentTotal,
                'formattedPaymentTotal' => $formattedPaymentTotal,
                'due_date' => $due_date,
                'loanNumber' => $loanNumber,
                'borrowerFullname' => $borrowerFullname,
            ]);
        }
    }
    
  2. 前端直接使用返回的格式化字符串:

    $.ajax({
        method: 'get',
        url: `${url}/${due_date}`,
    }).done((data) => {
        let { formattedPaymentTotal, due_date, loanNumber, borrowerFullname } = data;
        $('#simulation-table').show();
        // 直接用服务器端已经格式化好的字符串
        $('#totalbayar').append(formattedPaymentTotal);
    }).fail((err) => {
        console.log(err, 'error coy');
    });
    

为什么原来的写法无效?

再给你理清楚核心原因:

  • Blade的@money指令是服务器端执行的:当浏览器请求页面时,Laravel会先解析所有Blade指令,把@money($xxx)转换成对应的格式化字符串,然后才把完整的HTML发送到客户端。
  • 你的paymentTotal是客户端JS变量:只有当AJAX请求完成后,这个变量才会被赋值,此时Blade早就执行完了,根本无法感知到这个JS变量的存在。

所以直接混合两种不同执行时机的代码,自然不会得到预期的结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 22:52:48