Magento 2.4.5 分层导航库存数量范围滑块筛选模块开发咨询
Magento 2.4.5 库存数量范围滑块分层导航模块开发步骤
1. 创建基础模块结构
在app/code下创建模块目录Vendor/InventorySlider,添加核心配置文件:
registration.php:
<?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'Vendor_InventorySlider', __DIR__ );
etc/module.xml:
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Vendor_InventorySlider" setup_version="1.0.0"> <sequence> <module name="Magento_Catalog"/> <module name="Magento_CatalogSearch"/> </sequence> </module> </config>
执行bin/magento setup:upgrade启用模块。
2. 注册库存数量筛选器
创建库存筛选器模型,直接复用价格滑块的核心逻辑,创建Model/Layer/Filter/Inventory.php:
<?php namespace Vendor\InventorySlider\Model\Layer\Filter; class Inventory extends \Magento\Catalog\Model\Layer\Filter\Price { protected $_requestVar = 'stock_qty'; public function __construct( \Magento\Catalog\Model\Layer\Filter\ItemFactory $filterItemFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Catalog\Model\Layer $layer, \Magento\Catalog\Model\Layer\Filter\Item\DataBuilder $itemDataBuilder, \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency, array $data = [] ) { parent::__construct($filterItemFactory, $storeManager, $layer, $itemDataBuilder, $priceCurrency, $data); $this->_filterField = 'qty'; $this->setLabel(__('Stock Quantity')); } protected function _renderRangeLabel($from, $to) { if ($from == 0) { return __('Up to %1', $to); } elseif ($to == PHP_INT_MAX) { return __('From %1', $from); } else { return __('%1 - %2', $from, $to); } } }
3. 配置DI加载筛选器
在etc/di.xml中配置,让分层导航加载库存筛选器:
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <type name="Magento\Catalog\Model\Layer\FilterList"> <arguments> <argument name="filters" xsi:type="array"> <item name="inventory" xsi:type="object">Vendor\InventorySlider\Model\Layer\Filter\Inventory</item> </argument> </arguments> </type> <type name="Vendor\InventorySlider\Model\Layer\Filter\Inventory"> <arguments> <argument name="range" xsi:type="number">10</argument> <!-- 自定义滑块步长 --> </arguments> </type> </config>
4. 前端模板与滑块组件
复制价格滑块模板结构,创建view/frontend/templates/layer/filter/inventory.phtml:
<?php /** @var $block \Vendor\InventorySlider\Model\Layer\Filter\Inventory */ ?> <div class="filter-slider stock-qty-slider" data-role="stock-qty-filter"> <div class="filter-title"> <?= $block->escapeHtml(__('Stock Quantity')) ?> </div> <div class="filter-content"> <div class="slider-container"> <input type="hidden" id="stock-qty-min" value="<?= $block->getMinValue() ?>" /> <input type="hidden" id="stock-qty-max" value="<?= $block->getMaxValue() ?>" /> <div id="stock-qty-slider"></div> <div class="slider-values"> <input type="text" id="stock-qty-from" data-role="from-input" value="<?= $block->getCurrentMin() ?>" /> <span class="separator">-</span> <input type="text" id="stock-qty-to" data-role="to-input" value="<?= $block->getCurrentMax() ?>" /> <button type="button" class="action apply" data-role="apply-filter"> <?= $block->escapeHtml(__('Apply')) ?> </button> </div> </div> </div> </div> <script type="text/x-magento-init"> { "[data-role=stock-qty-filter]": { "Vendor_InventorySlider/js/slider": { "min": <?= $block->getMinValue() ?>, "max": <?= $block->getMaxValue() ?>, "from": <?= $block->getCurrentMin() ?>, "to": <?= $block->getCurrentMax() ?>, "sliderSelector": "#stock-qty-slider", "fromInputSelector": "#stock-qty-from", "toInputSelector": "#stock-qty-to", "applyButtonSelector": "[data-role=apply-filter]", "url": "<?= $block->escapeUrl($block->getUrl('*/*/*', ['_current' => true, '_use_rewrite' => true])) ?>" } } } </script>
创建前端JS组件view/frontend/web/js/slider.js,复用滑块交互逻辑:
define([ 'jquery', 'jquery/ui', 'mage/url' ], function ($) { 'use strict'; $.widget('vendor.stockQtySlider', { options: { min: 0, max: 100, from: 0, to: 100, sliderSelector: '', fromInputSelector: '', toInputSelector: '', applyButtonSelector: '', url: '' }, _create: function () { var self = this; $(this.options.sliderSelector).slider({ range: true, min: this.options.min, max: this.options.max, values: [this.options.from, this.options.to], slide: function (event, ui) { $(self.options.fromInputSelector).val(ui.values[0]); $(self.options.toInputSelector).val(ui.values[1]); }, change: function (event, ui) { self._applyFilter(ui.values[0], ui.values[1]); } }); $(this.options.applyButtonSelector).on('click', function () { var from = $(self.options.fromInputSelector).val(), to = $(self.options.toInputSelector).val(); self._applyFilter(from, to); }); }, _applyFilter: function (from, to) { var url = new URL(this.options.url); url.searchParams.set('stock_qty', from + '-' + to); window.location.href = url.toString(); } }); return $.vendor.stockQtySlider; });
5. 布局关联模板
创建view/frontend/layout/catalog_category_view.xml和view/frontend/layout/catalogsearch_result_index.xml,绑定筛选器模板:
<?xml version="1.0"?> <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"> <body> <referenceBlock name="catalog.leftnav"> <referenceBlock name="inventory_filter"> <action method="setTemplate"> <argument name="template" xsi:type="string">Vendor_InventorySlider::layer/filter/inventory.phtml</argument> </action> </referenceBlock> </referenceBlock> </body> </page>
6. 测试与优化
- 清理缓存:
bin/magento cache:clean && bin/magento cache:flush - 生产模式编译代码:
bin/magento setup:di:compile - 验证分类/搜索页的滑块显示、拖动筛选功能是否正常
- 按需调整滑块步长(修改
di.xml的range参数)、样式文案
内容的提问来源于stack exchange,提问作者Ram Pratap Singh Gour
相关产品推荐
相关产品推荐

