[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"recent-posts":3,"featured-projects":718},[4,373],{"id":5,"title":6,"body":7,"date":358,"description":359,"draft":360,"extension":361,"featured":362,"image":363,"meta":364,"navigation":362,"path":365,"seo":366,"stem":367,"tags":368,"__hash__":372},"blog\u002Fblog\u002Fhello-world.md","使用 Nuxt 3 + Nuxt UI 搭建个人网站",{"type":8,"value":9,"toc":349},"minimark",[10,15,19,48,51,108,111,116,119,195,199,202,339,342,345],[11,12,14],"h2",{"id":13},"为什么选择-nuxt","为什么选择 Nuxt？",[16,17,18],"p",{},"Nuxt 3 是一个基于 Vue 3 的全栈框架，提供了：",[20,21,22,30,36,42],"ul",{},[23,24,25,29],"li",{},[26,27,28],"strong",{},"文件路由","：创建文件即创建路由",[23,31,32,35],{},[26,33,34],{},"自动导入","：组件和工具函数无需手动导入",[23,37,38,41],{},[26,39,40],{},"SSR\u002FSSG","：灵活的服务端渲染和静态生成",[23,43,44,47],{},[26,45,46],{},"模块生态","：丰富的官方和社区模块",[11,49,50],{"id":50},"快速开始",[52,53,58],"pre",{"className":54,"code":55,"language":56,"meta":57,"style":57},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","npx nuxi@latest init my-website -t ui\ncd my-website\nnpm run dev\n","bash","",[59,60,61,86,96],"code",{"__ignoreMap":57},[62,63,66,70,74,77,80,83],"span",{"class":64,"line":65},"line",1,[62,67,69],{"class":68},"sBMFI","npx",[62,71,73],{"class":72},"sfazB"," nuxi@latest",[62,75,76],{"class":72}," init",[62,78,79],{"class":72}," my-website",[62,81,82],{"class":72}," -t",[62,84,85],{"class":72}," ui\n",[62,87,89,93],{"class":64,"line":88},2,[62,90,92],{"class":91},"s2Zo4","cd",[62,94,95],{"class":72}," my-website\n",[62,97,99,102,105],{"class":64,"line":98},3,[62,100,101],{"class":68},"npm",[62,103,104],{"class":72}," run",[62,106,107],{"class":72}," dev\n",[11,109,110],{"id":110},"核心模块",[112,113,115],"h3",{"id":114},"nuxtui","@nuxt\u002Fui",[16,117,118],{},"内置 100+ 组件，基于 Tailwind CSS，支持暗色模式。",[52,120,124],{"className":121,"code":122,"language":123,"meta":57,"style":57},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Ctemplate>\n  \u003CUButton color=\"primary\">点击我\u003C\u002FUButton>\n  \u003CUColorModeButton \u002F>\n\u003C\u002Ftemplate>\n","vue",[59,125,126,139,176,186],{"__ignoreMap":57},[62,127,128,132,136],{"class":64,"line":65},[62,129,131],{"class":130},"sMK4o","\u003C",[62,133,135],{"class":134},"swJcz","template",[62,137,138],{"class":130},">\n",[62,140,141,144,147,151,154,157,160,162,165,169,172,174],{"class":64,"line":88},[62,142,143],{"class":130},"  \u003C",[62,145,146],{"class":134},"UButton",[62,148,150],{"class":149},"spNyl"," color",[62,152,153],{"class":130},"=",[62,155,156],{"class":130},"\"",[62,158,159],{"class":72},"primary",[62,161,156],{"class":130},[62,163,164],{"class":130},">",[62,166,168],{"class":167},"sTEyZ","点击我",[62,170,171],{"class":130},"\u003C\u002F",[62,173,146],{"class":134},[62,175,138],{"class":130},[62,177,178,180,183],{"class":64,"line":98},[62,179,143],{"class":130},[62,181,182],{"class":134},"UColorModeButton",[62,184,185],{"class":130}," \u002F>\n",[62,187,189,191,193],{"class":64,"line":188},4,[62,190,171],{"class":130},[62,192,135],{"class":134},[62,194,138],{"class":130},[112,196,198],{"id":197},"nuxtcontent","@nuxt\u002Fcontent",[16,200,201],{},"Markdown 驱动的内容管理，类型安全的查询。",[52,203,207],{"className":204,"code":205,"language":206,"meta":57,"style":57},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","const { data } = await useAsyncData(() =>\n  queryCollection('blog')\n    .where('draft', '!=', true)\n    .order('date', 'DESC')\n    .all()\n)\n","ts",[59,208,209,242,260,296,323,334],{"__ignoreMap":57},[62,210,211,214,217,220,223,226,230,233,236,239],{"class":64,"line":65},[62,212,213],{"class":149},"const",[62,215,216],{"class":130}," {",[62,218,219],{"class":167}," data ",[62,221,222],{"class":130},"}",[62,224,225],{"class":130}," =",[62,227,229],{"class":228},"s7zQu"," await",[62,231,232],{"class":91}," useAsyncData",[62,234,235],{"class":167},"(",[62,237,238],{"class":130},"()",[62,240,241],{"class":149}," =>\n",[62,243,244,247,249,252,255,257],{"class":64,"line":88},[62,245,246],{"class":91},"  queryCollection",[62,248,235],{"class":167},[62,250,251],{"class":130},"'",[62,253,254],{"class":72},"blog",[62,256,251],{"class":130},[62,258,259],{"class":167},")\n",[62,261,262,265,268,270,272,275,277,280,283,286,288,290,294],{"class":64,"line":98},[62,263,264],{"class":130},"    .",[62,266,267],{"class":91},"where",[62,269,235],{"class":167},[62,271,251],{"class":130},[62,273,274],{"class":72},"draft",[62,276,251],{"class":130},[62,278,279],{"class":130},",",[62,281,282],{"class":130}," '",[62,284,285],{"class":72},"!=",[62,287,251],{"class":130},[62,289,279],{"class":130},[62,291,293],{"class":292},"sfNiH"," true",[62,295,259],{"class":167},[62,297,298,300,303,305,307,310,312,314,316,319,321],{"class":64,"line":188},[62,299,264],{"class":130},[62,301,302],{"class":91},"order",[62,304,235],{"class":167},[62,306,251],{"class":130},[62,308,309],{"class":72},"date",[62,311,251],{"class":130},[62,313,279],{"class":130},[62,315,282],{"class":130},[62,317,318],{"class":72},"DESC",[62,320,251],{"class":130},[62,322,259],{"class":167},[62,324,326,328,331],{"class":64,"line":325},5,[62,327,264],{"class":130},[62,329,330],{"class":91},"all",[62,332,333],{"class":167},"()\n",[62,335,337],{"class":64,"line":336},6,[62,338,259],{"class":167},[11,340,341],{"id":341},"小结",[16,343,344],{},"Nuxt 3 生态让构建个人网站变得简单高效。",[346,347,348],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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 .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":57,"searchDepth":88,"depth":88,"links":350},[351,352,353,357],{"id":13,"depth":88,"text":14},{"id":50,"depth":88,"text":50},{"id":110,"depth":88,"text":110,"children":354},[355,356],{"id":114,"depth":98,"text":115},{"id":197,"depth":98,"text":198},{"id":341,"depth":88,"text":341},"2026-07-03","一篇完整的教程，带你从零开始用 Nuxt 3 和 Nuxt UI 搭建现代化个人网站，支持暗色模式、响应式布局。",false,"md",true,null,{},"\u002Fblog\u002Fhello-world",{"title":6,"description":359},"blog\u002Fhello-world",[369,123,370,371],"nuxt","typescript","tutorial","MvNAvNYjefFzOMDNdEFcJh8ON6dzpvCZ7zfBcP2nQBU",{"id":374,"title":375,"body":376,"date":709,"description":710,"draft":360,"extension":361,"featured":360,"image":363,"meta":711,"navigation":362,"path":712,"seo":713,"stem":714,"tags":715,"__hash__":717},"blog\u002Fblog\u002Ftypescript-tips.md","TypeScript 高级类型技巧",{"type":8,"value":377,"toc":703},[378,381,384,479,482,485,600,603,606,680,683,700],[11,379,380],{"id":380},"条件类型",[16,382,383],{},"条件类型根据条件选择不同的类型：",[52,385,387],{"className":204,"code":386,"language":206,"meta":57,"style":57},"type IsString\u003CT> = T extends string ? true : false\n\ntype A = IsString\u003C'hello'>  \u002F\u002F true\ntype B = IsString\u003C42>       \u002F\u002F false\n",[59,388,389,426,431,457],{"__ignoreMap":57},[62,390,391,394,397,399,402,404,406,409,412,415,418,420,423],{"class":64,"line":65},[62,392,393],{"class":149},"type",[62,395,396],{"class":68}," IsString",[62,398,131],{"class":130},[62,400,401],{"class":68},"T",[62,403,164],{"class":130},[62,405,225],{"class":130},[62,407,408],{"class":68}," T",[62,410,411],{"class":149}," extends",[62,413,414],{"class":68}," string",[62,416,417],{"class":130}," ?",[62,419,293],{"class":68},[62,421,422],{"class":130}," :",[62,424,425],{"class":68}," false\n",[62,427,428],{"class":64,"line":88},[62,429,430],{"emptyLinePlaceholder":362},"\n",[62,432,433,435,438,440,442,444,446,449,451,453],{"class":64,"line":98},[62,434,393],{"class":149},[62,436,437],{"class":68}," A",[62,439,225],{"class":130},[62,441,396],{"class":68},[62,443,131],{"class":130},[62,445,251],{"class":130},[62,447,448],{"class":72},"hello",[62,450,251],{"class":130},[62,452,164],{"class":130},[62,454,456],{"class":455},"sHwdD","  \u002F\u002F true\n",[62,458,459,461,464,466,468,470,474,476],{"class":64,"line":188},[62,460,393],{"class":149},[62,462,463],{"class":68}," B",[62,465,225],{"class":130},[62,467,396],{"class":68},[62,469,131],{"class":130},[62,471,473],{"class":472},"sbssI","42",[62,475,164],{"class":130},[62,477,478],{"class":455},"       \u002F\u002F false\n",[11,480,481],{"id":481},"映射类型",[16,483,484],{},"基于已有类型创建新类型：",[52,486,488],{"className":204,"code":487,"language":206,"meta":57,"style":57},"type Readonly\u003CT> = {\n  readonly [K in keyof T]: T[K]\n}\n\ntype Partial\u003CT> = {\n  [K in keyof T]?: T[K]\n}\n",[59,489,490,508,543,548,552,569,595],{"__ignoreMap":57},[62,491,492,494,497,499,501,503,505],{"class":64,"line":65},[62,493,393],{"class":149},[62,495,496],{"class":68}," Readonly",[62,498,131],{"class":130},[62,500,401],{"class":68},[62,502,164],{"class":130},[62,504,225],{"class":130},[62,506,507],{"class":130}," {\n",[62,509,510,513,516,519,522,525,527,530,533,535,538,540],{"class":64,"line":88},[62,511,512],{"class":149},"  readonly",[62,514,515],{"class":167}," [",[62,517,518],{"class":68},"K",[62,520,521],{"class":130}," in",[62,523,524],{"class":130}," keyof",[62,526,408],{"class":68},[62,528,529],{"class":167},"]",[62,531,532],{"class":130},":",[62,534,408],{"class":68},[62,536,537],{"class":167},"[",[62,539,518],{"class":68},[62,541,542],{"class":167},"]\n",[62,544,545],{"class":64,"line":98},[62,546,547],{"class":130},"}\n",[62,549,550],{"class":64,"line":188},[62,551,430],{"emptyLinePlaceholder":362},[62,553,554,556,559,561,563,565,567],{"class":64,"line":325},[62,555,393],{"class":149},[62,557,558],{"class":68}," Partial",[62,560,131],{"class":130},[62,562,401],{"class":68},[62,564,164],{"class":130},[62,566,225],{"class":130},[62,568,507],{"class":130},[62,570,571,574,576,578,580,582,584,587,589,591,593],{"class":64,"line":336},[62,572,573],{"class":167},"  [",[62,575,518],{"class":68},[62,577,521],{"class":130},[62,579,524],{"class":130},[62,581,408],{"class":68},[62,583,529],{"class":167},[62,585,586],{"class":130},"?:",[62,588,408],{"class":68},[62,590,537],{"class":167},[62,592,518],{"class":68},[62,594,542],{"class":167},[62,596,598],{"class":64,"line":597},7,[62,599,547],{"class":130},[11,601,602],{"id":602},"模板字面量类型",[16,604,605],{},"对字符串字面量类型做模式匹配：",[52,607,609],{"className":204,"code":608,"language":206,"meta":57,"style":57},"type EventName\u003CT extends string> = `on${Capitalize\u003CT>}`\n\ntype Click = EventName\u003C'click'>  \u002F\u002F 'onClick'\n",[59,610,611,651,655],{"__ignoreMap":57},[62,612,613,615,618,620,622,624,626,628,630,633,636,639,642,644,646,648],{"class":64,"line":65},[62,614,393],{"class":149},[62,616,617],{"class":68}," EventName",[62,619,131],{"class":130},[62,621,401],{"class":68},[62,623,411],{"class":149},[62,625,414],{"class":68},[62,627,164],{"class":130},[62,629,225],{"class":130},[62,631,632],{"class":130}," `",[62,634,635],{"class":72},"on",[62,637,638],{"class":130},"${",[62,640,641],{"class":68},"Capitalize",[62,643,131],{"class":130},[62,645,401],{"class":68},[62,647,164],{"class":130},[62,649,650],{"class":130},"}`\n",[62,652,653],{"class":64,"line":88},[62,654,430],{"emptyLinePlaceholder":362},[62,656,657,659,662,664,666,668,670,673,675,677],{"class":64,"line":98},[62,658,393],{"class":149},[62,660,661],{"class":68}," Click",[62,663,225],{"class":130},[62,665,617],{"class":68},[62,667,131],{"class":130},[62,669,251],{"class":130},[62,671,672],{"class":72},"click",[62,674,251],{"class":130},[62,676,164],{"class":130},[62,678,679],{"class":455},"  \u002F\u002F 'onClick'\n",[11,681,682],{"id":682},"实用工具类型",[16,684,685,686,689,690,689,693,689,696,699],{},"TypeScript 内置了很多实用的工具类型，如 ",[59,687,688],{},"Pick",", ",[59,691,692],{},"Omit",[59,694,695],{},"Exclude",[59,697,698],{},"Extract"," 等。",[346,701,702],{},"html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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 .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}",{"title":57,"searchDepth":88,"depth":88,"links":704},[705,706,707,708],{"id":380,"depth":88,"text":380},{"id":481,"depth":88,"text":481},{"id":602,"depth":88,"text":602},{"id":682,"depth":88,"text":682},"2026-06-20","总结日常开发中常用的 TypeScript 高级类型用法，包括条件类型、映射类型、模板字面量类型等。",{},"\u002Fblog\u002Ftypescript-tips",{"title":375,"description":710},"blog\u002Ftypescript-tips",[370,716],"frontend","5pNMWjrmQxpbEUknNBR8ONXmblBf4Vg2exSTV4j1sKQ",[719],{"id":720,"title":721,"body":722,"date":772,"description":773,"extension":361,"featured":362,"image":363,"meta":774,"navigation":362,"path":775,"repo":776,"seo":777,"status":778,"stem":779,"tags":780,"techStack":783,"url":788,"__hash__":789},"projects\u002Fprojects\u002Fmarkdown-editor.md","Markdown Editor",{"type":8,"value":723,"toc":767},[724,727,730,733,750,753,756],[11,725,726],{"id":726},"项目背景",[16,728,729],{},"在日常写作中，我需要一个支持 Markdown 语法的编辑器。市面上的方案要么太重量级，要么定制性不够。于是我基于 ProseMirror 构建了这款编辑器。",[11,731,732],{"id":732},"核心功能",[20,734,735,738,741,744,747],{},[23,736,737],{},"实时 Markdown 渲染预览",[23,739,740],{},"代码块语法高亮",[23,742,743],{},"自定义扩展系统",[23,745,746],{},"键盘快捷键支持",[23,748,749],{},"暗色模式适配",[11,751,752],{"id":752},"技术选型",[16,754,755],{},"ProseMirror 是编辑器领域最成熟的框架之一，提供了：",[20,757,758,761,764],{},[23,759,760],{},"强大的 Schema 系统",[23,762,763],{},"事务性编辑模型",[23,765,766],{},"Plugin 架构便于扩展",{"title":57,"searchDepth":88,"depth":88,"links":768},[769,770,771],{"id":726,"depth":88,"text":726},{"id":732,"depth":88,"text":732},{"id":752,"depth":88,"text":752},"2026-06-15","一个基于 ProseMirror 的 Markdown 编辑器，支持实时预览、语法高亮和自定义扩展。",{},"\u002Fprojects\u002Fmarkdown-editor","https:\u002F\u002Fgithub.com\u002Fuser\u002Fmarkdown-editor",{"title":721,"description":773},"active","projects\u002Fmarkdown-editor",[123,781,782],"editor","markdown",[784,785,786,787],"Vue 3","TypeScript","ProseMirror","Node.js","https:\u002F\u002Feditor.example.com","S0MFPF3c9hiA--s2caiOY9Gs1nsi1KZod4tLSor1Cno"]