基于Livewire实现Statamic移动端动态调整条目显示数量
问题:根据屏幕尺寸动态调整Livewire组件的文章显示条数
首次使用Livewire开发,现有一个Statamic Livewire组件用于展示博客文章集合,默认显示9条,但移动端(屏幕宽度<768px)需要调整为3条,尝试用JavaScript连接Livewire未成功,求实现方案。
组件代码如下:
<?php namespace App\Livewire; use Livewire\Component; use Statamic\Facades\Collection; class FilterCollection extends Component { public $taxonomyField; public $taxonomySlug; public $collectionName; public $viewName = 'collection'; public $offset = 0; public $limit = 9; public $q; public $defaultSortBy = 'desc'; public $sortBy; public $cards = [ 'blog_articles' => '_blog-list-card', ]; public function render() { $newEntries = Collection::find($this->collectionName) ->queryEntries() ->where('published', 1) ->orderBy('date', $this->defaultSortBy) ->offset($this->offset) ->limit($this->limit); if (!empty($this->taxonomySlug)) { $newEntries->whereTaxonomy($this->taxonomyField . '::' . $this->taxonomySlug); } if (!empty($this->q)) { $newEntries->where(function ($query) { $query->where('title', 'like', '%' . $this->q . '%') ->orWhere('article_summary', 'like', '%' . $this->q . '%') ->orWhere('page_builder', 'like', '%' . $this->q . '%');; }); } return view('livewire.filter-' . $this->viewName, ['entries' => $newEntries]); } public function filterCollection($taxonomySlug) { $this->taxonomySlug = $taxonomySlug; } public function loadMore() { $this->limit += $this->limit; } public function mount($collectionName, $taxonomyField = 'articles_tags', $q = null) { $this->collectionName = $collectionName ?? 'articles'; $this->taxonomyField = $taxonomyField; $this->q = $q; } }
解决方案
1. 给组件添加响应式状态与更新方法
修改组件类,添加移动端判断属性,并实现根据屏幕状态更新limit的方法:
<?php namespace App\Livewire; use Livewire\Component; use Statamic\Facades\Collection; class FilterCollection extends Component { // 标记是否为移动端 public $isMobile = false; // 基础显示条数,用于统一加载增量 private $baseLimitDesktop = 9; private $baseLimitMobile = 3; public $taxonomyField; public $taxonomySlug; public $collectionName; public $viewName = 'collection'; public $offset = 0; public $limit = 9; public $q; public $defaultSortBy = 'desc'; public $sortBy; public $cards = [ 'blog_articles' => '_blog-list-card', ]; // 根据屏幕状态更新显示条数 public function updateLimitBasedOnScreen($isMobile) { $this->isMobile = $isMobile; // 重置为对应设备的基础条数,避免loadMore后的值混乱 $this->limit = $isMobile ? $this->baseLimitMobile : $this->baseLimitDesktop; } // 修改loadMore逻辑:按对应设备的基础条数增量加载 public function loadMore() { $addAmount = $this->isMobile ? $this->baseLimitMobile : $this->baseLimitDesktop; $this->limit += $addAmount; } public function render() { $newEntries = Collection::find($this->collectionName) ->queryEntries() ->where('published', 1) ->orderBy('date', $this->defaultSortBy) ->offset($this->offset) ->limit($this->limit); if (!empty($this->taxonomySlug)) { $newEntries->whereTaxonomy($this->taxonomyField . '::' . $this->taxonomySlug); } if (!empty($this->q)) { $newEntries->where(function ($query) { $query->where('title', 'like', '%' . $this->q . '%') ->orWhere('article_summary', 'like', '%' . $this->q . '%') ->orWhere('page_builder', 'like', '%' . $this->q . '%');; }); } return view('livewire.filter-' . $this->viewName, ['entries' => $newEntries]); } public function filterCollection($taxonomySlug) { $this->taxonomySlug = $taxonomySlug; } public function mount($collectionName, $taxonomyField = 'articles_tags', $q = null) { $this->collectionName = $collectionName ?? 'articles'; $this->taxonomyField = $taxonomyField; $this->q = $q; } }
2. 在视图中添加JavaScript监听窗口变化
在组件对应的视图文件(livewire.filter-collection.blade.php)底部添加以下代码,监听窗口resize事件并同步状态到Livewire后端:
<script> // 防抖函数,避免窗口拖动时频繁触发请求 function debounce(func, wait) { let timeout; return function() { const context = this; const args = arguments; clearTimeout(timeout); timeout = setTimeout(() => func.apply(context, args), wait); }; } // 检查当前是否为移动端 function checkIsMobile() { return window.innerWidth < 768; } // 页面初始化时同步一次屏幕状态 document.addEventListener('livewire:initialized', () => { @this.updateLimitBasedOnScreen(checkIsMobile()); }); // 监听窗口resize事件,防抖后更新状态 window.addEventListener('resize', debounce(() => { @this.updateLimitBasedOnScreen(checkIsMobile()); }, 300)); </script>
说明
- 防抖函数设置300毫秒延迟,减少不必要的Livewire请求
- 初始化时自动检测屏幕尺寸并设置对应显示条数
- 窗口大小变化时,自动重置显示条数为对应设备的基础值,保证移动端始终从3条开始加载
- 修改后的
loadMore方法,移动端每次加载3条,桌面端每次加载9条,逻辑更符合场景需求
内容的提问来源于stack exchange,提问作者D Silva
相关产品推荐
相关产品推荐

