Magento2中使用RequireJS调用jQuery:能否避免重复声明?
在Magento2区块中通过RequireJS复用jQuery的方案
问题描述
我在Magento2的区块中需要通过RequireJS使用jQuery,现在每个函数开头都要重复声明require(['jquery', 'jquery/ui']),想请教有没有只声明一次的实现方式?
HTML代码示例
<div class="mainMenu"> <div style="background-color: black;color: white;"> <div onClick="openCategory(1)">MENU 1</div> <div onClick="openCategory(2)">MENU 2</div> <div onClick="openCategory(3)">MENU 3</div> </div> </div> <div onClick="openMainMenu()"> OUVRIR MENU </div>
PHTML脚本代码示例
<script> let menu require(['jquery', 'jquery/ui'], function($){ $.ajax({ url: "https://catfact.ninja/fact", context: document.body }).done(function(value) { menu = [] menu.forEach(element => { $('.mainMenu').append("<div class='menuContainer menuNumber" + element.id + "'>" + element.name + "</div>") }); }); }); function openMainMenu(){ require(['jquery', 'jquery/ui'], function($){ $('.mainMenu').show() }); } function openCategory(categoryNumber){ require(['jquery', 'jquery/ui'], function($){ console.log($('.menuNumber' + categoryNumber).css("visibility", "visible")); }); } </script>
解决方案
方案1:将所有逻辑包裹在单个RequireJS回调中
把所有函数和初始化逻辑都放在同一个require的回调函数里,只声明一次jQuery依赖,同时避免全局污染,符合Magento的最佳实践:
<script> require(['jquery', 'jquery/ui'], function($){ let menu; // 初始化AJAX请求 $.ajax({ url: "https://catfact.ninja/fact", context: document.body }).done(function(value) { menu = []; menu.forEach(element => { $('.mainMenu').append("<div class='menuContainer menuNumber" + element.id + "'>" + element.name + "</div>"); }); }); // 定义菜单相关函数 function openMainMenu(){ $('.mainMenu').show(); } function openCategory(categoryNumber){ console.log($('.menuNumber' + categoryNumber).css("visibility", "visible")); } // 绑定事件(替代内联onClick) $('.mainMenu [onClick]').each(function() { const categoryNum = $(this).attr('onClick').match(/\d+/)[0]; $(this).off('click').on('click', function() { openCategory(categoryNum); }); }); $('div:contains("OUVRIR MENU")').off('click').on('click', openMainMenu); }); </script>
方案2:将jQuery暴露到全局(应急可用,不推荐)
如果必须保留内联事件,可以在全局作用域中暴露$,但注意这可能和其他脚本冲突,不符合Magento模块化规范:
<script> let $; require(['jquery', 'jquery/ui'], function(jQuery){ $ = jQuery; // 把jQuery赋值给全局变量$ let menu; $.ajax({ url: "https://catfact.ninja/fact", context: document.body }).done(function(value) { menu = []; menu.forEach(element => { $('.mainMenu').append("<div class='menuContainer menuNumber" + element.id + "'>" + element.name + "</div>"); }); }); }); function openMainMenu(){ $('.mainMenu').show(); } function openCategory(categoryNumber){ console.log($('.menuNumber' + categoryNumber).css("visibility", "visible")); } </script>
方案3:使用自定义RequireJS模块(Magento规范推荐方式)
把菜单逻辑封装成自定义RequireJS模块,后续在区块中直接引用即可:
- 在主题或模块目录下创建
js/menu-handler.js文件:
define(['jquery', 'jquery/ui'], function($){ return { init: function() { let menu; $.ajax({ url: "https://catfact.ninja/fact", context: document.body }).done(function(value) { menu = []; menu.forEach(element => { $('.mainMenu').append("<div class='menuContainer menuNumber" + element.id + "'>" + element.name + "</div>"); }); }); // 绑定事件 $('.mainMenu .menu-item').on('click', function() { const categoryNum = $(this).data('category'); this.openCategory(categoryNum); }); $('.open-menu-btn').on('click', this.openMainMenu); }, openMainMenu: function() { $('.mainMenu').show(); }, openCategory: function(categoryNumber) { console.log($('.menuNumber' + categoryNumber).css("visibility", "visible")); } }; });
- 修改HTML,移除内联事件,添加类名和数据属性:
<div class="mainMenu"> <div style="background-color: black;color: white;"> <div class="menu-item" data-category="1">MENU 1</div> <div class="menu-item" data-category="2">MENU 2</div> <div class="menu-item" data-category="3">MENU 3</div> </div> </div> <div class="open-menu-btn"> OUVRIR MENU </div>
- 在PHTML中引用模块并初始化:
<script> require(['js/menu-handler'], function(menuHandler){ menuHandler.init(); }); </script>
内容的提问来源于stack exchange,提问作者kevin richard
相关产品推荐
相关产品推荐

