[{"data":1,"prerenderedAt":1169},["ShallowReactive",2],{"rainink-post-nuxt4-static-site":3,"rainink-content-index":1030},{"id":4,"title":5,"body":6,"category":1013,"cover":1014,"date":1015,"description":1016,"draft":1017,"extension":1018,"featured":1017,"lang":1014,"meta":1019,"navigation":647,"order":1014,"path":1020,"period":1014,"pinned":647,"repo":1014,"seo":1021,"slug":1014,"stack":1014,"stem":1022,"tags":1023,"thumb":1014,"toc":647,"updated":1028,"__hash__":1029},"content\u002Fposts\u002Fnuxt4-static-site.md","用 Nuxt 4 + Nuxt Content 搭一个纯静态个人站",{"type":7,"value":8,"toc":1000},"minimark",[9,16,21,24,27,40,43,51,61,65,72,76,276,280,377,381,387,496,499,514,521,525,536,743,746,749,767,920,929,932,990,993,996],[10,11,12],"blockquote",{},[13,14,15],"p",{},"这篇文章记录的是「雨墨」这个站本身的搭建过程：从一张手写原型图，到一份能直接丢给 Nginx 的静态产物。",[17,18,20],"h2",{"id":19},"为什么不做传统-cms","为什么不做传统 CMS",[13,22,23],{},"个人技术站的内容更新频率很低，但每次更新都希望是「写一个 Markdown 文件、提交、部署」这么简单。数据库 + 后台管理界面这套组合，对一个只有作者一人的站点来说是纯粹的运维负担。",[13,25,26],{},"于是目标定得很清楚：",[28,29,30,34,37],"ul",{},[31,32,33],"li",{},"内容以文件形式存在 Git 里，可 diff、可回溯；",[31,35,36],{},"构建产物是纯静态文件，不需要 Node 常驻进程；",[31,38,39],{},"站内没有任何用户输入入口（无评论、无注册、无搜索后端）。",[17,41,42],{"id":42},"目录结构",[13,44,45,46,50],{},"最终落地的结构遵循 Nuxt 4 的目录约定，",[47,48,49],"code",{},"app\u002F"," 目录承载全部前端代码：",[52,53,59],"pre",{"className":54,"code":56,"language":57,"meta":58},[55],"language-text","site\u002F\n├─ app\u002F\n│  ├─ assets\u002Fcss\u002Fmain.css        # 设计令牌 + 全站样式\n│  ├─ assets\u002Fimages\u002Fhero-ink.svg # 首屏水墨底图\n│  ├─ components\u002F                # 页头\u002F页脚\u002F卡片\u002F目录\u002F回到顶部\n│  ├─ composables\u002F               # 主题、文章索引、目录高亮\n│  ├─ data\u002Fsite.ts               # 站点名、导航、备案号等常量\n│  ├─ layouts\u002Fdefault.vue        # 页头 + 内容 + 页脚 + 回到顶部\n│  └─ pages\u002F                     # 首页 \u002F 栏目 \u002F 文章 \u002F 标签 \u002F 关于\n├─ content\u002F                      # Markdown 内容\n├─ public\u002F                       # 静态资源（favicon 等）\n└─ nuxt.config.ts\n","text","",[47,60,56],{"__ignoreMap":58},[17,62,64],{"id":63},"内容管线markdown-即数据库","内容管线：Markdown 即数据库",[13,66,67,68,71],{},"Nuxt Content 负责把 ",[47,69,70],{},"content\u002F"," 下的 Markdown 变成可查询的集合。schema 用 Zod 声明，写错 frontmatter 会在构建期直接报错，而不是等到渲染时才发现字段缺失。",[73,74,75],"h3",{"id":75},"集合定义",[52,77,81],{"className":78,"code":79,"language":80,"meta":58,"style":58},"language-ts shiki shiki-themes github-light github-dark","export default defineContentConfig({\n  collections: {\n    content: defineCollection({\n      type: 'page',\n      source: '**\u002F*.md',\n      schema: z.object({\n        title: z.string(),\n        date: z.string().optional(),\n        category: z.enum(['tech', 'life', 'project']).optional(),\n        tags: z.array(z.string()).optional(),\n        pinned: z.boolean().optional(),\n      }),\n    }),\n  },\n})\n","ts",[47,82,83,103,109,120,133,144,155,167,183,216,237,252,258,264,270],{"__ignoreMap":58},[84,85,88,92,95,99],"span",{"class":86,"line":87},"line",1,[84,89,91],{"class":90},"szBVR","export",[84,93,94],{"class":90}," default",[84,96,98],{"class":97},"sScJk"," defineContentConfig",[84,100,102],{"class":101},"sVt8B","({\n",[84,104,106],{"class":86,"line":105},2,[84,107,108],{"class":101},"  collections: {\n",[84,110,112,115,118],{"class":86,"line":111},3,[84,113,114],{"class":101},"    content: ",[84,116,117],{"class":97},"defineCollection",[84,119,102],{"class":101},[84,121,123,126,130],{"class":86,"line":122},4,[84,124,125],{"class":101},"      type: ",[84,127,129],{"class":128},"sZZnC","'page'",[84,131,132],{"class":101},",\n",[84,134,136,139,142],{"class":86,"line":135},5,[84,137,138],{"class":101},"      source: ",[84,140,141],{"class":128},"'**\u002F*.md'",[84,143,132],{"class":101},[84,145,147,150,153],{"class":86,"line":146},6,[84,148,149],{"class":101},"      schema: z.",[84,151,152],{"class":97},"object",[84,154,102],{"class":101},[84,156,158,161,164],{"class":86,"line":157},7,[84,159,160],{"class":101},"        title: z.",[84,162,163],{"class":97},"string",[84,165,166],{"class":101},"(),\n",[84,168,170,173,175,178,181],{"class":86,"line":169},8,[84,171,172],{"class":101},"        date: z.",[84,174,163],{"class":97},[84,176,177],{"class":101},"().",[84,179,180],{"class":97},"optional",[84,182,166],{"class":101},[84,184,186,189,192,195,198,201,204,206,209,212,214],{"class":86,"line":185},9,[84,187,188],{"class":101},"        category: z.",[84,190,191],{"class":97},"enum",[84,193,194],{"class":101},"([",[84,196,197],{"class":128},"'tech'",[84,199,200],{"class":101},", ",[84,202,203],{"class":128},"'life'",[84,205,200],{"class":101},[84,207,208],{"class":128},"'project'",[84,210,211],{"class":101},"]).",[84,213,180],{"class":97},[84,215,166],{"class":101},[84,217,219,222,225,228,230,233,235],{"class":86,"line":218},10,[84,220,221],{"class":101},"        tags: z.",[84,223,224],{"class":97},"array",[84,226,227],{"class":101},"(z.",[84,229,163],{"class":97},[84,231,232],{"class":101},"()).",[84,234,180],{"class":97},[84,236,166],{"class":101},[84,238,240,243,246,248,250],{"class":86,"line":239},11,[84,241,242],{"class":101},"        pinned: z.",[84,244,245],{"class":97},"boolean",[84,247,177],{"class":101},[84,249,180],{"class":97},[84,251,166],{"class":101},[84,253,255],{"class":86,"line":254},12,[84,256,257],{"class":101},"      }),\n",[84,259,261],{"class":86,"line":260},13,[84,262,263],{"class":101},"    }),\n",[84,265,267],{"class":86,"line":266},14,[84,268,269],{"class":101},"  },\n",[84,271,273],{"class":86,"line":272},15,[84,274,275],{"class":101},"})\n",[73,277,279],{"id":278},"frontmatter-字段约定","frontmatter 字段约定",[281,282,283,299],"table",{},[284,285,286],"thead",{},[287,288,289,293,296],"tr",{},[290,291,292],"th",{},"字段",[290,294,295],{},"用途",[290,297,298],{},"是否必填",[300,301,302,316,329,341,353,365],"tbody",{},[287,303,304,310,313],{},[305,306,307],"td",{},[47,308,309],{},"title",[305,311,312],{},"列表卡标题与文章页标题",[305,314,315],{},"是",[287,317,318,323,326],{},[305,319,320],{},[47,321,322],{},"description",[305,324,325],{},"摘要，用于卡片与 SEO",[305,327,328],{},"否",[287,330,331,336,339],{},[305,332,333],{},[47,334,335],{},"date",[305,337,338],{},"排序依据",[305,340,328],{},[287,342,343,348,351],{},[305,344,345],{},[47,346,347],{},"category",[305,349,350],{},"决定文章归属栏目",[305,352,328],{},[287,354,355,360,363],{},[305,356,357],{},[47,358,359],{},"tags",[305,361,362],{},"标签云与相关阅读的关联依据",[305,364,328],{},[287,366,367,372,375],{},[305,368,369],{},[47,370,371],{},"pinned",[305,373,374],{},"标记精选，卡片上加印刷编号样式",[305,376,328],{},[17,378,380],{"id":379},"ssg把整站预渲染成静态文件","SSG：把整站预渲染成静态文件",[13,382,383,386],{},[47,384,385],{},"nitro.prerender"," 里显式列出栏目路由，其余文章页交给链接爬取：",[52,388,390],{"className":78,"code":389,"language":80,"meta":58,"style":58},"nitro: {\n  preset: 'static',\n  prerender: {\n    crawlLinks: true,\n    routes: ['\u002F', '\u002Ftech', '\u002Flife', '\u002Fprojects', '\u002Fabout', '\u002Ftags', '\u002Frss.xml', '\u002Fsitemap.xml', '\u002Frobots.txt'],\n  },\n}\n",[47,391,392,400,413,420,433,487,491],{"__ignoreMap":58},[84,393,394,397],{"class":86,"line":87},[84,395,396],{"class":97},"nitro",[84,398,399],{"class":101},": {\n",[84,401,402,405,408,411],{"class":86,"line":105},[84,403,404],{"class":97},"  preset",[84,406,407],{"class":101},": ",[84,409,410],{"class":128},"'static'",[84,412,132],{"class":101},[84,414,415,418],{"class":86,"line":111},[84,416,417],{"class":97},"  prerender",[84,419,399],{"class":101},[84,421,422,425,427,431],{"class":86,"line":122},[84,423,424],{"class":97},"    crawlLinks",[84,426,407],{"class":101},[84,428,430],{"class":429},"sj4cs","true",[84,432,132],{"class":101},[84,434,435,438,441,444,446,449,451,454,456,459,461,464,466,469,471,474,476,479,481,484],{"class":86,"line":135},[84,436,437],{"class":97},"    routes",[84,439,440],{"class":101},": [",[84,442,443],{"class":128},"'\u002F'",[84,445,200],{"class":101},[84,447,448],{"class":128},"'\u002Ftech'",[84,450,200],{"class":101},[84,452,453],{"class":128},"'\u002Flife'",[84,455,200],{"class":101},[84,457,458],{"class":128},"'\u002Fprojects'",[84,460,200],{"class":101},[84,462,463],{"class":128},"'\u002Fabout'",[84,465,200],{"class":101},[84,467,468],{"class":128},"'\u002Ftags'",[84,470,200],{"class":101},[84,472,473],{"class":128},"'\u002Frss.xml'",[84,475,200],{"class":101},[84,477,478],{"class":128},"'\u002Fsitemap.xml'",[84,480,200],{"class":101},[84,482,483],{"class":128},"'\u002Frobots.txt'",[84,485,486],{"class":101},"],\n",[84,488,489],{"class":86,"line":146},[84,490,269],{"class":101},[84,492,493],{"class":86,"line":157},[84,494,495],{"class":101},"}\n",[13,497,498],{},"构建命令是一条：",[52,500,504],{"className":501,"code":502,"language":503,"meta":58,"style":58},"language-bash shiki shiki-themes github-light github-dark","pnpm generate\n","bash",[47,505,506],{"__ignoreMap":58},[84,507,508,511],{"class":86,"line":87},[84,509,510],{"class":97},"pnpm",[84,512,513],{"class":128}," generate\n",[13,515,516,517,520],{},"产物落在 ",[47,518,519],{},".output\u002Fpublic\u002F","，直接同步到服务器目录即可，不需要在服务器上装任何运行时。",[17,522,524],{"id":523},"设计令牌一套变量管两套主题","设计令牌：一套变量管两套主题",[13,526,527,528,531,532,535],{},"样式层不引入 UI 框架，令牌集中写在 ",[47,529,530],{},":root"," 与 ",[47,533,534],{},"html[data-theme=\"dark\"]"," 两个作用域里，组件样式只引用变量：",[52,537,541],{"className":538,"code":539,"language":540,"meta":58,"style":58},"language-css shiki shiki-themes github-light github-dark",":root {\n  --bg: #F7F4EE;\n  --surface: #FFFDF8;\n  --text: #1A1A1A;\n  --text-muted: #6B6558;\n  --accent: #C8492F;\n  --line: #E2DCCF;\n  --radius: 2px;\n}\n\nhtml[data-theme=\"dark\"] {\n  --bg: #131313;\n  --surface: #1C1C1C;\n  --text: #E8E4DC;\n  --text-muted: #9A948A;\n  --accent: #E4694E;\n  --line: #2E2E2E;\n}\n","css",[47,542,543,550,564,576,588,600,612,624,639,643,649,670,681,692,703,714,726,738],{"__ignoreMap":58},[84,544,545,547],{"class":86,"line":87},[84,546,530],{"class":97},[84,548,549],{"class":101}," {\n",[84,551,552,556,558,561],{"class":86,"line":105},[84,553,555],{"class":554},"s4XuR","  --bg",[84,557,407],{"class":101},[84,559,560],{"class":429},"#F7F4EE",[84,562,563],{"class":101},";\n",[84,565,566,569,571,574],{"class":86,"line":111},[84,567,568],{"class":554},"  --surface",[84,570,407],{"class":101},[84,572,573],{"class":429},"#FFFDF8",[84,575,563],{"class":101},[84,577,578,581,583,586],{"class":86,"line":122},[84,579,580],{"class":554},"  --text",[84,582,407],{"class":101},[84,584,585],{"class":429},"#1A1A1A",[84,587,563],{"class":101},[84,589,590,593,595,598],{"class":86,"line":135},[84,591,592],{"class":554},"  --text-muted",[84,594,407],{"class":101},[84,596,597],{"class":429},"#6B6558",[84,599,563],{"class":101},[84,601,602,605,607,610],{"class":86,"line":146},[84,603,604],{"class":554},"  --accent",[84,606,407],{"class":101},[84,608,609],{"class":429},"#C8492F",[84,611,563],{"class":101},[84,613,614,617,619,622],{"class":86,"line":157},[84,615,616],{"class":554},"  --line",[84,618,407],{"class":101},[84,620,621],{"class":429},"#E2DCCF",[84,623,563],{"class":101},[84,625,626,629,631,634,637],{"class":86,"line":169},[84,627,628],{"class":554},"  --radius",[84,630,407],{"class":101},[84,632,633],{"class":429},"2",[84,635,636],{"class":90},"px",[84,638,563],{"class":101},[84,640,641],{"class":86,"line":185},[84,642,495],{"class":101},[84,644,645],{"class":86,"line":218},[84,646,648],{"emptyLinePlaceholder":647},true,"\n",[84,650,651,655,658,661,664,667],{"class":86,"line":239},[84,652,654],{"class":653},"s9eBZ","html",[84,656,657],{"class":101},"[",[84,659,660],{"class":97},"data-theme",[84,662,663],{"class":90},"=",[84,665,666],{"class":128},"\"dark\"",[84,668,669],{"class":101},"] {\n",[84,671,672,674,676,679],{"class":86,"line":254},[84,673,555],{"class":554},[84,675,407],{"class":101},[84,677,678],{"class":429},"#131313",[84,680,563],{"class":101},[84,682,683,685,687,690],{"class":86,"line":260},[84,684,568],{"class":554},[84,686,407],{"class":101},[84,688,689],{"class":429},"#1C1C1C",[84,691,563],{"class":101},[84,693,694,696,698,701],{"class":86,"line":266},[84,695,580],{"class":554},[84,697,407],{"class":101},[84,699,700],{"class":429},"#E8E4DC",[84,702,563],{"class":101},[84,704,705,707,709,712],{"class":86,"line":272},[84,706,592],{"class":554},[84,708,407],{"class":101},[84,710,711],{"class":429},"#9A948A",[84,713,563],{"class":101},[84,715,717,719,721,724],{"class":86,"line":716},16,[84,718,604],{"class":554},[84,720,407],{"class":101},[84,722,723],{"class":429},"#E4694E",[84,725,563],{"class":101},[84,727,729,731,733,736],{"class":86,"line":728},17,[84,730,616],{"class":554},[84,732,407],{"class":101},[84,734,735],{"class":429},"#2E2E2E",[84,737,563],{"class":101},[84,739,741],{"class":86,"line":740},18,[84,742,495],{"class":101},[13,744,745],{},"字体走系统栈，不加载任何网络字体 —— 首屏少一次往返，也避免了字体闪烁。",[17,747,748],{"id":748},"主题切换不闪白",[13,750,751,752,755,756,759,760,762,763,766],{},"深色偏好在 ",[47,753,754],{},"localStorage"," 里，若只靠客户端 hydration 后切换，首屏一定闪一下浅色。解法是把一段极短的判断脚本内联进 ",[47,757,758],{},"\u003Chead>","，在 CSS 生效前就把 ",[47,761,660],{}," 写到 ",[47,764,765],{},"\u003Chtml>"," 上：",[52,768,772],{"className":769,"code":770,"language":771,"meta":58,"style":58},"language-js shiki shiki-themes github-light github-dark","(function () {\n  try {\n    var saved = localStorage.getItem('rainink-theme')\n    var dark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n    document.documentElement.setAttribute('data-theme', saved || (dark ? 'dark' : 'light'))\n  } catch (e) {\n    document.documentElement.setAttribute('data-theme', 'light')\n  }\n})()\n","js",[47,773,774,785,792,816,845,882,893,910,915],{"__ignoreMap":58},[84,775,776,779,782],{"class":86,"line":87},[84,777,778],{"class":101},"(",[84,780,781],{"class":90},"function",[84,783,784],{"class":101}," () {\n",[84,786,787,790],{"class":86,"line":105},[84,788,789],{"class":90},"  try",[84,791,549],{"class":101},[84,793,794,797,800,802,805,808,810,813],{"class":86,"line":111},[84,795,796],{"class":90},"    var",[84,798,799],{"class":101}," saved ",[84,801,663],{"class":90},[84,803,804],{"class":101}," localStorage.",[84,806,807],{"class":97},"getItem",[84,809,778],{"class":101},[84,811,812],{"class":128},"'rainink-theme'",[84,814,815],{"class":101},")\n",[84,817,818,820,823,825,828,831,834,837,839,842],{"class":86,"line":122},[84,819,796],{"class":90},[84,821,822],{"class":101}," dark ",[84,824,663],{"class":90},[84,826,827],{"class":101}," window.matchMedia ",[84,829,830],{"class":90},"&&",[84,832,833],{"class":101}," window.",[84,835,836],{"class":97},"matchMedia",[84,838,778],{"class":101},[84,840,841],{"class":128},"'(prefers-color-scheme: dark)'",[84,843,844],{"class":101},").matches\n",[84,846,847,850,853,855,858,861,864,867,870,873,876,879],{"class":86,"line":135},[84,848,849],{"class":101},"    document.documentElement.",[84,851,852],{"class":97},"setAttribute",[84,854,778],{"class":101},[84,856,857],{"class":128},"'data-theme'",[84,859,860],{"class":101},", saved ",[84,862,863],{"class":90},"||",[84,865,866],{"class":101}," (dark ",[84,868,869],{"class":90},"?",[84,871,872],{"class":128}," 'dark'",[84,874,875],{"class":90}," :",[84,877,878],{"class":128}," 'light'",[84,880,881],{"class":101},"))\n",[84,883,884,887,890],{"class":86,"line":146},[84,885,886],{"class":101},"  } ",[84,888,889],{"class":90},"catch",[84,891,892],{"class":101}," (e) {\n",[84,894,895,897,899,901,903,905,908],{"class":86,"line":157},[84,896,849],{"class":101},[84,898,852],{"class":97},[84,900,778],{"class":101},[84,902,857],{"class":128},[84,904,200],{"class":101},[84,906,907],{"class":128},"'light'",[84,909,815],{"class":101},[84,911,912],{"class":86,"line":169},[84,913,914],{"class":101},"  }\n",[84,916,917],{"class":86,"line":185},[84,918,919],{"class":101},"})()\n",[13,921,922,925,926,928],{},[47,923,924],{},"try\u002Fcatch"," 是为了无痕模式下 ",[47,927,754],{}," 抛异常时仍能兜底成浅色。",[17,930,931],{"id":931},"踩坑清单",[28,933,934,950,973],{},[31,935,936,945,946,949],{},[937,938,939,531,942,944],"strong",{},[47,940,941],{},"string[]",[47,943,163],{}," 一字之差","：项目陈列的 ",[47,947,948],{},"stack"," 一开始声明成字符串，写数组时构建直接失败——这是好事，schema 就是用来挡这类错误的。",[31,951,952,960,961,964,965,968,969,972],{},[937,953,954,957,958],{},[47,955,956],{},"~\u002F"," 别名指向 ",[47,959,49],{},"：Nuxt 4 里 ",[47,962,963],{},"~\u002Fassets\u002F..."," 实际解析到 ",[47,966,967],{},"app\u002Fassets\u002F...","，",[47,970,971],{},"public\u002F"," 例外。",[31,974,975,978,979,982,983,985,986,989],{},[937,976,977],{},"首屏底图要内联","：SVG 用 ",[47,980,981],{},"?raw"," 导入后内联渲染，才能跟着 ",[47,984,660],{}," 换墨色；换成 ",[47,987,988],{},"\u003Cimg>"," 就失去主题联动能力。",[17,991,992],{"id":992},"小结",[13,994,995],{},"对一个内容更新不快、样式要求却很具体的个人站来说，「Markdown 文件 + 静态产物」是维护成本最低的组合。真正花时间的不是框架接入，而是设计令牌和交互细节的打磨 —— 那部分下一篇再说。",[997,998,999],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}",{"title":58,"searchDepth":105,"depth":105,"links":1001},[1002,1003,1004,1008,1009,1010,1011,1012],{"id":19,"depth":105,"text":20},{"id":42,"depth":105,"text":42},{"id":63,"depth":105,"text":64,"children":1005},[1006,1007],{"id":75,"depth":111,"text":75},{"id":278,"depth":111,"text":279},{"id":379,"depth":105,"text":380},{"id":523,"depth":105,"text":524},{"id":748,"depth":105,"text":748},{"id":931,"depth":105,"text":931},{"id":992,"depth":105,"text":992},"tech",null,"2026-10-12","站点骨架的取舍：内容目录怎么定、SSG 怎么预渲染、设计令牌怎么从原型抽成一套 CSS 变量，以及首屏主题闪烁的解法。",false,"md",{},"\u002Fposts\u002Fnuxt4-static-site",{"title":5,"description":1016},"posts\u002Fnuxt4-static-site",[1024,1025,1026,1027],"Nuxt","Nuxt Content","SSG","前端工程化","2026-10-18","BEymHrrE6Yh7yiAfOoBmz0sSUyh0NtXVnD68IrrOVUs",{"all":1031,"posts":1124,"essays":1134,"projects":1141,"tags":1151},[1032,1039,1051,1062,1074,1083,1100,1114],{"title":5,"description":1016,"path":1020,"slug":1033,"category":1013,"categoryLabel":1034,"kind":1035,"tags":1036,"date":1015,"updated":1028,"minutes":135,"pinned":647,"draft":1017,"order":1037,"stack":1038,"period":58,"repo":58,"thumb":58},"nuxt4-static-site","技术","post",[1024,1025,1026,1027],0,[],{"title":1040,"description":1041,"path":1042,"slug":1043,"category":1013,"categoryLabel":1034,"kind":1035,"tags":1044,"date":1049,"updated":58,"minutes":135,"pinned":1017,"draft":1017,"order":1037,"stack":1050,"period":58,"repo":58,"thumb":58},"B 端后台底座：把权限、菜单、请求收敛成三层","后台系统做多了会发现，真正需要沉淀的不是页面，而是权限模型、动态菜单和请求层这三块底座。","\u002Fposts\u002Fvue3-admin-base","vue3-admin-base",[1045,1046,1047,1048],"Vue","后台","架构","权限","2026-09-24",[],{"title":1052,"description":1053,"path":1054,"slug":1055,"category":1013,"categoryLabel":1034,"kind":1035,"tags":1056,"date":1060,"updated":58,"minutes":135,"pinned":1017,"draft":1017,"order":1037,"stack":1061,"period":58,"repo":58,"thumb":58},"工作流引擎实操笔记：节点、流转与幂等","从状态机到可配置流程：一次工作流引擎落地中关于节点模型、流转条件、幂等与补偿的实操记录。","\u002Fposts\u002Fworkflow-engine-notes","workflow-engine-notes",[1057,1058,1047,1059],"工作流","后端","幂等","2026-08-30",[],{"title":1063,"description":1064,"path":1065,"slug":1066,"category":1067,"categoryLabel":1068,"kind":1035,"tags":1069,"date":1072,"updated":58,"minutes":87,"pinned":1017,"draft":1017,"order":1037,"stack":1073,"period":58,"repo":58,"thumb":58},"上半年读书清单：几本反复翻的技术书","上半年读完与重读的几本书，以及它们各自解决了我在工程实践中的哪个具体问题。","\u002Fposts\u002Freading-2026-h1","reading-2026-h1","life","随笔",[1070,1068,1071],"阅读","效率","2026-07-06",[],{"title":1075,"description":1076,"path":1077,"slug":1078,"category":1067,"categoryLabel":1068,"kind":1035,"tags":1079,"date":1081,"updated":58,"minutes":105,"pinned":1017,"draft":1017,"order":1037,"stack":1082,"period":58,"repo":58,"thumb":58},"我的写作与输入工具链","从收集、整理到成稿：一套尽量少依赖工具的写作流程，以及几个用了三年以上没换过的选择。","\u002Fposts\u002Ftools-and-writing","tools-and-writing",[1080,1071,1068],"工具","2026-06-15",[],{"title":1084,"description":1085,"path":1086,"slug":1087,"category":1088,"categoryLabel":1089,"kind":1088,"tags":1090,"date":1091,"updated":58,"minutes":87,"pinned":1017,"draft":1017,"order":87,"stack":1092,"period":1098,"repo":58,"thumb":1099},"Super Admin 后台底座","一套可复用的 B 端后台前端底座：权限三层收敛、动态菜单、请求层封装与通用表格表单组件，新项目接入只需替换业务页面。","\u002Fprojects\u002Fsuper-admin","super-admin","project","项目",[1045,1046,1027],"2026-05-20",[1093,1094,1095,1096,1097],"Vue 3","TypeScript","Vite","Pinia","Element Plus","2026 年至今","SA",{"title":1101,"description":1102,"path":1103,"slug":1104,"category":1088,"categoryLabel":1089,"kind":1088,"tags":1105,"date":1106,"updated":58,"minutes":87,"pinned":1017,"draft":1017,"order":105,"stack":1107,"period":1112,"repo":58,"thumb":1113},"轻量工作流引擎","面向审批场景的轻量工作流：节点与连线可配置，支持条件分支、抄送、超时补偿，重点解决幂等与流程改版两类问题。","\u002Fprojects\u002Fworkflow-engine","workflow-engine",[1057,1058,1047],"2026-04-08",[1108,1109,1110,1111],"Spring Boot","MyBatis","MySQL","Redis","2026 年上半年","WF",{"title":1115,"description":1116,"path":1117,"slug":1118,"category":1088,"categoryLabel":1089,"kind":1088,"tags":1119,"date":1028,"updated":58,"minutes":87,"pinned":1017,"draft":1017,"order":111,"stack":1120,"period":1122,"repo":58,"thumb":1123},"雨墨 RainInk 本站","你正在看的这个站：Nuxt 4 + Nuxt Content 的纯静态个人站，手写设计令牌、无评论无用户输入、产物可直接静态托管。","\u002Fprojects\u002Frainink-site","rainink-site",[1024,1026,1027],[1121,1093,1025,1094],"Nuxt 4","2026 年 10 月","RI",[1125,1128,1131],{"title":5,"description":1016,"path":1020,"slug":1033,"category":1013,"categoryLabel":1034,"kind":1035,"tags":1126,"date":1015,"updated":1028,"minutes":135,"pinned":647,"draft":1017,"order":1037,"stack":1127,"period":58,"repo":58,"thumb":58},[1024,1025,1026,1027],[],{"title":1040,"description":1041,"path":1042,"slug":1043,"category":1013,"categoryLabel":1034,"kind":1035,"tags":1129,"date":1049,"updated":58,"minutes":135,"pinned":1017,"draft":1017,"order":1037,"stack":1130,"period":58,"repo":58,"thumb":58},[1045,1046,1047,1048],[],{"title":1052,"description":1053,"path":1054,"slug":1055,"category":1013,"categoryLabel":1034,"kind":1035,"tags":1132,"date":1060,"updated":58,"minutes":135,"pinned":1017,"draft":1017,"order":1037,"stack":1133,"period":58,"repo":58,"thumb":58},[1057,1058,1047,1059],[],[1135,1138],{"title":1063,"description":1064,"path":1065,"slug":1066,"category":1067,"categoryLabel":1068,"kind":1035,"tags":1136,"date":1072,"updated":58,"minutes":87,"pinned":1017,"draft":1017,"order":1037,"stack":1137,"period":58,"repo":58,"thumb":58},[1070,1068,1071],[],{"title":1075,"description":1076,"path":1077,"slug":1078,"category":1067,"categoryLabel":1068,"kind":1035,"tags":1139,"date":1081,"updated":58,"minutes":105,"pinned":1017,"draft":1017,"order":1037,"stack":1140,"period":58,"repo":58,"thumb":58},[1080,1071,1068],[],[1142,1145,1148],{"title":1084,"description":1085,"path":1086,"slug":1087,"category":1088,"categoryLabel":1089,"kind":1088,"tags":1143,"date":1091,"updated":58,"minutes":87,"pinned":1017,"draft":1017,"order":87,"stack":1144,"period":1098,"repo":58,"thumb":1099},[1045,1046,1027],[1093,1094,1095,1096,1097],{"title":1101,"description":1102,"path":1103,"slug":1104,"category":1088,"categoryLabel":1089,"kind":1088,"tags":1146,"date":1106,"updated":58,"minutes":87,"pinned":1017,"draft":1017,"order":105,"stack":1147,"period":1112,"repo":58,"thumb":1113},[1057,1058,1047],[1108,1109,1110,1111],{"title":1115,"description":1116,"path":1117,"slug":1118,"category":1088,"categoryLabel":1089,"kind":1088,"tags":1149,"date":1028,"updated":58,"minutes":87,"pinned":1017,"draft":1017,"order":111,"stack":1150,"period":1122,"repo":58,"thumb":1123},[1024,1026,1027],[1121,1093,1025,1094],[1152,1154,1155,1156,1158,1159,1160,1161,1162,1163,1164,1165,1166,1167,1168],{"name":1071,"count":105,"weight":1153},1.6,{"name":1047,"count":105,"weight":1153},{"name":1068,"count":105,"weight":1153},{"name":1024,"count":87,"weight":1157},1.25,{"name":1025,"count":87,"weight":1157},{"name":1026,"count":87,"weight":1157},{"name":1045,"count":87,"weight":1157},{"name":1027,"count":87,"weight":1157},{"name":1046,"count":87,"weight":1157},{"name":1058,"count":87,"weight":1157},{"name":1057,"count":87,"weight":1157},{"name":1080,"count":87,"weight":1157},{"name":1059,"count":87,"weight":1157},{"name":1048,"count":87,"weight":1157},{"name":1070,"count":87,"weight":1157},1792657178959]