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

Laravel 8项目:如何在jQuery/JavaScript中编写Blade语法?

解决Laravel 8中AJAX加载更多复用Blade模板逻辑的方案

方案一:后端返回渲染好的HTML片段(最推荐)

这个方案能100%复用原有Blade模板的逻辑,避免前后端逻辑不一致,维护成本最低。

  1. 抽取产品局部视图
    把单个产品的渲染逻辑抽成独立的Blade局部视图,比如resources/views/partials/product-item.blade.php,直接复用原有的@if、自定义函数等语法:
<div class="product-item">
    <img src="{{ $product->image_url }}" alt="{{ $product->name }}">
    <h3>{{ $product->getTranslation('name', app()->getLocale()) }}</h3>
    @if($product->discount > 0)
        <span class="price discounted">${{ home_base_price($product) }}</span>
        <span class="original-price">${{ $product->original_price }}</span>
    @else
        <span class="price">${{ home_base_price($product) }}</span>
    @endif
</div>
  1. 修改AJAX接口返回HTML
    调整控制器的加载更多方法,查询产品后渲染局部视图为HTML字符串,返回给前端:
public function loadMore(Request $request)
{
    $page = $request->input('page', 1);
    $products = Product::paginate(10, ['*'], 'page', $page);
    
    // 批量渲染产品视图
    $html = '';
    foreach ($products as $product) {
        $html .= view('partials/product-item', compact('product'))->render();
    }
    
    return response()->json([
        'html' => $html,
        'has_more' => $products->hasMorePages()
    ]);
}
  1. 前端追加HTML
    AJAX请求成功后,直接把返回的HTML追加到页面容器中:
$('#load-more-btn').click(function() {
    const $btn = $(this);
    const currentPage = $btn.data('page') || 1;
    
    $.ajax({
        url: '/products/load-more',
        type: 'GET',
        data: { page: currentPage + 1 },
        beforeSend: () => $btn.prop('disabled', true),
        success: function(response) {
            $('.products-container').append(response.html);
            
            if (!response.has_more) {
                $btn.hide();
            } else {
                $btn.data('page', currentPage + 1);
            }
        },
        complete: () => $btn.prop('disabled', false)
    });
});

方案二:前端模拟Blade逻辑(临时应急)

如果不想改动后端接口,可以把Blade中的逻辑同步到前端JS里实现,但需保证前后端逻辑完全一致,否则会出现渲染差异。

  1. 同步自定义函数逻辑
    把后端的home_base_price函数逻辑复制到JS中:
function homeBasePrice(product) {
    if (product.discount > 0) {
        return (product.original_price * (100 - product.discount) / 100).toFixed(2);
    }
    return product.original_price.toFixed(2);
}
  1. 前端拼接HTML时模拟Blade语法
    AJAX获取JSON数据后,用JS的条件判断、函数调用模拟Blade的@if、{{ }}语法:
$('#load-more-btn').click(function() {
    const $btn = $(this);
    const currentPage = $btn.data('page') || 1;
    const appLocale = $('html').attr('lang'); // 从页面获取当前语言
    
    $.ajax({
        url: '/products/load-more-json',
        type: 'GET',
        data: { page: currentPage + 1 },
        beforeSend: () => $btn.prop('disabled', true),
        success: function(response) {
            let html = '';
            response.products.forEach(product => {
                html += '<div class="product-item">';
                html += `<img src="${product.image_url}" alt="${product.name}">`;
                // 模拟多语言名称渲染
                html += `<h3>${product.translations[appLocale].name}</h3>`;
                // 模拟@if条件判断
                if (product.discount > 0) {
                    html += `<span class="price discounted">$${homeBasePrice(product)}</span>`;
                    html += `<span class="original-price">$${product.original_price.toFixed(2)}</span>`;
                } else {
                    html += `<span class="price">$${homeBasePrice(product)}</span>`;
                }
                html += '</div>';
            });
            $('.products-container').append(html);
            
            if (!response.has_more) {
                $btn.hide();
            } else {
                $btn.data('page', currentPage + 1);
            }
        },
        complete: () => $btn.prop('disabled', false)
    });
});

注意:后续后端修改home_base_price或多语言逻辑时,必须同步修改前端代码,否则会出现数据不一致问题。

方案三:使用Laravel组件(进阶优化)

如果项目中已经使用组件,可以把产品渲染逻辑封装为Blade组件,本质和局部视图类似,但更符合组件化开发规范:

  1. 创建产品组件
php artisan make:component ProductItem

编辑resources/views/components/product-item.blade.php:

<div class="product-item">
    <img src="{{ $product->image_url }}" alt="{{ $product->name }}">
    <h3>{{ $product->getTranslation('name', app()->getLocale()) }}</h3>
    @if($product->discount > 0)
        <span class="price discounted">${{ home_base_price($product) }}</span>
        <span class="original-price">${{ $product->original_price }}</span>
    @else
        <span class="price">${{ home_base_price($product) }}</span>
    @endif
</div>
  1. 控制器中渲染组件
public function loadMore(Request $request)
{
    $page = $request->input('page', 1);
    $products = Product::paginate(10, ['*'], 'page', $page);
    
    $html = '';
    foreach ($products as $product) {
        $html .= view('components.product-item', compact('product'))->render();
    }
    
    return response()->json([
        'html' => $html,
        'has_more' => $products->hasMorePages()
    ]);
}

前端代码和方案一完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 12:02:09