记:ant-design-vue里layout的Bug

本文最后更新于:2021年6月26日 下午

最近在给项目升级ant-design-vue组件库的时候,发现新版里Layout组件的一个bug。

现象

可以看到,2.1.2版本的layout组件缺失了默认样式ant-layout

2.1.2版本

查看了下github仓库的更新记录,这个问题从2.0.1开始出现,太巧了,我们原本用的是2.0.0,那时候还是正常的,可以看到有默认样式ant-layout(其他class是自己定义的)

2.0.0版本

官方更新记录里提到,在2.2.0-beta.2重写了layout组件,试了下,果然在这个版本往前到2.0.1都有这个bug。

探索

把antd的库clone下来,切到tag为2.0.1的版本,看看啥情况

定位到layout.tsx里的generator函数, 里面有一段是这样的,props预定义的内容包括样式名,标签名等等(具体不同组件应该是不同的),prefixCls属性里存的其实就是最终得到的样式类名。

setup(props, { slots }) {
    const { getPrefixCls } = inject('configProvider', defaultConfigProvider);
    return () => {
        const { prefixCls: customizePrefixCls } = props;
        const prefixCls = getPrefixCls(suffixCls, customizePrefixCls);
        const basicComponentProps = {
            prefixCls,
            ...props,
            tagName,
        };
        return (
            <BasicComponent {...basicComponentProps}>
                {flattenChildren(slots.default?.())}
            </BasicComponent>
        );
    };
},

对比2.2.0-beta.2版本的源码。说实话好像没太大差别,useConfigInject最后调用的还是getPrefixCls这个方法,好像没差别啊!

setup(props, { slots }) {
        const { prefixCls } = useConfigInject(suffixCls, props);
        return () => {
          const basicComponentProps = {
            ...props,
            prefixCls: prefixCls.value,
            tagName,
          };
          return 
            <BasicComponent 
                {...basicComponentProps}>{slots.default?.()}				             </BasicComponent>;
        };
      },

研究了一小会,想不明白。代码文件缺了v2-doc(测试例子),第一次接触这个也摸不着头脑,查了下,目前只开源了v1版本的…

跑不起来…换个思路,我自己项目node_mode里其实也是有antd的源码的(lib下的只用了babel处理,未打包),可以在那边运行debug

如下

2.0.1版本

var customizePrefixCls = props.prefixCls;
var prefixCls = getPrefixCls(suffixCls, customizePrefixCls);
var basicComponentProps = _extends(_extends({
     prefixCls: prefixCls}, props), {
     tagName: tagName
});

2.2.0-beta.2版本

var _useConfigInject = (0, _useConfigInject3.default)(suffixCls, props),
    prefixCls = _useConfigInject.prefixCls;

var basicComponentProps = _extends(_extends({}, props), {
    prefixCls: prefixCls.value,
    tagName: tagName
});

这个_extends,如果浏览器支持Object.assign的话,他就是Object.assign,源码如下…

function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

我这一下就明白了…..

这不就是2.0.1版本对prefixCls的合并顺序错了嘛…..props里的prefixCls属性直接覆盖了默认的。

跑起来打断点验证下。运行项目,浏览器F12,打开source栏,ctrl+o查找layout.js,打上断点。可以看到,执行_extends后,undefine覆盖了ant-layout

默认css样式名直接被undefined(这个值应该是configProvider里提供的)冲掉了,用同样方法检查试试2.2.1-beta.2版本,可以看到prefixCls是ant-layout,这里就不放图了


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!