92d67aead52a37a9ba13dc08213b464c.png

前天我的同事问了我一个问题,说她遇到一个父子组件之间的props赋值失效的问题,奇怪的是同一个页面另外一个地方也调用了同一个子组件并且props使用赋值正常,而且她和我说其他props能正常赋值,还就只有一个props:noOptionsText这个属性赋值失效。附上图:

props赋值正常的代码块(模板字符串中调用):

1794d9982df7bdb9b31b5a62150ba534.png

props赋值失效的代码块(template中调用):

281a160de2c89e13b774320cd29eed0a.png

一开始我也是愣住了,在子组件中用watch监听失效的props:noOptionsText属性,发现确实赋值失效而且其他属性也确实能赋值成功(除了props:noOptionsText以及noResultsText)。并且我也确信肯定是props属性名有问题,排除了单词拼错多加空格等低级错误,我在子组件打印了它的整个props对象,发现了问题所在:

在vue的中文官网有这样的说明:HTML 中的特性名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符。

这意味着当你使用 DOM 中的模板时,camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名。

在Vue的源码中创建Vue组件的时候createComponent(),解析组件的相关属性,

// extract props
var propsData = extractPropsFromVNodeData(data, Ctor, tag);

在extractPropsFromVNodeData()中,Vue通过调用内部方法hyphenate,把驼峰形式的属性转换为横断线形式。

  /**
   * Hyphenate a camelCase string.
   */
  var hyphenateRE = /B([A-Z])/g;
  var hyphenate = cached(function (str) {
    return str.replace(hyphenateRE, '-$1').toLowerCase()
  });

但是!!!如果你使用字符串模板,那么这个限制就不存在了。这也就出现了文章开头,为什么一模一样的命名方式在字符串模板中props还是能够正常赋值。

5c31846a9d4c833565b6cf00194af20e.png

最后附上正确的命名方式:

45ffb2b1122522a9818d857731fb9233.png

其实,会出现这种问题,还是说明自身vue基础还是不够稳固,而且我也被字符串模板那边能正常赋值给蒙住了,导致最后我还是靠打印props对象才发现了问题的根源。

bug无止境,踩坑无涯。

Logo

前往低代码交流专区

更多推荐