本文为稀土掘金技术社区首发签约文章,14天内禁止转载,14天后未获授权禁止转载,侵权必究!
- 前言
大家好,我是若川。我倾力持续组织了一年每周大家一起学习200行左右的源码共读活动,感兴趣的可以点此扫码加我微信 ruochuan02
参与。另外,想学源码,极力推荐关注我写的专栏《学习源码整体架构系列》,目前是掘金关注人数(4.1k+人)第一的专栏,写有20余篇源码文章。
我们开发业务时经常会使用到组件库,一般来说,很多时候我们不需要关心内部实现。但是如果希望学习和深究里面的原理,这时我们可以分析自己使用的组件库实现。有哪些优雅实现、最佳实践、前沿技术等都可以值得我们借鉴。
相比于原生 JS
等源码。我们或许更应该学习,正在使用的组件库的源码,因为有助于帮助我们写业务和写自己的组件。
如果是 Vue
技术栈,开发移动端的项目,大多会选用 vant
组件库,目前(2022-10-24) star
多达 20.3k
。我们可以挑选 vant
组件库学习,我会写一个vant 组件库源码系列专栏,欢迎大家关注。
vant 组件库源码分析系列:
- 1.vant 4 即将正式发布,支持暗黑主题,那么是如何实现的呢
- 2.跟着 vant 4 源码学习如何用 vue3+ts 开发一个 loading 组件,仅88行代码
- 3.分析 vant 4 源码,如何用 vue3 + ts 开发一个瀑布流滚动加载的列表组件?
- 4.分析 vant 4 源码,学会用 vue3 + ts 开发毫秒级渲染的倒计时组件,真是妙啊
- 5.vant 4.0 正式发布了,分析其源码学会用 vue3 写一个图片懒加载组件!
这次我们来分析 vant4
新增的暗黑主题是如何实现的。文章中的 vant4
的版本是 4.0.0-rc.6
。vant
的核心开发者是@chenjiahan,一直在更新vant
。预计不久后就会发布 vant4
正式版。
暗黑主题如图所示:
也可以打开官方文档链接,自行体验。
学完本文,你将学到:
1 | bash复制代码1. 学会暗黑主题的原理和实现 |
- 准备工作
看一个开源项目,第一步应该是先看 README.md 再看贡献文档 github/CONTRIBUTING.md。
不知道大家有没有发现,很多开源项目都是英文的 README.md
,即使刚开始明显是为面向中国开发者。再给定一个中文的 README.md
。主要原因是因为英文是世界通用的语言。想要非中文用户参与进来,英文是必备。也就是说你开源的项目能提供英文版就提供。
2.1 克隆源码
贡献文档中有要求:You will need Node.js >= 14 and pnpm.
1 | bash复制代码# 推荐克隆我的项目 |
我们先来看 pnpm dev
最终执行的什么命令。
vant
项目使用的是 monorepo
结构。查看根路径下的 package.json
。
2.2 pnpm dev
1 | json复制代码// vant/package.json |
再看 packages/vant/package.json
。
1 | json复制代码// vant/packages/vant/package.json |
pnpm dev
最终执行的是:vant-cli dev
启动了一个服务。本文主要是讲主题切换的实现,所以我们就不深入 vant-cli dev
命令了。
执行 pnpm dev
后,命令终端输入如图所示,可以发现是使用的是目前最新版本的 vite 3.1.8
。
这时我们打开 http://localhost:5173/#/zh-CN/config-provider
。
- 文档网站
打开后,我们可以按 F12
和 vue-devtools
来查看vant
官方文档的结构。如果没有安装,我们可以访问vue-devtools 官网通过谷歌应用商店去安装。如果无法打开谷歌应用商店,可以通过这个极简插件链接 下载安装。
mobile 端
3.1 通过 vue-devtools 打开组件文件
如图所示,我们通过 vue-devtools
打开 VanDocSimulator
组件文件。
曾经在我的公众号@若川视野 发起投票 发现有很多人不知道这个功能。我也曾经写过文章《据说 99% 的人不知道 vue-devtools 还能直接打开对应组件文件?本文原理揭秘》分析这个功能的原理。感兴趣的小伙伴可以查看。
我们可以看到 vant/packages/vant-cli/site/desktop/components/Simulator.vue
文件,主要是 iframe
实现的,渲染的链接是 /mobile.html#/zh-CN
。我们也可以直接打开 mobile 官网 验证下。
1 | js复制代码// vant/packages/vant-cli/site/desktop/components/Simulator.vue |
3.2 desktop 端
和打开 VanDocSimulator
类似,我们通过 vue-devtools
打开 VanDocHeader
组件文件。
打开了文件后,我们也可以使用 Gitlens
插件。根据 git
提交记录 feat(@vant/cli): desktop site support dark mode,查看添加暗黑模式做了哪些改动。
接着我们来看 vant/packages/vant-cli/site/desktop/components/Header.vue
文件。找到切换主题的代码位置如下:
模板部分
1 | html复制代码// vant/packages/vant-cli/site/desktop/components/Header.vue |
JS部分
1 | js复制代码// vant/packages/vant-cli/site/desktop/components/Header.vue |
3.3 iframe 通信 iframe-sync
上文JS代码中,有 getDefaultTheme, syncThemeToChild
函数引自文件 vant/packages/vant-cli/site/common/iframe-sync.js
文件开头主要判断 iframe
渲染完成。
1 | js复制代码// vant/packages/vant-cli/site/common/iframe-sync.js |
后半部分主要是三个函数 getDefaultTheme
、syncThemeToChild
、useCurrentTheme
。
1 | js复制代码// 获取默认的主题 |
在项目中,我们可以可以搜索 useCurrentTheme
看在哪里使用的。很容易我们可以发现 vant/packages/vant-cli/site/mobile/App.vue
文件中有使用。
3.4 mobile 端
1 | html复制代码// 模板部分 |
1 | js复制代码// js 部分 |
上文阐述了浅色主题和暗黑主题的实现原理,我们接着来看如何通过 ConfigProvider
组件实现主题的深度定制。
- ConfigProvider 组件,深度定制主题
这个组件的文档有说明,主要就是利用 CSS 变量
来实现的,具体可以查看这个链接学习。这里举个简单的例子。
1 | js复制代码// html |
可以预设写好若干变量,然后在 style
中修改相关变量,就能得到相应的样式,从而达到深度定制修改主题的能力。
比如:如果把 --van-color: black;
,改成 --van-color: red;
则字体颜色是红色。
如果把 --van-background-color: pink;
改成 --van-background-color: white;
则背景色是白色。
vant
中有一次提交把之前所有的 less
变量,改成了原生 css
的 var
变量。breaking change: no longer support less vars
vant
中 ConfigProvider
组件其实就是利用了这个原理。
知晓了上面的原理,我们再来简单看下 ConfigProvider
具体实现。
1 | js复制代码// vant/packages/vant/src/config-provider/ConfigProvider.tsx |
有小伙伴可能注意到了,这感觉就是和 react
类似啊。其实 vue
也是支持 jsx
。不过需要配置插件 @vue/babel-plugin-jsx
。全局搜索这个插件,可以搜索到在 vant-cli
中配置了这个插件。
- 总结
我们通过查看 README.md
和贡献文档等,知道了项目使用的 monorepo
,vite
等,pnpm i
安装依赖,pnpm dev
跑项目。
我们学会了利用 vue-devtools
快速找到我们不那么熟悉的项目中的文件,并打开相应的文件。
通过文档桌面端和移动端的主题切换,我们学到了原来是 iframe
渲染的移动(mobile)端,通过 iframe
postMessage
和 addEventListener
通信切换主题。
学会了 ConfigProvider
组件是利用
CSS 变量 预设变量样式,来实现的定制主题。
也学会使用 @vue/babel-plugin-jsx
编写 jsx
组件,和写 react
类似。
相比于原生 JS
等源码。我们或许更应该学习,正在使用的组件库的源码,因为有助于帮助我们写业务和写自己的组件。开源项目通常有很多优雅实现、最佳实践、前沿技术等都可以值得我们借鉴。
如果是自己写开源项目相对耗时耗力,而且短时间很难有很大收益,很容易放弃。而刚开始可能也无法参与到开源项目中,这时我们可以先从看懂开源项目的源码做起。对于写源码来说,看懂源码相对容易。看懂源码后可以写文章分享回馈给社区,也算是对开源做出一种贡献。重要的是行动起来,学着学着就会发现很多都已经学会,锻炼了自己看源码的能力。
如果看完有收获,欢迎点赞、评论、分享支持。你的支持和肯定,是我写作的动力。
最后可以持续关注我@若川。这是 vant
第一篇文章。我会写一个组件库源码系列专栏,欢迎大家关注。
我倾力持续组织了一年每周大家一起学习200行左右的源码共读活动,感兴趣的可以点此扫码加我微信 ruochuan02
参与。
另外,想学源码,极力推荐关注我写的专栏《学习源码整体架构系列》,目前是掘金关注人数(4.1k+人)第一的专栏,写有20余篇源码文章。包含jQuery
、underscore
、lodash
、vuex
、sentry
、axios
、redux
、koa
、vue-devtools
、vuex4
、koa-compose
、vue 3.2 发布
、vue-this
、create-vue
、玩具vite
、create-vite
等20余篇源码文章。
本文转载自: 掘金