由于Magento 2已经发布了很长一段时间,而且基于该版本的新项目正在快速接近,作为开发人员,毫无疑问我们需要为这一挑战做好充分准备。

 

介绍

Magento 2中主导航的前端部分是用javascript代码构建的,其用于从移动设备转换到计算机悬停延迟计时的众多操作。在大多数情况下,默认方法就足够了,基本上可以满足所有的需求,但是有时候,在项目需要特定/定制方法的情况下,我们迟早会发现自己需要修改默认代码。

如果我们的项目需要对主导航javascript部分进行修改,首先我们需要了解该过程中涉及的一些基本文件架构和技术。

Magento 2使用Require JS(AMD或异步模块加载器)和jQuery/Query UI库作为创建系统当前存在的javascript组件的基础。

我将不再深入介绍requireJS,但如果您需要了解更多信息,可以查看我们的这篇博客此外,我强烈建议在使用Magento 2之前访问requireJS网站以获得AMD的基本要求和requireJS基本用法。

我将不再深入介绍requireJS,但是如果你需要更多的了解它,你可以查看我们关于这个主题的博文。同时,我强烈建议在与Magento 2合作之前,先访问requireJS网站,了解AMD的基础知识和requireJS的基本用法。

另一个重要的注意事项是jQuery UI widget factory用于提供简单的可扩展技术,类似于Magento 1中的旧原型类方法。如果您不熟悉jQuery UI widget,我强烈建议访问  使用 widget factory示例学习jQuery网站熟悉这个概念。

 

扩展默认值

负责导航菜单功能的主文件是位于[project_root]/lib/web/mage/以及其他默认js系统组件下的menu.js

现在,如果我们不想扩展或覆盖它,我们需要确保我们遵循这些步骤。

步骤1

使用我们的自定义内容正确扩展menu.js部分,第一步是映射我们的js文件,以便系统加载它而不是默认文件。
Magento使用requirejs-config.js文件成功映射系统上的js组件。首先,重要的是要知道requirejs-config.js的位置它可以放在几个层面上。

所有requireJS配置将按以下顺序合并和执行:

  • 模块级别
  • 主题模块级别(父主题)
  • 主题模块级别(当前主题)
  • 主题级别(父主题)
  • 主题级别(当前主题)

让我们看一个实际的例子。默认文件是menu.js,我们想用我们的自定义文件替换它。请注意,我仍然会将默认的menu.js文件作为依赖项加载

我们需要创建将替换menu.js文件的文件,我们将其命名为menu-custom.js并将其放在[current_theme]/web/js/ 目录下。

步骤2

接下来,我们需要创建requirejs-config.js文件并将其放在[current_theme]/root目录下。这样我们就可以成功映射文件以替换默认文件。请参阅以下示例:

var config = {
    "map": {
        "*": {
            "menu": "js/menu-custom"
        }
 
    }
};

要确定该过程是否成功,请确保在加载新文件时检入开发人员工具。

步骤3

我们不想扩展默认功能,这就是jQuery widget factory发挥作用的地方。我们将以下代码放在我们新创建的menu-custom.js文件中

define([
    'jquery',
    'jquery/ui',
    'mage/menu'],
    function($){
        $.widget('magease.menu', $.mage.menu, {
            _init: function () {
                alert("I'm Magease");
            },
            toggle: function () {
                alert("I'm Magease");
            }
    });
    return $.magease.menu;
    });

我们从上面的例子中可以看到,我们使用require js来定义我们的依赖关系。第一个是jquery,第二个是jquery/ui,最后一个是mage/menu。
这意味着我们的脚本在完全加载之前不会加载,因为我们的逻辑依赖于它。

我们正在扩展默认的$.mage.menu的自定义小部件名为magease.menu,在本例中为了本教程,我扩展了两个方法,_inittoggleToggle方法负责切换智能手机和平板电脑上的导航,而_init方法负责组件初始化。

默认menu.js中的原始切换方法示例

toggle: function () {
            if ($('html').hasClass('nav-open')) {
                $('html').removeClass('nav-open');
                setTimeout(function () {
                    $('html').removeClass('nav-before-open');
                }, 300);
            } else {
                $('html').addClass('nav-before-open');
                setTimeout(function () {
                    $('html').addClass('nav-open');
                }, 42);
            }
        },

 

覆盖文件

在某些情况下(尽管在相对较少的情况下),您会发现自己可以完全覆盖菜单逻辑(创建自定义导航)。在这种特定情况下,我们可以应用步骤1步骤2并在menu-custom.js文件中创建自定义导航逻辑