8

2019年1月12日 上午11:30

date-picker, picker-options, firstDayofWeek

起因

昨天下班前开了一个小会,会议中提到了一个问题:
element-ui日期组件默认是从周日开始的(如下图),目的是希望能从周一开始。
7-6

一个成熟的组件,这个基本功能怎么可能没有?!(如果没有,组件是否方便扩展实现)
但他们说查阅了文档,没发现该功能。

探索

查文档

本着怀疑的态度,会议结束后,我去翻了一下文档。

发现文档里是有这个配置的:

picker-options

文档中写了可选值1到7,默认值7,这不正是我们要的吗?只要把这个配置设置为1不就行了吗 ?
(这个时候我并没有注意到这个配置的标题是Picker Options

文档上明明写的有,为什么他们说不行呢?那就让我来验证一下吧!

验证

于是我本地起了个服务,直接给ElDatePicker 组件传入了一个firstDayofWeek:1,

<el-date-picker 
  ...(省略)
  :firstDayOfWeek="1"
  placeholder="选择日期">
</el-date-picker>

咦 ?确实没生效,日期还是从7开始的。
我值传错了?回看一下文档类型是Number,没错啊。
组件接收到我传的值了吗?

排疑

通过Vue Devtools查看了一下
data

奇怪,是7也就算了,怎么还是挂在data下面的,为什么不是props?

再验证

我点击旁边的-号修改了这个值,发现日期组件随着这个值在变化!(只要把值调为1,就是我们希望的结果)

得出结论

这说明了什么??

说明这确实是可配置的!!

那么问题就很明显了:

  • 要么是我配置错了
  • 要么是组件有bug

再探索

提出疑问

于是我又回头看了一下文档

  • Picker Options 上方的表格是 Attributes
  • 放在Attributes里才是直接通过props传递啊?
  • firstDayOfWeek为什么不放在Attributes里?(由于没用过这个组件,并没仔细去看Attributes里的每一个值,此时还没有发现Attributes表格里面有picker-options,如果能认真一点的话,事情到这里就该结束?)

跟随疑问

带着一肚子疑问去看了下组件源码

当我看到firstDayOfWeekdata里定义,而且当前文件没有对它赋值的时候,居然就天真的认为这是一个bug,为什么把一个要配置的值放在data里写死了7?放在data里我怎么传值?(这个地方的我太草率了!! 这个时候正确的做法应该是:耐心的接着看一下,比如mixins,如果这里仔细点,问题到这里也能解决了)

<date-table
   …(省略部分属性)
  :first-day-of-week="firstDayOfWeek"
>
</date-table>
data() {
  return {
   …(省略)
    firstDayOfWeek: 7
  };
}

我愚蠢的把这个当成是一个bug,于是打开了github,去issues里搜索了一下看有没有提过这个bug,一搜,还真有。

[Bug Report] datepicker week type doesn't consider firstWeekOfDay

下面有一条维护者的回复:"
firstDayOfWeek should be nested in picker-options"

找到正确使用方法

⚡️⚡️⚡️⚡️⚡️(我真蠢,真的)
此时才明白上面那个疑问(为什么firstDayOfWeek不放在Attributes)

于是这个时候,我才去Attributes下面看了一下,看见picker-options安安静静地躺在里面。改为下面这样,就行了。

:picker-options="{
  firstDayOfWeek: 1
}"

1-7

探索答疑

事情到了这里,已经结束了吗?不!上面还有一个疑问没解决呢(为什么pickerDayofWeekdata里,那它是怎么改变的?)

我这次由外到内,仔细的看了一下组件源码,这才看清楚了

const updateOptions = () => {
   …(省略)
  for (const option in options) {
    if (options.hasOwnProperty(option) &&
        // 忽略 time-picker 的该配置项
        option !== 'selectableRange') {
      this.picker[option] = options[option]; // 赋值在这里!
    }
  }
}
this.unwatchPickerOptions = this.$watch('pickerOptions', () => updateOptions(), { deep: true });

组件的细节这里就不赘述了,有兴趣可以自己去看。

最后:

这更像是一篇流水账式的叙事文,问题是个小问题,希望大家能从解决问题的思路上有点启发。

鸡汤式反思:

  • 探索 既然已经给出了firstDayOfWeek,那就说明功能是有的,没生效不能武断认为它没提供。
  • 认真 曾经有两次差点接近真相,但都错过了。

这不是一次成功的解题,是走了弯路最后解决的问题。

共勉。


小青虫
122 声望6 粉丝

即使折了腰,也要笔直前行