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

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模块,后续在区块中直接引用即可:

  1. 在主题或模块目录下创建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"));
        }
    };
});
  1. 修改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>
  1. 在PHTML中引用模块并初始化:
<script>
    require(['js/menu-handler'], function(menuHandler){
        menuHandler.init();
    });
</script>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 06:45:38