由于Magento 2已经发布了很长一段时间,而且基于该版本的新项目正在快速接近,作为开发人员,毫无疑问我们需要为这一挑战做好充分准备。
介绍
Magento 2中主导航的前端部分是用javascript代码构建的,其用于从移动设备转换到计算机悬停延迟计时的众多操作。在大多数情况下,默认方法就足够了,基本上可以满足所有的需求,但是有时候,在项目需要特定/定制方法的情况下,我们迟早会发现自己需要修改默认代码。
如果我们的项目需要对主导航javascript部分进行修改,首先我们需要了解该过程中涉及的一些基本文件架构和技术。
Magento 2使用Require JS(AMD或异步模块加载器)和jQuery/Query UI库作为创建系统当前存在的javascript组件的基础。
我将不再深入介绍requireJS,但如果您需要了解更多信息,可以查看我们的Magento2 使用requireJS添加自定义javascript。此外,我强烈建议在使用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,在本例中为了本教程,我扩展了两个方法,_init和toggle。Toggle方法负责切换智能手机和平板电脑上的导航,而_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文件中创建自定义导航逻辑。