如何切换产品颜色实现sku也变化?

默认使用的可配置产品实现颜色卡变化,但是显示的SKU并没有变化。
如何实现点击Magento2可配置产品的色卡,实现SKU变化?
我使用的是最新的Magento 2.1.9

以下方法适用版本为Magento 2.1.9以下,由于2.1.10以后图片切换方法有所变化,故不适用

首先,需要修改后端,让后端的数据传给前端
找到 magento/module-swatches/Helper/Data.php这个文件,找到方法 private function getAllSizeImages(ModelProduct $product, $imageFile),如果是Magento2.1.9,大概在该文件的324行.
增加一行值为 ‘sku’ => $product->getSku()
这样整个方法看起来是这样的:

private function getAllSizeImages(ModelProduct $product, $imageFile) {
 return [
     'large' => $this->imageHelper->init($product, 'product_page_image_large')
         ->constrainOnly(true)->keepAspectRatio(true)->keepFrame(false)
         ->setImageFile($imageFile)
         ->getUrl(),
     'medium' => $this->imageHelper->init($product, 'product_page_image_medium')
         ->constrainOnly(true)->keepAspectRatio(true)->keepFrame(false)
         ->setImageFile($imageFile)
         ->getUrl(),
     'small' => $this->imageHelper->init($product, 'product_page_image_small')
         ->setImageFile($imageFile)
         ->getUrl(),
         'sku' => $product->getSku(),
 ];}    

修改这个方法之后,后端会传给前端json文件中增加SKU这个字段和值.

接着,我们修改前端的js文件,让我们把SKU展示到页面上,首先找到文件view/frontend/web/js/swatch-renderer.js
找到方法: _ProductMediaCallback,然后我们增加代码:

for(var pro in response){
if ($("[itemprop='"+pro+"']").length>0) {
	$("[itemprop='"+pro+"']").html(response[pro]);
 }
}

然后保存退回到Magento的根目录执行命令:

bin/magento ma:en && bin/magento ca:cl && chmod -R 777 . && chown -R www:www .  && bin/magento se:di:co &&bin/magento se:st:de && chmod -R 777 . && chown -R www:www . && bin/magento ma:dis

等待刷新缓存的命令执行完成后,刷新页面,检查功能是否实现.

如果您使用Magento 2.1.10和Magento 2.2.1以上版本

您可以尝试使用这个模块:
https://github.com/andering/magento2-configurable-dynamic

希望可以帮助到你.

1 Like

####如果您使用Magento 2.1.10和Magento 2.2.1以上版本,又想使用手动修改,请参考下面的方法:
该版本之后,Magento修改了图片加载的方式,之前的版本是使用ajax方式加载,之后就不是了,所以上面的方法不适用。
1.加载sku信息到页面中

app/code/Mage/Bugfix/Plugin/Magento/ConfigurableProduct/Block/Product/View/Type/Configurable.php

<?php
namespace Mage\Bugfix\Plugin\Magento\ConfigurableProduct\Block\Product\View\Type;

class Configurable
{

public function afterGetJsonConfig(
    \Magento\ConfigurableProduct\Block\Product\View\Type\Configurable $subject,
    $result
) {

    $jsonResult = json_decode($result, true);

    $jsonResult['skus'] = [];
    foreach ($subject->getAllowProducts() as $simpleProduct) {
        $jsonResult['skus'][$simpleProduct->getId()] = $simpleProduct->getSku();
    }


    $result = json_encode($jsonResult);

    return $result;
}
}

2.重写js

app/code/Mage/Bugfix/view/frontend/requirejs-config.js

var config = {
config: {
    mixins: {
        'Magento_Swatches/js/swatch-renderer': {
            'Mage_Bugfix/js/model/swatch-skuswitch': true
        },
        'Magento_ConfigurableProduct/js/configurable': {
            'Mage_Bugfix/js/model/configurable-skuswitch': true
        }
    }
}
};

3.针对没有开启swatch 功能的修正

app/code/Mage/Bugfix/view/frontend/web/js/model/configurable-skuswitch.js

/*jshint browser:true jquery:true*/
/*global alert*/
define([
'jquery',
'mage/utils/wrapper'
], function ($, wrapper) {
'use strict';

return function(targetModule){

    var reloadPrice = targetModule.prototype._reloadPrice;
    var reloadPriceWrapper = wrapper.wrap(reloadPrice, function(original){
        //do extra stuff

        //call original method
        var result = original();

        //do extra stuff
        var simpleSku = this.options.spConfig.skus[this.simpleProduct];

        if(simpleSku != '') {
            $('div.product-info-main .sku .value').html(simpleSku);
        }


        //return original value
        return result;
    });

    targetModule.prototype._reloadPrice = reloadPriceWrapper;
    return targetModule;
};
});

4.针对开启swatch 功能的修正

app/code/Mage/Bugfix/view/frontend/web/js/model/swatch-skuswitch.js

/*jshint browser:true jquery:true*/
/*global alert*/
define([
'jquery',
'mage/utils/wrapper'
], function ($, wrapper) {
'use strict';

return function(targetModule){

    var _loadMedia = targetModule.prototype._loadMedia;
    var _loadMediaWrapper = wrapper.wrap(_loadMedia, function(original){
        //do extra stuff

        //call original method
        var result = original();

        //do extra stuff
        var simpleSku = this.options.jsonConfig.skus[this.getProduct()];

        if(simpleSku != '') {
            $('div.product-info-main .sku .value').html(simpleSku);
        }


        //return original value
        return result;
    });

    targetModule.prototype._loadMedia = _loadMediaWrapper;
    return targetModule;
};
});