目标
来用 ReScript 绑定一下 Day.js 的来处理时间相关的操作
从简单使用开始
我们在之前一篇文章 ReScript 真好玩-ReScript 简化版 Redux 实现 的项目基础上,进一步完善内容。
首先是把 Day.js 安装好,直接 bun i dayjs
安装好依赖,接着我们看一下 Day.js 官方文档如何使用,它直接可以通过 dayjs()
创建一个对象的,所以我们先把这一步完成。
首先我们知道每个 ReScript 文件表示一个 Module,所以先上来就创建一个 Dayjs.res 文件放在 src 目录下,接着按照惯例写一个 make
函数,这里涉及一个知识点,@module("")
这种装饰器风格的语法是表达使用某个模块,这里咱们使用 dayjs 模块
@module("dayjs") external make: unit => ? = "default"
现在我们面临一个问题,我们不知道 make
调用后是一个什么类型,而实际上这个类型又是从 JavaScript 那边来的,其实我们不用管它是什么类型,真正到我们用这个类型也只是后续给 JavaScript 那侧操作,所以我们只需要按照惯例在 Module 文件第一行标识一下
type t
@module("dayjs") external make: unit => t = "default"
这其实属于 ReScript 抽象的一部分,它提供一个类型标识,后续要表达一个 Dayjs 对象的类型只需要 Dayjs.t
就可以。
现在可以使用一下,切到之前项目的 App.res 文件,然后写上一句下面这个,就可以在控制台看到一条 Dayjs 对象的日志
// ...
@react.component
let make = () => {
// ...
Console.log(Dayjs.make())
<>
// ...
</>
}
绑定时间格式化操作
我们接着来绑定一下 format 操作,我们可以用它把 Dayjs 的对象转成一个好理解的时间字符串,我们在 Dayjs.res 文件中写写下面这句代码,这里涉及到两个知识点,一个是 @send
语法,另一个是 (t, ~formatter: string=?) => string
中的 ~formatter
,先不解释
@send external format: (t, ~formatter: string=?) => string = "format"
我们赶紧来调用一下
// ...
@react.component
let make = () => {
// ...
Console.log(Dayjs.make()->Dayjs.format)
<>
// ...
</>
}
调用结果是一个这种风格的字符串 2024-10-23T23:00:00+08:00
,我们发觉没传第二个参数,因为 ~formatter
这种语法表示这是一个可选参数,然后我们再来看看实际生成的 JavaScript 代码(这里是 App.bs.js),其他的不管,主要是发觉生成的 JavaScript 代码里有
import Dayjs from "dayjs";
// ...
console.log(Dayjs().format());
// ...
这下子就理解了 @send
的作用,它是调用一个对象的方法,这里是 Dayjs()
对象调用 format()
方法。接着再来试验一下带 formatter 参数的效果,这里我们直接结合 setInterval
函数把实时时间显示在之前的 App.res 页面上,能看到时分秒一直在页面上更新
@module("./assets/react.svg") external reactLogo: string = "default"
@module("/vite.svg") external viteLogo: string = "default"
%%raw("import './assets/css/App.css'")
open Redux
@react.component
let make = () => {
let str = useSelector(state => state.str)
let dispatch = useDispatch()
let (date, setDate) = React.useState(() => "")
setInterval(() => setDate(_ => Dayjs.make()->Dayjs.format(~formatter="HH:mm:ss")), 1000)->ignore
<>
<div>
<a href="https://vitejs.dev" target="_blank">
<img src={viteLogo} className="logo" alt="Vite logo" />
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1> {`Vite + React + ${str} + ${date}`->React.string} </h1>
<div className="card">
<button onClick={_ => dispatch(Add("ReScript"))}> {`ReScript`->React.string} </button>
<p>
{"Edit "->React.string}
<code> {"src/App.res"->React.string} </code>
{" and save to test HMR"->React.string}
</p>
</div>
<p className="read-the-docs">
{"Click on the Vite and React logos to learn more"->React.string}
</p>
</>
}
其他 API 的绑定
有了上面的基础,其他还能绑定其他的 Dayjs API,不过篇幅有限,知晓怎么绑定,后续可以在实际开发中进行。这里再给出几个绑定,譬如我们可以用 Dayjs 来比较两个时间,或者把一段正确的时间字符串时间转成 Dayjs 对象
// Dayjs.make()->Dayjs.isAfter("2024-11-01"->Dayjs.parseString)
@send external isAfter: (t, t) => bool = "isAfter"
@module("dayjs") external parseString: string => t = "default"