2025-06-09 08:00:00
本期已录制 B 站视频 👉 【Next.js】路由跳转显示进度条
哈喽,我是楷鹏。
先来看一个反面教材。
在 Dify.ai 中,当点击跳转页面之后,会有一段需要等待的时间,然后才会跳转页面。
然而,中间这段时间我并不知道是否跳转成功了,所以我会多点了几下,直到跳转。
这种体验很不好 👎
解决方案很简单,我们来看一下 GitHub 的跳转交互。
可以看到,GitHub 在跳转期间,会显示一个进度条,清晰地告诉用户——"我正在跳转,请稍等"。
那么在 Next.js 中,如何实现这个效果呢?
我们可以借助 BProgress 这个库来实现。
BProgress 是一个轻量级的进度条组件库,支持 Next.js 15+,同时也支持 Remix、Vue 等其他框架。
对于 BProgress 的使用,我做了一个 demo 项目 nextjs-progress-bar-demo,我们可以把这个项目先 clone 下来:
git clone [email protected]:wukaipeng-dev/nextjs-progress-bar-demo.git
然后进入项目目录:
cd nextjs-progress-bar-demo
先安装依赖:
npm install @bprogress/next
启动项目:
npm run dev
可以看到,这是一个简单的 Next.js 项目,包含三个页面:首页、登录页、注册页。
main
分支已经配置好了进度条,我们切换到分支 without-progress-bar-demo
:
git checkout without-progress-bar-demo
当前分支下,我们没有配置进度条,所以跳转页面时,不会显示进度条。
接下来我们在根布局 app/layout.tsx
中引入 ProgressProvider
:
'use client';
import "./globals.css";
import { ProgressProvider } from '@bprogress/next/app';
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body>
<ProgressProvider
height="4px"
color="#4c3aed"
options={{ showSpinner: false }}
shallowRouting
>
{children}
</ProgressProvider>
</body>
</html>
);
}
接下来,我们可以看一下,在首页和登录页、登录页和注册页之间跳转,都会显示一个进度条。
ProgressProvider
的参数如下:
height
:进度条的高度color
:进度条的颜色options
:进度条的配置,这里 showSpinner
设置为 false
,表示不显示一个动画的加载图标。shallowRouting
:是否启用浅层路由,如果开启的话,只改变路由的 query 参数,比如 ?page=1
变成 ?page=2
,那么进度条不会重新加载。但是,当我们登录成功之后,再点击跳转,却不会显示进度条。
这是因为,首页和登录页、登录页和注册页之间,是使用 <Link>
组件进行跳转的。
<Link>
组件实际会渲染成 <a>
,BProgress 通过给所有 <a>
组件添加点击事件,来显示进度条。
我们可以看下在 DevTools → Elements → <a>
→ Event Listeners 中,是否添加了点击事件:
但是,当我们登录成功之后,则是使用 router.push
进行跳转的。
BProgress 不会给 router.push
添加点击事件,自然也不会显示进度条。
不用慌,BProgress 为我们提供了 useRouter
方法。
将 Next.js 的 useRouter
替换为 BProgress 提供的 useRouter
:
// import { useRouter } from 'next/navigation';
import { useRouter } from '@bprogress/next/app';
然后,正常使用即可:
const router = useRouter();
router.push('/');
这时,你可以看到,在登录成功之后,自动跳转首页时,进度条就能正常显示了。
但如果你的项目已经封装过了自己的 useRouter
,那么你可以将封装过的 useRouter
作为参数 customRouter
传入,进行二次封装:
import { useRouter } from '@bprogress/next/app';
import { useRouter as useNextIntlRouter } from '@/i18n/navigation';
export default function Home() {
const router = useRouter({
customRouter: useNextIntlRouter,
});
return (
<button
onClick={() =>
router.push('/about', {
startPosition: 0.3,
locale: 'en',
})
}
>
Go to about page
</button>
);
}
最后,让我们回到 app/layout.tsx
,这里我们引入了 ProgressProvider
,但却把 app/layout
变成了一个客户端组件,我们来把 ProgressProvider
抽离到其他地方,仍然保持 app/layout
是一个服务端组件。
// app/components/ProgressWrapper.tsx
'use client';
import { ProgressProvider } from '@bprogress/next/app';
interface ProgressWrapperProps {
children: React.ReactNode;
}
export function ProgressWrapper({ children }: ProgressWrapperProps) {
return (
<ProgressProvider
height="4px"
color="#0000ff"
options={{ showSpinner: false }}
shallowRouting
>
{children}
</ProgressProvider>
);
}
在 app/layout.tsx
中,我们引入 ProgressWrapper
:
import { ProgressWrapper } from './components/ProgressWrapper';
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body>
<ProgressWrapper>
{children}
</ProgressWrapper>
</body>
</html>
);
}
好的,不愧是你,完成了一个 Next.js 集成路由跳转显式进度条的封装。
以上就是本期的全部内容,希望对你有所帮助。
感谢观看!👏
2025-05-31 08:00:00
作为一个前端 er,工作或者学习中,至少会遇到这么一次,需要区分 Next.js、Nest.js、Nuxt.js 的场景。
我最近就遇到这么一次。
公司有一位新入职的同事,吃饭聊天的时候,听他说之前做过 Next.js 的项目。
由于公司最近的新项目基于 Next.js,我就在想,“太好了,我们的新项目有救了”。
结果,在群聊的时候,他澄清了下,做的是 Nest.js 的项目。
一下子给我立不住了。
作为一个说着普通话的普通程序员,听不清 Next /nekst/ 和 Nest /nest/ 这两个发音,实在是太正常了。
这些框架的起名作者真是聪明。
命名跟批发一样,都是 N__t.js,上一次让我这么犯难的,还是黄金届的“周大福、周六福、周生生、六福珠宝……”
而这场品牌碰瓷,其实主要集中在前端框架爆发的 2016 年左右。
那个时候,前端行业百花齐放,各种框架层出不穷。
在 2016 年 10 月 25 号,Next.js 1.0 发布,首次作为开源项目亮相。
Next.js 基于 React 框架,提供服务端渲染(SSR)和静态站点生成(SSG)功能,以及自动代码拆分、路由系统等特性。
随后的一天,也就是 10 月 26 号,Nuxt.js 发布。
不得不说,Nuxt.js 抄得真快,它基于 Vue.js,整出了另一个 Next.js 翻版。
而 Nest.js 则是在下一年 2017 年的 2 月 26 号发布,它跟 Next.js 和 Nuxt.js 关系就比较远了。
它是纯 Node.js 后端框架,属于是 JavaScript 届的 Spring Boot。
现在这三个框架都发展得很好,除了打铁自身硬之外,是不是更多地得益于“蹭热度”的命名呢?
或许下一次,开发新框架的时候,就叫做 Not.js 吧。
2025-05-24 08:00:00
最开始在安装 Node.js 的时候,我们只能通过官网下载安装包,安装指定的一个版本,比如 18.17.1。
但对于不同的项目,我们可能需要使用不同的 Node.js 版本,比如 18.17.1 和 20.17.1。
如果要去切换版本,那就需要卸载旧版本,安装新版本,再切换项目,非常麻烦(痛苦面具)。
于是出现了 Node.js 版本管理器,比如 NVM、Volta 等。
它支持安装指定版本的 Node.js,并且可以自由切换版本。
但是,NVM 存在一些问题,for example,无法根据项目自动切换版本,不支持 Windows 平台(当然,有一个非官方支持的野鸡 nvm-windows 可以使用) 等等。
新一代的 Node.js 版本管理器 Volta 解决了这些问题。
它可以根据项目自动切换 Node.js 版本,并且还支持 Mac、Windows、Linux 三大平台。
Volta 基于 Rust 开发,速度更快,活更好。
根据安装指南,我们在终端中输入以下命令来安装 Volta:
curl -fsSL https://get.volta.sh | bash
安装完成后,打开另一个新终端,输入以下命令来查看当前的 Volta 版本:
volta -v
2.0.2
恭喜你,Volta 安装成功。
接下来,我们就可以使用 Volta 来管理 Node.js 版本了。
在终端中输入以下命令来安装 Node.js:
volta install node
这条命令会安装最新 LTS 版本的 Node.js。
LTS:Long Term Support,长期支持版本。
当然,也可以用艾特符号 @
安装特定版本的 Node.js,比如:
volta install [email protected]
打开一个你正在维护的 Node.js 项目,比如“shit-mountain”,找到 package.json
文件,添加以下内容:
{
//...
"volta": {
"node": "20.17.1"
}
}
当你执行 npm i
时,Volta 会寻找 20.17.1 版本的 Node.js。
如果找不到,Volta 会自动安装 20.17.1 版本的 Node.js,然后再执行 npm i
。
这样就确保了项目中使用的 Node.js 版本为 20.17.1。
Volta 还有其他一些特性,比如 Volta 的各种命令,list
、uninstall
等等,又比如 Hooks,可以指定下载源,这里就不再展开。
前往 Volta 官网查看更多信息 👉 https://volta.sh
2025-01-19 08:00:00
在一些成名的 GitHub 开源项目中,会支持 Vercel 一键部署,比如前两年爆火,如今坐拥 78.7k star 的 NextChat:
那么 Vercel 是什么呢? 它是一个专为前端开发者设计的现代化部署平台,特别适合用于静态网站和前端应用的构建、预览和发布。
So,如果你的开源项目属于静态网站或者前端应用一类的,可以考虑 README.md 上添加 Vercel 一键部署,为你的开源项目增加吸引力。
添加一键部署的方式也很简单,Vercel 提供了一个按钮生成工具:deploy-button
按钮生成器会生成 Markdown、HTML 和 URL 三种方式,可以按需取用
提醒一下,这里的交互会有点奇怪,页面下方是表单输入,比如填写 Git 仓库地址之后,上方 Markdown 链接会自动改变,并且没有成功提醒,这里需要适应一下
这里必填的,只有你的 Git 仓库地址:
其他的还有像是环境变量、默认项目名称、重定向、Demo、集成等,按需填写,最后将生成好的 Markdown 贴到你的开源项目 README.md 上:
整个流程就完成了,非常简单
对于用户侧来说,当他点击部署按钮之后,就会跳转到 Vercel 网站:
这里需要登录 Vercel,同时 Vercel 会要求授予 Git 仓库读写权限,因为 Vercel 会执行对目标仓库的克隆,再以克隆后的仓库为准进行部署:
填写项目名称,点击创建:
接下来就是等待大功告成:
Congratulations!
这里已经能看到网站运行成功之后的预览截图了,也可以点击「Continue to Dashboard」去到控制台,点击 domain 网址,同样能看到网站已经成功部署:
整体回顾来看,Vercel 的部署服务非常丝滑,我甚至都不需要提供框架信息、运行命令等等
So,觉得 Vercel 一键部署的方式不错,那么考虑为你的项目增加一下吧!
如有需要,可查看本文示例项目参考:https://github.com/wukaipeng-dev/ken
2025-01-03 08:00:00
Raycast 的 2024 年度统计出来了,这份统计包含了我这一年来用 Raycast 去打开其他应用的情况,看到滴答清单被打开上千次,排列榜首,还是有点小意外
滴答清单英文名:TickTick
今年是尝试并逐渐重度使用滴答清单的一年,一开始,我只想要找一个任务管理的软件,对比过其他很多 todo 软件,滴答清单的免费版本是我个人认为最良心的,大部分功能都涵盖到了
虽然免费很诱人,但还不足以打动我,真正打动的点还是解决了我长久以来的痛点。
在做任务的时候,我用的是番茄工作法,这种方法指的是在 25 分钟(1 个番茄钟)内专注,然后 5 分钟短休息,累计 4 个番茄钟后进行长休息这样的一个周期性节奏去专注
之前我买了一个桌面计时钟,考研党朋友应该很熟悉,类似于下面这种:
这种计时钟既可以正计时,也可以倒计时,也就是做一个 25 分钟的番茄钟倒计时,就这我用了 2 年多,在家里买一个,在公司也买了一个。
它很方便,物理按键,一按就可以开启番茄钟,但它的优点也正是它的缺点。
物理的限制,我不可能随时随地带着一个计时钟,更麻烦的是,一天结束,我不知道每天花了多少番茄钟,不知道什么时候开启番茄钟,不知道番茄钟期间都做了什么任务。
滴答清单在添加任务之后,可以针对这个任务直接开启番茄钟,也可以在番茄钟上去关联对应的任务,同时能做一些额外的笔记,打开统计页面,能清晰地看到每个番茄钟的开始结束
这基本上解决了我的大痛点,另外一个小痒点就是它的通知功能,日常总会忘记开启番茄钟,滴答清单在电脑的菜单栏,可以显式地看到专注的进度:
如果开启了跨设备同步,那么手机和电脑都会实时同步当前的专注进度:
让我小小惊喜的是,移动端开启专注模式后,会自动进入沉浸模式,其中除了翻页时钟模式,还有下面这款像素模式,UI 做得特别好看:
滴答清单在解决我的 Big Trouble 之后,我开始慢慢上手其他功能。
对于核心功能——任务管理,第一个提的点是对任务的分类,我相信很多人的分类都比较杂乱,今天加一个「读书」的类目,明天加一个「项目管理」的类目,而且类目一旦多了起来就难以管理了
这里我推荐一个非常实用的分类方式,那就是按照「角色」划分
在公司里,角色就是「员工」,在学校里,角色就是「学生」,在跑道上,角色就是「运动员」,在任意的社会关系中,每个人都是不同的角色。
在我个人的滴答任务分类中,会有管理员(Admin)、员工(Worker)、开发者(Dev)、Friend(朋友)、读书人(Reader)等等角色
这种划分方法非常稳定,我的任务分类一旦划分后,几乎没有大的改动,它还足够灵活,比如喜当爹了,那就加一个「父亲」角色,买奶粉、换尿布的任务都怼在这个角色上
按照角色划分,几乎囊括了所有的事情,但对于某些角色来说,它需要横向扩展,比如作为员工,需要做项目 a、项目 b 、项目 c 等等,那么可以使用标签,为任务打上对应标签,也就能够把角色下不同的任务类型区分开来:
通过角色划分 + 标签系统,基本可以建立一个有序稳定的分类体系了
第二点是任务处理方面,滴答清单藏了很多小心思,比如可以设置预估任务使用的番茄钟数量:
还比如可以设置任务进度百分比:
按住 Shift 或者 Command/Control 键选中多个任务之后,能够进行批量处理:
移动端长按应用图标添加任务,任务框右下角有个语音转文字功能,可以加速添加任务时间
另外是日程表功能,之前没有相应的使用习惯,最近发现了两点,让我开始觉得日程表非常香。
第一点发现是,可以运用筛选面板去查看目标任务,之前没有使用筛选,看着日历上所有任务都堆在一起,一个头两个大:
现在使用筛选功能,按照清单、标签等筛选,可以轻松地查看日程对应的任务:
第二点发现是原来日程之间是有通用协议的——CalDAV,它是一种日历数据共享和同步的协议,适用于安卓、iPhone、Windowns、macOS 等一切设备,只需要日历源即可在需要的日历地方导入即可同步到日程。
我在滴答清单上通过导入飞书的 CalCAV 配置,即能实现对飞书所有会议、日程的订阅:
还有一个习惯功能,我挖掘出了三种使用方法:
第一种就是最常用的正习惯:
第二种是坏习惯:
这种和正习惯相反,只有在出现这些坏习惯的时候才会做记录,坏习惯记录的场景是有:
第三是数据记录
习惯是有自带日历,可以当做一个数据记录,比如减肥的过程,可以记录每天的体重情况:
以上就是个人对滴答清单这一年来的使用,这确实是一款优秀的软件,但不可否认,它也存在一些局限性,比如艾森豪威尔矩阵,仅仅是对任务进行重要性、紧急性做一个简单的二维划分:
但这世界上不可能有完美的软件,有问题就解决问题,2024 年陆陆续续给滴答清单提的 bug 加上 feature request,有将近 30 个:
所以,我这算是编外的测试人员 + 产品经理吗 😆
2024-10-13 08:00:00
之前使用 Windows 的过程中,最痛苦的事是没有一款可以满足我快速进行记录的应用
基本都得先打开该笔记软件,然后创建新笔记,最后才能输入,这么多步骤太麻烦了
在切换到 MacOS 之后,让我惊喜的就是自带的备忘录,只需要简单地把鼠标移动到屏幕右下角,就可以创建一篇快速备忘录
Amazing!
这种方式叫做触发角,触发角可以在「系统设置 » 桌面与程序坞 » 触发角」设置:
四个触发角分别可以自由设置:
除了触发角,快捷键【 fn(🌐) + Q】同样能创建一篇快速备忘录
还有一个问题是,触发角 or 快捷键默认会打开上一次编辑的备忘录,如果想要每次都创建一篇新的快速备忘录的话,可以在设置这里:
把「始终回到上个快速备忘录」取消勾选
备忘录支持大部分高频的文本样式,选取文本后,在头部导航栏 Aa 这里做修改样式:
也能支持 check 清单:
表格功能比较弱鸡,就一个简单的表格,什么合并、冻结等高级功能都没有
另外还有图片、链接,这里就不再赘述。
备忘录默认支持文件夹分类,另外还支持标签分类,只需要在备忘录中使用井号(#
)加上对应文字,Mac 即会生成对应的标签清单:
之前在浏览网页的时候,特别想高亮某些内容,同时做一些拓展记录,安装过插件 Weava Highlighter,但是不好用,每次只要选中文字就 Weava 就会弹出,特别烦人。
没想到 Mac 备忘录居然原生支持这个功能
在 Safari 中,可以选择想要收藏的内容,右键「添加到快速备忘录」
创建快速备忘录之后,选中的这句话在 Safari 中会被高亮:
在最新的 MacOS 15 中更新中,备忘录新支持了录音功能:
并且还支持实时的语言转文本,但目前又又又又仅支持英语
库克的母语是英语,我的母语是无语 😅
另外,还新增了高亮颜色,分别有紫色、粉色、橙色、薄荷色和蓝色,不得不说,这几种颜色确实还挺好看的
最有用的功能当属于这个数学功能了
直接输入像是 (27/3)^2=
或者 47*96=
算式,备忘录会自动计算结果:
还支持自定义变量:
总体来说,Mac 的备忘录还算是一个不错的笔记软件,虽然缺乏像 Notion 的文档目录结构和块编辑的一些先进笔记能力,但它有着原生的支持,能够满足快速记录和基础编辑的需求