Javascript mixins的使用

更新

JavaScript mixins

JavaScript中的 mixin 是指在对象或类中混合其他对象或类的属性和方法,以便重用代码。在JavaScript中,您可以通过将多个对象合并为一个对象来创建混合对象。

在Magento 2中,mixins是用于在模块中重写或扩展其他模块、插件或组件的属性和方法的一种方法。Mixins是一个对象,其中包含要添加或修改的属性和方法。在Magento 2中,这些属性和方法被称为目标组件。

Magento 2 mixins的使用方式如下:

  1. 创建一个mixin对象,其中包含要添加或修改的属性和方法。
  2. 定义一个目标组件,即要修改或扩展的组件。
  3. 使用requirejs-config.js文件将mixin对象与目标组件关联起来。

例如,以下代码是将自定义JavaScript文件添加到Magento 2主题中的示例:

define([
    'jquery'
], function ($) {
    'use strict';

    var myMixin = {
        myFunction: function() {
            console.log('This is my custom function.');
        }
    };

    return function (target) {
        return target.extend(myMixin);
    };
});

在这个例子中,我们定义了一个名为myMixin的mixin对象,其中包含一个名为myFunction的自定义函数。然后,我们使用target.extend方法将mixin对象与目标组件关联起来。最后,我们使用requirejs-config.js文件将mixin和目标组件关联起来。

总之,在JavaScript中,mixins是用于将多个对象或类合并为一个对象或类以便于重用代码的技术。在Magento 2中,mixins是用于重写或扩展其他组件的属性和方法的一种方法。

Mixin scope

一个模块的混合器的范围取决于它在视图目录下的目录位置。这使得你可以在Magento的特定区域内锁定组件实例。

下表将目录位置映射到mixin所影响的应用程序区域。

| view/frontend | Storefront | | ---------------- | ------------------------------------------------------------ | | view/adminhtml | Admin panel | | view/base | All areas (unless a specific frontend or adminhtml entry exists) |

Mixin files

位置

混合器是位于 web/js 目录下的 JavaScript 文件,位于一个特定区域的目录下。mixin 文件可以嵌套在更多的目录下,只要这些目录是在 web/js 下。

格式

在 Magento 中,mixin 被写成一个 AMD 模块,返回一个回调函数。这个函数接受一个目标组件(模块)作为参数并返回一个模块。

这允许你返回一个新的目标组件实例,并在应用中使用之前附上你的修改。

例子

扩展UI组件

下面是一个 mixin 的例子,它用一个函数扩展了目标组件,为一个列元素引入了一个新的 blockVisibility 属性。

文件: ExampleCorp/Sample/view/base/web/js/columns-mixin.js


define(function () {
    'use strict';

    var mixin = {

        /**
         *
         * @param {Column} elem
         */
        isDisabled: function (elem) {
            return elem.blockVisibility || this._super();
        }
    };

    return function (target) { // target == Result that Magento_Ui/.../columns returns.
        return target.extend(mixin); // new result that all other modules receive
    };
});


扩展 jQuery Widget

下面是一个 mixin 的例子,它扩展了 modal widget 的功能,为 modal 关闭添加确认。

文件: ExampleCorp/Sample/view/base/web/js/modal-widget-mixin.js


define(['jquery'], function ($) {
    'use strict';

    var modalWidgetMixin = {
        options: {
            confirmMessage: "Please, confirm modal closing."
        },

        /**
         * Added confirming for modal closing
         *
         * @returns {Element}
         */
        closeModal: function () {
            if (!confirm(this.options.confirmMessage)) {
                return this.element;
            }

            return this._super();
        }
    };

    return function (targetWidget) {
        // Example how to extend a widget by mixin object
        $.widget('mage.modal', targetWidget, modalWidgetMixin); // the widget alias should be like for the target widget

        return $.mage.modal; //  the widget by parent alias should be returned
    };
});

Extend JS Object

JS混合器的另一个用例是当基本的 Javascript 文件返回一个对象时。在这种情况下,一个封装器是必要的。下面的例子混合器扩展了步骤导航器对象的 setHash 方法。这里,this._super() 是基础方法,需要时可以调用。

文件: ExampleCorp/Sample/view/frontend/web/js/model/step-navigator-mixin.js


define([
    'mage/utils/wrapper'
], function (wrapper) {
    'use strict';

    return function (stepNavigator) {
        stepNavigator.setHash = wrapper.wrapSuper(stepNavigator.setHash, function (hash) {
            this._super(hash);
            // add extended functionality here or modify method logic altogether
        });

        return stepNavigator;
    };
});

Extend JS Function

下面是一个 mixin 的例子,它为 proceed to checkout 函数添加了额外的功能。

文件: ExampleCorp/Sample/view/frontend/web/js/proceed-to-checkout-mixin.js


define([
    'mage/utils/wrapper'
], function (wrapper) {
    'use strict';

    return function (proceedToCheckoutFunction) {
        return wrapper.wrap(proceedToCheckoutFunction, function (originalProceedToCheckoutFunction, config, element) {
            originalProceedToCheckoutFunction(config, element);
            // add extended functionality here
        });
    };
});

Declaring a mixin 声明一个混合器

混合器是在 requirejs-config.js 配置文件的 mixins 属性中声明的。该文件必须在混合器定义的同一区域的特定目录中创建。

requirejs-config.js 中的 mixins 配置使用它们的路径将目标组件与混合器联系起来。

例子 下面是一个 requirejs-config.js 文件的例子,它将前面例子中定义的 columns-mixin、modal-widget-mixin、step-navigator-mixin 和 proceed-to-checkout-mixin 混合变量添加到网格列组件、modal widget、step navigator 对象和 proceed to checkout 函数中。

文件: ExampleCorp/Sample/view/base/requirejs-config.js


var config = {
 config: {
     mixins: {
         'Magento_Ui/js/grid/controls/columns': {
             'ExampleCorp_Sample/js/columns-mixin': true
         },
         'Magento_Ui/js/modal/modal': {
             'ExampleCorp_Sample/js/modal-widget-mixin': true
         },
         'Magento_Checkout/js/model/step-navigator': {
             'ExampleCorp_Sample/js/model/step-navigator-mixin': true
         },
         'Magento_Checkout/js/proceed-to-checkout': {
             'ExampleCorp_Sample/js/proceed-to-checkout-mixin': true
         }
     }
 }
};


重写一个mixin

一个混合器可以被另一个混合器所覆盖,但不能单独禁用。

例子

文件:ExampleCorp/CartFix/view/base/requirejs-config.js


var config = {
    config: {
        mixins: {
            'Magento_Catalog/js/catalog-add-to-cart': {
                'ExampleCorp_Sample/js/original-add-to-cart-mixin': false,
                'ExampleCorp_CartFix/js/overwritten-add-to-cart-mixin': true
            }
        }
    }
};

在这种情况下,ExampleCorp_Sample/js/original-add-to-cart-mixin 被 ExampleCorp_CartFix/js/overwritten-add-to-cart-mixin 覆盖了。请确保将 origin 模块作为被覆盖模块的依赖关系(使用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="ExampleCorp_CartFix" setup_version="0.0.1">
        <sequence>
            <module name="ExampleCorp_Sample" />
        </sequence>
    </module>
</config>

在对 requirejs-config.js 配置进行修改后,你必须清理缓存并重新生成静态文件。

Magento中的混合器实例 以下是Magento_CheckoutAgreement模块中声明和定义修改结账行为的混合器的文件列表。