前言
上一篇 dayjs 源码解析(四)(Dayjs 类)介绍了 dayjs 的源码目录结构。接下来,本篇将分析一下 dayjs 中插件功能的用法、源码以及如何编写自己的 dayjs 插件。
dayjs 插件用法
dayjs 的插件,通过挂载到 dayjs 函数下的 extend 函数加载,然后使用:
import plugin // 导入插件
dayjs.extend(plugin) // 加载插件
dayjs.extend(plugin, options) // 或者加载插件的同时,加入插件所需要的参数
例子:使用官方的 IsLeapYear 插件
import isLeapYear from 'dayjs/plugin/isLeapYear'
dayjs.extend(isLeapYear)
dayjs('2000-01-01').isLeapYear() // true
这就是 dayjs 插件的使用方法。
dayjs 插件源码(即 dayjs.extend() 方法)
// 扩展插件的方法
// plugin:插件函数
// option:插件的选项
dayjs.extend = (plugin, option) => {
// 插件函数接受三个参数
// 1.插件选项 2.Dayjs 类 3.dayjs 函数
// 插件的方法都是挂载在 Dayjs 类的原型对象上的(Dayjs.prototype)。
plugin(option, Dayjs, dayjs)
return dayjs
}
dayjs.extend() 方法,接受两个参数,即插件(函数)和插件的选项。
在 dayjs.extend() 方法中,直接调用传入的插件(函数),且传入三个参数:传入 dayjs.extend() 方法的 option、Dayjs 类以及 dayjs 函数。
最后,返回 dayjs 函数。
然后,我们来看一个官方的 isLeapYear 插件的源码,看看它是怎么写的:
export default (o, c) => {
const proto = c.prototype
proto.isLeapYear = function () {
return ((this.$y % 4 === 0) && (this.$y % 100 !== 0)) || (this.$y % 400 === 0)
}
}
在 isLeapYear 插件源码中,导出一个函数,该函数接受两个参数(即在 dayjs.extend() 方法中的 option 和 Dayjs 类),然后将 isLeapYear 函数挂载到 Dayjs 类的原型对象上。因此,每个 Dayjs 实例都可以使用 isLeapYear 方法。
编写自己的 dayjs 插件
通过阅读插件的源码,我们知道了插件的方法,可以挂载到 Dayjs 类上、Dayjs 类原型上以及 dayjs 函数对象上。并且,可以通过插件选项(option),来对插件进行配置。
官方文档也提供了插件开发的模板:
export default (option, dayjsClass, dayjsFactory) => {
// 扩展 dayjs() 实例
// 例:添加 dayjs().isSameOrBefore() 实例方法
dayjsClass.prototype.isSameOrBefore = function (arguments) {}
// 扩展 dayjs 类
// 例:添加 dayjs.utc() 类方法
dayjsFactory.utc = (arguments) => {}
// 覆盖已存在的 API
// 例:扩展 dayjs().format() 方法
const oldFormat = dayjsClass.prototype.format
dayjsClass.prototype.format = function (arguments) {
// 原始format结果
const result = oldFormat(arguments)
// 返回修改后结果
}
}
通过插件,可以很方便的进行 dayjs 库的方法的扩展,来更好的服务我们的具体的业务需求。
dayjs 源码解析完。这五篇文章,也只是大概的解析了一下 dayjs 源码的主要函数、方法和类,其他 api 方法还需要自己一个一个去看。☺
总结
如何阅读源码?
- 先从库的 api 入手,看其如何使用
- 然后再看源码的入口函数或类,了解源码的整体结构
- 最后再具体看 api 的源码