如何在JavaScript脚本中使用Laravel Blade的@money指令?
解决Laravel @money指令无法在JavaScript中使用的问题
这个问题我之前也碰到过,核心原因是Blade指令是服务器端渲染时执行的,而你的JavaScript变量是AJAX请求完成后才在客户端生成的,两者的执行时机完全错开,所以直接写@money(${paymentTotal})肯定无效。下面给你几个可行的解决方案:
方案1:把货币格式化逻辑封装成JavaScript函数
既然Blade的@money本质是服务器端的格式化规则,我们可以把相同的逻辑搬到客户端,写一个对应的JS函数,这样就能在AJAX回调里直接调用了。
实现步骤:
在你的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>在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把需要格式化的字段处理好,然后和原始数据一起返回给前端,前端直接使用即可。
实现步骤:
修改你的控制器方法,添加格式化后的字段:
<?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, ]); } }前端直接使用返回的格式化字符串:
$.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
相关产品推荐
相关产品推荐

