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

Laravel多对多场景下,如何用AJAX点击分类列出对应文章?

没问题,我来帮你实现点击分类菜单用AJAX加载对应文章的功能,咱们一步步来操作:

实现分类菜单AJAX加载文章的完整方案

1. 修正并完善Blade分类菜单模板

首先补全你提供的模板代码,同时添加AJAX所需的标识和交互基础:

<ul class="Categories__Menu"> 
  @foreach($categories->take(6) as $category) 
    <!-- 动态高亮当前选中的分类 -->
    <li class="{{ request('category') == $category->id ? 'active' : '' }}"> 
      <!-- 阻止默认跳转,添加分类ID标识和点击类 -->
      <a href="javascript:void(0)" class="category-link" data-category-id="{{ $category->id }}">
        {{ $category->name }}
      </a>
    </li> 
  @endforeach
</ul>

<!-- 文章列表容器,给ID方便后续替换内容 -->
<div id="posts-container">
  <!-- 初始加载最新10篇文章,后续AJAX会替换这里的内容 -->
  @include('posts.partials.posts_list', ['posts' => $latestPosts])
</div>

2. 编写AJAX交互代码

这里提供两种常用方案,选你项目在用的即可:

方案一:原生JavaScript

在页面底部添加这段脚本:

<script>
const categoryLinks = document.querySelectorAll('.category-link');
const postsContainer = document.getElementById('posts-container');

categoryLinks.forEach(link => {
  link.addEventListener('click', async function() {
    // 更新分类菜单的选中状态
    document.querySelectorAll('.Categories__Menu li').forEach(li => li.classList.remove('active'));
    this.parentElement.classList.add('active');

    const categoryId = this.dataset.categoryId;

    try {
      // 发送请求到后端接口
      const response = await fetch(`/category/posts/${categoryId}`);
      if (!response.ok) throw new Error('请求失败');
      const html = await response.text();
      // 替换文章列表内容
      postsContainer.innerHTML = html;
    } catch (error) {
      console.error('加载文章出错:', error);
      postsContainer.innerHTML = '<p>加载文章失败,请稍后重试</p>';
    }
  });
});
</script>

方案二:jQuery(如果项目引入了jQuery)

<script>
$(document).ready(function() {
  $('.category-link').on('click', function() {
    const categoryId = $(this).data('category-id');

    // 更新选中状态
    $('.Categories__Menu li').removeClass('active');
    $(this).parent().addClass('active');

    // 发送AJAX请求
    $.ajax({
      url: `/category/posts/${categoryId}`,
      type: 'GET',
      success: function(html) {
        $('#posts-container').html(html);
      },
      error: function() {
        $('#posts-container').html('<p>加载文章失败,请稍后重试</p>');
      }
    });
  });
});
</script>

3. 配置后端路由

在routes/web.php中添加处理分类文章请求的路由:

use App\Http\Controllers\PostController;

Route::get('/category/posts/{category}', [PostController::class, 'getPostsByCategory'])->name('category.posts');

4. 实现控制器方法

在app/Http/Controllers/PostController.php中添加获取分类文章的方法:

use App\Models\Category;

public function getPostsByCategory(Category $category)
{
    // 通过多对多关联查询该分类下的最新10篇文章
    $posts = $category->posts()->latest()->take(10)->get();

    // 返回文章列表的局部视图
    return view('posts.partials.posts_list', compact('posts'));
}

5. 创建文章列表局部视图

新建resources/views/posts/partials/posts_list.blade.php,把文章展示逻辑抽出来复用:

@foreach($posts as $post)
  <div class="post-item">
    <h3>{{ $post->title }}</h3>
    <p>{{ Illuminate\Support\Str::limit($post->content, 100) }}</p>
    <span class="post-date">{{ $post->created_at->format('Y-m-d') }}</span>
  </div>
@endforeach

@if($posts->isEmpty())
  <p>该分类下暂无文章</p>
@endif

额外检查:确保模型关联正确

确认Category和Post模型的多对多关联已经定义:

  • Category模型:
public function posts()
{
    return $this->belongsToMany(Post::class, 'category_post');
}
  • Post模型:
public function categories()
{
    return $this->belongsToMany(Category::class, 'category_post');
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:31:38