BlogArticles/2025-08/SiteBuild.md

8.8 KiB
Raw Blame History

title description draft type created_at published_at updated_at category tags tech_stack tech_stack_percent tech_stack_icon_names tech_stack_theme_colors
建站小记 作者选择自行搭建博客以挑战技术能力追求完全控制权。项目使用NuxtContent + SSG、TypeScript、Tailwind CSS等技术栈开发中遇到Nuxt ColorMode切换动画问题、Content的Schema类型难题以及响应式布局与动画冲突等挑战。目前进度不理想管理端尚未完成能否完工取决于后续时间。 false article 2025-08-25T02:54:33+08:00 2025-08-25T04:17:34+08:00
2025-08-25T02:54:33+08:00
记录
前端
文档
Vue.js
Nuxt
TypeScript
60
70
40
mdi:vuejs
lineicons:nuxt
lineicons:typescript
#41b883
#a179dc
#054e63

为什么我要自行建设博客?

We choose to go to the moon in this decade and do the other things, not because they are easy, but because they are hard; because that goal will serve to organize and measure the best of our energies and skills, because that challenge is one that we are willing to accept, one we are unwilling to postpone, and one which we intend to win, and the others, too. —— John F. Kennedy, 1962 我们选择在这个十年内登上月球并完成其他任务,不是因为它们容易,而是因为它们困难;因为这个目标将有助于组织和衡量我们最好的精力和技能,因为这是一个我们愿意接受的挑战,一个我们不愿推迟的挑战,一个我们打算赢得的挑战,当然也包括其他挑战。 —— 约翰·F·肯尼迪1962年

从某种程度上来说,我自行搭建博客的原因与以上发言类似 (有点大言不惭了) ,我需要一个测试自己的机会。我已经构建了几十个项目,我对它们尽心尽力,但是它们中大多数生命周期很短,往往是为了实验、比赛等短期目标。这些代码往往不需要过高的可扩展性和稳定性。同时,我注意到我的能力似乎已经足以支撑我去构建一个更加大型的长期项目。思来想去,博客是一个不错的选择,并且我可以通过它来记录我的学习和生活。

构建博客的原因之二是,市面上现有的博客也许它们能满足我的需求,但是我感觉研究它们的配置没有我自己重写一个有趣。而且,我希望能够完全控制我的博客内容和样式,而不是被平台所限制。

进展如何?

当我实际开始写之后我注意到这件事远比我设想的复杂。有很多技术我只是想当然的认为可行虽然结果也确实能行但是有大量的细节需要注意。不得不说首次编写本博客的现在已是暑假之末但是项目进度很不理想。先不考虑管理端博客部分有两个页面没创建一个页面有bug已有页面中有一个组件还没开始写。

而管理端前后端呢?更是不见踪影,与博客配对的相关配置,也处于残缺状态。

考虑到后续的比赛、保研以及可能的实习。我只能说,这项目能不能写完纯看缘分。

博客技术

聊点不那么现实的

这次博客使用了Nuxt来编写Nuxt构建后的产物的加载速度给我留下了颇为深刻的印象。在与ChatGPT、Claude 聊了一段时间后确定了用Nuxt Content + SSG作为博客核心。

就目前的开发体验来说Nuxt的启动和加载确实不够快但是其代码确实足够优雅我很喜欢。虽然从一定角度来讲为了所谓的优雅牺牲了太多开发效率消耗了太多时间在查文档和debug上。 但是我觉得这是值得的。从某种程度而言,我学计算机就是想来干这个的。

对于其他的技术栈,目前博客使用了

TypeScript
Pinia 
Tailwind CSS
Nuxt UI
HighCharts
MdEditor V3

那些大家都在用的就不放了

这里面 TypeScript Tailwind CSS 能明显提升前端体验我说实话我已经不太确定自己能不能写纯CSS项目了TS更不用多说JS看了半小时我就开始用TS了。好用爱用。

在用Nuxt时顺便被安利了Nuxt UI 就目前来讲还可以用的没有TDesign熟练有些组件即便有还是选择了手搓主要还是控制上差了一点。这次没用TDesign主要是和博客想要的风格不符TDesign有点太正式了。ElementPlus也不考虑有点丑我用的也少。

Nuxt的Pinia集成也是一个难点曾几何时Nuxt的Pinia集成搞了我一下午的时间。Vuex还没学过我估计这个项目也不需要Pinia够了。

HighCharts是个意外我本来想用ECharts的但是ECharts不支持坐标轴中放HTML代码只支持纯文字。而HighCharts虽然也不是能接受任意HTML但至少支持svg。配合icons这个强大的网站,够用了。 HighCharts开源但商用收费拿来建个人博客还是没问题的。 PSHighCharts的介绍页面图表又多又好看期待后续有新想法继续使用。

MdEditor V3 这是我第一个使用的前端Markdown编辑/渲染器。之前做实验就用过但是这次我没有首选它而是选了MilkDown不好用。 从 MilkDown core 和 MilkDown creep 中可以看到这个项目的潜力。但是实在有点难配了文档真看不懂感觉写的有点屎当然我觉得还是自己能力不足。只能说为了WYSIWYG实在不值得双屏写MD我是没什么障碍的例如我现在就在WebStorm里写MD然后同步渲染到dev网页里。因此索性放弃了MilkDown。 后来又试了 Markdown-it。如果我没记错放弃它的原因是因为滚动不是连贯的。

试来试去,发现最初遇到的就是最好的,果断复合了。

PS正在写这篇文章的时候发现上面的代码段竟然在我Navbar的上面一看z-index是10000绝了。改成5了我看看会出什么问题。

遇到的各种难点

Nuxt ColorMode

这个插件真的很神奇。如果我没记错这个插件的问题是在切换主题时有些设置了过渡动画的DOM没有播放动画而是一步到位。我真的卡了很久但最后没办法自己实现了一个ColorMode切换器丝滑无比。而且我认为原理上和Nuxt-ColorMode应该是一致的都是在顶级中添加dark class。但是用这插件就是会出现问题最终含泪放弃。

Nuxt Content

Nuxt Content 的文档确实需要仔细翻才能找到某些功能。从某种程度上也是吃了英语不好的亏。但总体来说,这个手册质量还是在线的。 但是我也确实有没能解决的问题。

Content Config 中有一个 Schema 的属性它会利用zod自动生成一个ContentCollectionItem属性。Schema作用是定义文章元数据如果定义了rawbody那么将得到文章原文。 问题出在 queryCollection 后的 select 方法上select方法接受一组键这些键都是Schema中定义的数据结构但是问题在于我只是不想要其中的rawbody因为在列表加载原文可能会浪费很多性能。 在这种情况下,我希望将 Schema 提取出来然后将所有非rawbody的键写入到select中。这么做虽然没问题但是TS不高兴。虽然我们通过 Schema 定义了 文章属性,但是它与自动生成 ContentCollectionItem 毫无关联。对于ts来说我们在试图将string赋值给keyof ContentCollectionItem这显然是不行的。 而ContentCollectionItem也没有export出来无法直接使用。 目前的解决方案是先连同rawbody一起加载出问题再说。理论上只有生成时会慢运行时不会受影响。

粘性布局、响应式更新与动画冲突

这三个东西随便缺一个都不会有我接下来要讲的神奇问题 在浏览其他人的博客时,我注意到大部分博客信息流旁会有一个随滚动而滚动的侧边栏,这个侧边栏通常是粘性布局实现的。

但我在具体实现上犯了难。

观察别人的博客HTML后确定应当将sticky的父设置为table然后把sticky DOM设置为float left主DOM设置为 float right。这样粘性布局就搞定了。

在其基础上,设置断点对应的宽度,实现响应式布局,也没问题。

再加上动画设置,结果问题出现了。

由于使用了浮动而两个DOM都是块。当两者宽度大于父DOM宽度时两个DOM会从左右布局变为上下布局。在动画开始时是正确的动画结束时是正确的但是动画进行时外部的DOM宽度减小速度过快内部的宽度减小速度较慢导致内部两DOM变为上下布局。

解决方法是把原先会响应式更新的侧边栏的宽度改为固定值然后让右侧DOM根据父组件计算自己的宽度。这样就不会出现上述问题了。

未完待续

最近保研真是焦虑quq