[{"data":1,"prerenderedAt":7458},["ShallowReactive",2],{"blog-2LK7M1":3,"blog-all":2673},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"body":11,"_type":2666,"_id":2667,"_source":2668,"_file":2669,"_stem":2670,"_extension":2671,"code":2672},"\u002Fblog\u002F3-post","blog",false,"","Nuxt 4 博客重构实战：实现动态文章目录与阅读进度条","使用 Intersection Observer 与 requestAnimationFrame 优化长文阅读体验","2026-06-17",{"type":12,"children":13,"toc":2655},"root",[14,22,36,55,62,67,74,102,993,999,1019,1527,1569,1575,1580,1586,1606,2220,2226,2239,2519,2527,2566,2572,2584,2629,2645,2650],{"type":15,"tag":16,"props":17,"children":19},"element","h1",{"id":18},"nuxt-4-博客重构实战实现动态文章目录与阅读进度条",[20],{"type":21,"value":8},"text",{"type":15,"tag":23,"props":24,"children":25},"p",{},[26,28,34],{"type":21,"value":27},"在技术博客的重构过程中，内容固然重要，但",{"type":15,"tag":29,"props":30,"children":31},"strong",{},[32],{"type":21,"value":33},"阅读体验",{"type":21,"value":35},"往往决定了读者能否耐心看完一篇长文。作为一个前端开发者，我始终认为博客不仅是内容的载体，更是前端技术的试验田。",{"type":15,"tag":23,"props":37,"children":38},{},[39,41,53],{"type":21,"value":40},"在将博客迁移到 Nuxt 4 的过程中，我决定为文章页加入两个核心体验优化：",{"type":15,"tag":29,"props":42,"children":43},{},[44,46,51],{"type":21,"value":45},"动态文章目录（TOC）",{"type":15,"tag":29,"props":47,"children":48},{},[49],{"type":21,"value":50},"和",{"type":21,"value":52},"沉浸式阅读进度条",{"type":21,"value":54},"。本文将记录这两个功能的实现思路，以及在 SSR 环境下遇到的一些坑。",{"type":15,"tag":56,"props":57,"children":59},"h2",{"id":58},"一-动态文章目录toc的实现",[60],{"type":21,"value":61},"一、 动态文章目录（TOC）的实现",{"type":15,"tag":23,"props":63,"children":64},{},[65],{"type":21,"value":66},"对于包含大量代码和层级标题的技术文章，侧边目录是刚需。我们需要实现两个功能：解析标题生成目录、滚动时高亮当前章节。",{"type":15,"tag":68,"props":69,"children":71},"h3",{"id":70},"_1-提取文章标题",[72],{"type":21,"value":73},"1. 提取文章标题",{"type":15,"tag":23,"props":75,"children":76},{},[77,79,86,88,93,95,100],{"type":21,"value":78},"在 Nuxt 中，Markdown 渲染后通常会包裹在一个特定的容器内（例如 ",{"type":15,"tag":80,"props":81,"children":83},"code",{"className":82},[],[84],{"type":21,"value":85},".article-content",{"type":21,"value":87},"）。我们可以在组件挂载后，通过 DOM 查询提取所有的 ",{"type":15,"tag":80,"props":89,"children":91},{"className":90},[],[92],{"type":21,"value":56},{"type":21,"value":94}," 和 ",{"type":15,"tag":80,"props":96,"children":98},{"className":97},[],[99],{"type":21,"value":68},{"type":21,"value":101}," 标签。",{"type":15,"tag":103,"props":104,"children":108},"pre",{"className":105,"code":106,"language":107,"meta":7,"style":7},"language-typescript shiki shiki-themes github-light github-dark","\u002F\u002F composables\u002FuseToc.ts\nimport { ref, onMounted, onUnmounted } from 'vue'\n\ninterface TocItem {\n  id: string\n  text: string\n  level: number\n}\n\nexport function useToc(containerSelector = '.article-content') {\n  const headings = ref\u003CTocItem[]>([])\n  const activeId = ref('')\n  let observer: IntersectionObserver | null = null\n\n  const generateToc = () => {\n    \u002F\u002F 仅在客户端执行 DOM 操作\n    if (import.meta.server) return\n    \n    const container = document.querySelector(containerSelector)\n    if (!container) return\n\n    const elements = container.querySelectorAll('h2, h3')\n    headings.value = Array.from(elements).map((el) => ({\n      id: el.id || `heading-${Math.random().toString(36).substr(2, 9)}`,\n      text: el.textContent || '',\n      level: parseInt(el.tagName.substring(1)),\n    }))\n\n    \u002F\u002F 确保标题有 id，方便锚点跳转\n    elements.forEach((el, index) => {\n      if (!el.id) el.id = headings.value[index].id\n    })\n    \n    initObserver()\n  }\n\n  \u002F\u002F ... 初始化 IntersectionObserver 的逻辑\n}\n","typescript",[109],{"type":15,"tag":80,"props":110,"children":111},{"__ignoreMap":7},[112,124,151,161,181,202,219,237,246,254,298,336,371,413,421,452,461,499,508,541,567,575,615,672,768,790,828,837,845,854,897,928,937,945,959,968,976,985],{"type":15,"tag":113,"props":114,"children":117},"span",{"class":115,"line":116},"line",1,[118],{"type":15,"tag":113,"props":119,"children":121},{"style":120},"--shiki-default:#6A737D;--shiki-dark:#6A737D",[122],{"type":21,"value":123},"\u002F\u002F composables\u002FuseToc.ts\n",{"type":15,"tag":113,"props":125,"children":127},{"class":115,"line":126},2,[128,134,140,145],{"type":15,"tag":113,"props":129,"children":131},{"style":130},"--shiki-default:#D73A49;--shiki-dark:#F97583",[132],{"type":21,"value":133},"import",{"type":15,"tag":113,"props":135,"children":137},{"style":136},"--shiki-default:#24292E;--shiki-dark:#E1E4E8",[138],{"type":21,"value":139}," { ref, onMounted, onUnmounted } ",{"type":15,"tag":113,"props":141,"children":142},{"style":130},[143],{"type":21,"value":144},"from",{"type":15,"tag":113,"props":146,"children":148},{"style":147},"--shiki-default:#032F62;--shiki-dark:#9ECBFF",[149],{"type":21,"value":150}," 'vue'\n",{"type":15,"tag":113,"props":152,"children":154},{"class":115,"line":153},3,[155],{"type":15,"tag":113,"props":156,"children":158},{"emptyLinePlaceholder":157},true,[159],{"type":21,"value":160},"\n",{"type":15,"tag":113,"props":162,"children":164},{"class":115,"line":163},4,[165,170,176],{"type":15,"tag":113,"props":166,"children":167},{"style":130},[168],{"type":21,"value":169},"interface",{"type":15,"tag":113,"props":171,"children":173},{"style":172},"--shiki-default:#6F42C1;--shiki-dark:#B392F0",[174],{"type":21,"value":175}," TocItem",{"type":15,"tag":113,"props":177,"children":178},{"style":136},[179],{"type":21,"value":180}," {\n",{"type":15,"tag":113,"props":182,"children":184},{"class":115,"line":183},5,[185,191,196],{"type":15,"tag":113,"props":186,"children":188},{"style":187},"--shiki-default:#E36209;--shiki-dark:#FFAB70",[189],{"type":21,"value":190},"  id",{"type":15,"tag":113,"props":192,"children":193},{"style":130},[194],{"type":21,"value":195},":",{"type":15,"tag":113,"props":197,"children":199},{"style":198},"--shiki-default:#005CC5;--shiki-dark:#79B8FF",[200],{"type":21,"value":201}," string\n",{"type":15,"tag":113,"props":203,"children":205},{"class":115,"line":204},6,[206,211,215],{"type":15,"tag":113,"props":207,"children":208},{"style":187},[209],{"type":21,"value":210},"  text",{"type":15,"tag":113,"props":212,"children":213},{"style":130},[214],{"type":21,"value":195},{"type":15,"tag":113,"props":216,"children":217},{"style":198},[218],{"type":21,"value":201},{"type":15,"tag":113,"props":220,"children":222},{"class":115,"line":221},7,[223,228,232],{"type":15,"tag":113,"props":224,"children":225},{"style":187},[226],{"type":21,"value":227},"  level",{"type":15,"tag":113,"props":229,"children":230},{"style":130},[231],{"type":21,"value":195},{"type":15,"tag":113,"props":233,"children":234},{"style":198},[235],{"type":21,"value":236}," number\n",{"type":15,"tag":113,"props":238,"children":240},{"class":115,"line":239},8,[241],{"type":15,"tag":113,"props":242,"children":243},{"style":136},[244],{"type":21,"value":245},"}\n",{"type":15,"tag":113,"props":247,"children":249},{"class":115,"line":248},9,[250],{"type":15,"tag":113,"props":251,"children":252},{"emptyLinePlaceholder":157},[253],{"type":21,"value":160},{"type":15,"tag":113,"props":255,"children":257},{"class":115,"line":256},10,[258,263,268,273,278,283,288,293],{"type":15,"tag":113,"props":259,"children":260},{"style":130},[261],{"type":21,"value":262},"export",{"type":15,"tag":113,"props":264,"children":265},{"style":130},[266],{"type":21,"value":267}," function",{"type":15,"tag":113,"props":269,"children":270},{"style":172},[271],{"type":21,"value":272}," useToc",{"type":15,"tag":113,"props":274,"children":275},{"style":136},[276],{"type":21,"value":277},"(",{"type":15,"tag":113,"props":279,"children":280},{"style":187},[281],{"type":21,"value":282},"containerSelector",{"type":15,"tag":113,"props":284,"children":285},{"style":130},[286],{"type":21,"value":287}," =",{"type":15,"tag":113,"props":289,"children":290},{"style":147},[291],{"type":21,"value":292}," '.article-content'",{"type":15,"tag":113,"props":294,"children":295},{"style":136},[296],{"type":21,"value":297},") {\n",{"type":15,"tag":113,"props":299,"children":301},{"class":115,"line":300},11,[302,307,312,316,321,326,331],{"type":15,"tag":113,"props":303,"children":304},{"style":130},[305],{"type":21,"value":306},"  const",{"type":15,"tag":113,"props":308,"children":309},{"style":198},[310],{"type":21,"value":311}," headings",{"type":15,"tag":113,"props":313,"children":314},{"style":130},[315],{"type":21,"value":287},{"type":15,"tag":113,"props":317,"children":318},{"style":172},[319],{"type":21,"value":320}," ref",{"type":15,"tag":113,"props":322,"children":323},{"style":136},[324],{"type":21,"value":325},"\u003C",{"type":15,"tag":113,"props":327,"children":328},{"style":172},[329],{"type":21,"value":330},"TocItem",{"type":15,"tag":113,"props":332,"children":333},{"style":136},[334],{"type":21,"value":335},"[]>([])\n",{"type":15,"tag":113,"props":337,"children":339},{"class":115,"line":338},12,[340,344,349,353,357,361,366],{"type":15,"tag":113,"props":341,"children":342},{"style":130},[343],{"type":21,"value":306},{"type":15,"tag":113,"props":345,"children":346},{"style":198},[347],{"type":21,"value":348}," activeId",{"type":15,"tag":113,"props":350,"children":351},{"style":130},[352],{"type":21,"value":287},{"type":15,"tag":113,"props":354,"children":355},{"style":172},[356],{"type":21,"value":320},{"type":15,"tag":113,"props":358,"children":359},{"style":136},[360],{"type":21,"value":277},{"type":15,"tag":113,"props":362,"children":363},{"style":147},[364],{"type":21,"value":365},"''",{"type":15,"tag":113,"props":367,"children":368},{"style":136},[369],{"type":21,"value":370},")\n",{"type":15,"tag":113,"props":372,"children":374},{"class":115,"line":373},13,[375,380,385,389,394,399,404,408],{"type":15,"tag":113,"props":376,"children":377},{"style":130},[378],{"type":21,"value":379},"  let",{"type":15,"tag":113,"props":381,"children":382},{"style":136},[383],{"type":21,"value":384}," observer",{"type":15,"tag":113,"props":386,"children":387},{"style":130},[388],{"type":21,"value":195},{"type":15,"tag":113,"props":390,"children":391},{"style":172},[392],{"type":21,"value":393}," IntersectionObserver",{"type":15,"tag":113,"props":395,"children":396},{"style":130},[397],{"type":21,"value":398}," |",{"type":15,"tag":113,"props":400,"children":401},{"style":198},[402],{"type":21,"value":403}," null",{"type":15,"tag":113,"props":405,"children":406},{"style":130},[407],{"type":21,"value":287},{"type":15,"tag":113,"props":409,"children":410},{"style":198},[411],{"type":21,"value":412}," null\n",{"type":15,"tag":113,"props":414,"children":416},{"class":115,"line":415},14,[417],{"type":15,"tag":113,"props":418,"children":419},{"emptyLinePlaceholder":157},[420],{"type":21,"value":160},{"type":15,"tag":113,"props":422,"children":424},{"class":115,"line":423},15,[425,429,434,438,443,448],{"type":15,"tag":113,"props":426,"children":427},{"style":130},[428],{"type":21,"value":306},{"type":15,"tag":113,"props":430,"children":431},{"style":172},[432],{"type":21,"value":433}," generateToc",{"type":15,"tag":113,"props":435,"children":436},{"style":130},[437],{"type":21,"value":287},{"type":15,"tag":113,"props":439,"children":440},{"style":136},[441],{"type":21,"value":442}," () ",{"type":15,"tag":113,"props":444,"children":445},{"style":130},[446],{"type":21,"value":447},"=>",{"type":15,"tag":113,"props":449,"children":450},{"style":136},[451],{"type":21,"value":180},{"type":15,"tag":113,"props":453,"children":455},{"class":115,"line":454},16,[456],{"type":15,"tag":113,"props":457,"children":458},{"style":120},[459],{"type":21,"value":460},"    \u002F\u002F 仅在客户端执行 DOM 操作\n",{"type":15,"tag":113,"props":462,"children":464},{"class":115,"line":463},17,[465,470,475,479,484,489,494],{"type":15,"tag":113,"props":466,"children":467},{"style":130},[468],{"type":21,"value":469},"    if",{"type":15,"tag":113,"props":471,"children":472},{"style":136},[473],{"type":21,"value":474}," (",{"type":15,"tag":113,"props":476,"children":477},{"style":130},[478],{"type":21,"value":133},{"type":15,"tag":113,"props":480,"children":481},{"style":136},[482],{"type":21,"value":483},".",{"type":15,"tag":113,"props":485,"children":486},{"style":198},[487],{"type":21,"value":488},"meta",{"type":15,"tag":113,"props":490,"children":491},{"style":136},[492],{"type":21,"value":493},".server) ",{"type":15,"tag":113,"props":495,"children":496},{"style":130},[497],{"type":21,"value":498},"return\n",{"type":15,"tag":113,"props":500,"children":502},{"class":115,"line":501},18,[503],{"type":15,"tag":113,"props":504,"children":505},{"style":136},[506],{"type":21,"value":507},"    \n",{"type":15,"tag":113,"props":509,"children":511},{"class":115,"line":510},19,[512,517,522,526,531,536],{"type":15,"tag":113,"props":513,"children":514},{"style":130},[515],{"type":21,"value":516},"    const",{"type":15,"tag":113,"props":518,"children":519},{"style":198},[520],{"type":21,"value":521}," container",{"type":15,"tag":113,"props":523,"children":524},{"style":130},[525],{"type":21,"value":287},{"type":15,"tag":113,"props":527,"children":528},{"style":136},[529],{"type":21,"value":530}," document.",{"type":15,"tag":113,"props":532,"children":533},{"style":172},[534],{"type":21,"value":535},"querySelector",{"type":15,"tag":113,"props":537,"children":538},{"style":136},[539],{"type":21,"value":540},"(containerSelector)\n",{"type":15,"tag":113,"props":542,"children":544},{"class":115,"line":543},20,[545,549,553,558,563],{"type":15,"tag":113,"props":546,"children":547},{"style":130},[548],{"type":21,"value":469},{"type":15,"tag":113,"props":550,"children":551},{"style":136},[552],{"type":21,"value":474},{"type":15,"tag":113,"props":554,"children":555},{"style":130},[556],{"type":21,"value":557},"!",{"type":15,"tag":113,"props":559,"children":560},{"style":136},[561],{"type":21,"value":562},"container) ",{"type":15,"tag":113,"props":564,"children":565},{"style":130},[566],{"type":21,"value":498},{"type":15,"tag":113,"props":568,"children":570},{"class":115,"line":569},21,[571],{"type":15,"tag":113,"props":572,"children":573},{"emptyLinePlaceholder":157},[574],{"type":21,"value":160},{"type":15,"tag":113,"props":576,"children":578},{"class":115,"line":577},22,[579,583,588,592,597,602,606,611],{"type":15,"tag":113,"props":580,"children":581},{"style":130},[582],{"type":21,"value":516},{"type":15,"tag":113,"props":584,"children":585},{"style":198},[586],{"type":21,"value":587}," elements",{"type":15,"tag":113,"props":589,"children":590},{"style":130},[591],{"type":21,"value":287},{"type":15,"tag":113,"props":593,"children":594},{"style":136},[595],{"type":21,"value":596}," container.",{"type":15,"tag":113,"props":598,"children":599},{"style":172},[600],{"type":21,"value":601},"querySelectorAll",{"type":15,"tag":113,"props":603,"children":604},{"style":136},[605],{"type":21,"value":277},{"type":15,"tag":113,"props":607,"children":608},{"style":147},[609],{"type":21,"value":610},"'h2, h3'",{"type":15,"tag":113,"props":612,"children":613},{"style":136},[614],{"type":21,"value":370},{"type":15,"tag":113,"props":616,"children":618},{"class":115,"line":617},23,[619,624,629,634,638,643,648,653,658,663,667],{"type":15,"tag":113,"props":620,"children":621},{"style":136},[622],{"type":21,"value":623},"    headings.value ",{"type":15,"tag":113,"props":625,"children":626},{"style":130},[627],{"type":21,"value":628},"=",{"type":15,"tag":113,"props":630,"children":631},{"style":136},[632],{"type":21,"value":633}," Array.",{"type":15,"tag":113,"props":635,"children":636},{"style":172},[637],{"type":21,"value":144},{"type":15,"tag":113,"props":639,"children":640},{"style":136},[641],{"type":21,"value":642},"(elements).",{"type":15,"tag":113,"props":644,"children":645},{"style":172},[646],{"type":21,"value":647},"map",{"type":15,"tag":113,"props":649,"children":650},{"style":136},[651],{"type":21,"value":652},"((",{"type":15,"tag":113,"props":654,"children":655},{"style":187},[656],{"type":21,"value":657},"el",{"type":15,"tag":113,"props":659,"children":660},{"style":136},[661],{"type":21,"value":662},") ",{"type":15,"tag":113,"props":664,"children":665},{"style":130},[666],{"type":21,"value":447},{"type":15,"tag":113,"props":668,"children":669},{"style":136},[670],{"type":21,"value":671}," ({\n",{"type":15,"tag":113,"props":673,"children":675},{"class":115,"line":674},24,[676,681,686,691,696,700,705,710,715,719,724,729,734,738,743,748,753,758,763],{"type":15,"tag":113,"props":677,"children":678},{"style":136},[679],{"type":21,"value":680},"      id: el.id ",{"type":15,"tag":113,"props":682,"children":683},{"style":130},[684],{"type":21,"value":685},"||",{"type":15,"tag":113,"props":687,"children":688},{"style":147},[689],{"type":21,"value":690}," `heading-${",{"type":15,"tag":113,"props":692,"children":693},{"style":136},[694],{"type":21,"value":695},"Math",{"type":15,"tag":113,"props":697,"children":698},{"style":147},[699],{"type":21,"value":483},{"type":15,"tag":113,"props":701,"children":702},{"style":172},[703],{"type":21,"value":704},"random",{"type":15,"tag":113,"props":706,"children":707},{"style":147},[708],{"type":21,"value":709},"().",{"type":15,"tag":113,"props":711,"children":712},{"style":172},[713],{"type":21,"value":714},"toString",{"type":15,"tag":113,"props":716,"children":717},{"style":147},[718],{"type":21,"value":277},{"type":15,"tag":113,"props":720,"children":721},{"style":198},[722],{"type":21,"value":723},"36",{"type":15,"tag":113,"props":725,"children":726},{"style":147},[727],{"type":21,"value":728},").",{"type":15,"tag":113,"props":730,"children":731},{"style":172},[732],{"type":21,"value":733},"substr",{"type":15,"tag":113,"props":735,"children":736},{"style":147},[737],{"type":21,"value":277},{"type":15,"tag":113,"props":739,"children":740},{"style":198},[741],{"type":21,"value":742},"2",{"type":15,"tag":113,"props":744,"children":745},{"style":147},[746],{"type":21,"value":747},", ",{"type":15,"tag":113,"props":749,"children":750},{"style":198},[751],{"type":21,"value":752},"9",{"type":15,"tag":113,"props":754,"children":755},{"style":147},[756],{"type":21,"value":757},")",{"type":15,"tag":113,"props":759,"children":760},{"style":147},[761],{"type":21,"value":762},"}`",{"type":15,"tag":113,"props":764,"children":765},{"style":136},[766],{"type":21,"value":767},",\n",{"type":15,"tag":113,"props":769,"children":771},{"class":115,"line":770},25,[772,777,781,786],{"type":15,"tag":113,"props":773,"children":774},{"style":136},[775],{"type":21,"value":776},"      text: el.textContent ",{"type":15,"tag":113,"props":778,"children":779},{"style":130},[780],{"type":21,"value":685},{"type":15,"tag":113,"props":782,"children":783},{"style":147},[784],{"type":21,"value":785}," ''",{"type":15,"tag":113,"props":787,"children":788},{"style":136},[789],{"type":21,"value":767},{"type":15,"tag":113,"props":791,"children":793},{"class":115,"line":792},26,[794,799,804,809,814,818,823],{"type":15,"tag":113,"props":795,"children":796},{"style":136},[797],{"type":21,"value":798},"      level: ",{"type":15,"tag":113,"props":800,"children":801},{"style":172},[802],{"type":21,"value":803},"parseInt",{"type":15,"tag":113,"props":805,"children":806},{"style":136},[807],{"type":21,"value":808},"(el.tagName.",{"type":15,"tag":113,"props":810,"children":811},{"style":172},[812],{"type":21,"value":813},"substring",{"type":15,"tag":113,"props":815,"children":816},{"style":136},[817],{"type":21,"value":277},{"type":15,"tag":113,"props":819,"children":820},{"style":198},[821],{"type":21,"value":822},"1",{"type":15,"tag":113,"props":824,"children":825},{"style":136},[826],{"type":21,"value":827},")),\n",{"type":15,"tag":113,"props":829,"children":831},{"class":115,"line":830},27,[832],{"type":15,"tag":113,"props":833,"children":834},{"style":136},[835],{"type":21,"value":836},"    }))\n",{"type":15,"tag":113,"props":838,"children":840},{"class":115,"line":839},28,[841],{"type":15,"tag":113,"props":842,"children":843},{"emptyLinePlaceholder":157},[844],{"type":21,"value":160},{"type":15,"tag":113,"props":846,"children":848},{"class":115,"line":847},29,[849],{"type":15,"tag":113,"props":850,"children":851},{"style":120},[852],{"type":21,"value":853},"    \u002F\u002F 确保标题有 id，方便锚点跳转\n",{"type":15,"tag":113,"props":855,"children":857},{"class":115,"line":856},30,[858,863,868,872,876,880,885,889,893],{"type":15,"tag":113,"props":859,"children":860},{"style":136},[861],{"type":21,"value":862},"    elements.",{"type":15,"tag":113,"props":864,"children":865},{"style":172},[866],{"type":21,"value":867},"forEach",{"type":15,"tag":113,"props":869,"children":870},{"style":136},[871],{"type":21,"value":652},{"type":15,"tag":113,"props":873,"children":874},{"style":187},[875],{"type":21,"value":657},{"type":15,"tag":113,"props":877,"children":878},{"style":136},[879],{"type":21,"value":747},{"type":15,"tag":113,"props":881,"children":882},{"style":187},[883],{"type":21,"value":884},"index",{"type":15,"tag":113,"props":886,"children":887},{"style":136},[888],{"type":21,"value":662},{"type":15,"tag":113,"props":890,"children":891},{"style":130},[892],{"type":21,"value":447},{"type":15,"tag":113,"props":894,"children":895},{"style":136},[896],{"type":21,"value":180},{"type":15,"tag":113,"props":898,"children":900},{"class":115,"line":899},31,[901,906,910,914,919,923],{"type":15,"tag":113,"props":902,"children":903},{"style":130},[904],{"type":21,"value":905},"      if",{"type":15,"tag":113,"props":907,"children":908},{"style":136},[909],{"type":21,"value":474},{"type":15,"tag":113,"props":911,"children":912},{"style":130},[913],{"type":21,"value":557},{"type":15,"tag":113,"props":915,"children":916},{"style":136},[917],{"type":21,"value":918},"el.id) el.id ",{"type":15,"tag":113,"props":920,"children":921},{"style":130},[922],{"type":21,"value":628},{"type":15,"tag":113,"props":924,"children":925},{"style":136},[926],{"type":21,"value":927}," headings.value[index].id\n",{"type":15,"tag":113,"props":929,"children":931},{"class":115,"line":930},32,[932],{"type":15,"tag":113,"props":933,"children":934},{"style":136},[935],{"type":21,"value":936},"    })\n",{"type":15,"tag":113,"props":938,"children":940},{"class":115,"line":939},33,[941],{"type":15,"tag":113,"props":942,"children":943},{"style":136},[944],{"type":21,"value":507},{"type":15,"tag":113,"props":946,"children":948},{"class":115,"line":947},34,[949,954],{"type":15,"tag":113,"props":950,"children":951},{"style":172},[952],{"type":21,"value":953},"    initObserver",{"type":15,"tag":113,"props":955,"children":956},{"style":136},[957],{"type":21,"value":958},"()\n",{"type":15,"tag":113,"props":960,"children":962},{"class":115,"line":961},35,[963],{"type":15,"tag":113,"props":964,"children":965},{"style":136},[966],{"type":21,"value":967},"  }\n",{"type":15,"tag":113,"props":969,"children":971},{"class":115,"line":970},36,[972],{"type":15,"tag":113,"props":973,"children":974},{"emptyLinePlaceholder":157},[975],{"type":21,"value":160},{"type":15,"tag":113,"props":977,"children":979},{"class":115,"line":978},37,[980],{"type":15,"tag":113,"props":981,"children":982},{"style":120},[983],{"type":21,"value":984},"  \u002F\u002F ... 初始化 IntersectionObserver 的逻辑\n",{"type":15,"tag":113,"props":986,"children":988},{"class":115,"line":987},38,[989],{"type":15,"tag":113,"props":990,"children":991},{"style":136},[992],{"type":21,"value":245},{"type":15,"tag":68,"props":994,"children":996},{"id":995},"_2-滚动高亮当前章节",[997],{"type":21,"value":998},"2. 滚动高亮当前章节",{"type":15,"tag":23,"props":1000,"children":1001},{},[1002,1004,1010,1012,1017],{"type":21,"value":1003},"早期我使用监听 ",{"type":15,"tag":80,"props":1005,"children":1007},{"className":1006},[],[1008],{"type":21,"value":1009},"scroll",{"type":21,"value":1011}," 事件来计算标题位置，但在长文章中会导致严重的性能问题。后来改用 ",{"type":15,"tag":29,"props":1013,"children":1014},{},[1015],{"type":21,"value":1016},"Intersection Observer API",{"type":21,"value":1018},"，由浏览器底层异步监听，性能极佳。",{"type":15,"tag":103,"props":1020,"children":1022},{"className":105,"code":1021,"language":107,"meta":7,"style":7},"  const initObserver = () => {\n    if (observer) observer.disconnect()\n\n    observer = new IntersectionObserver(\n      (entries) => {\n        entries.forEach((entry) => {\n          \u002F\u002F 当标题进入视口时，更新激活状态\n          if (entry.isIntersecting) {\n            activeId.value = entry.target.id\n          }\n        })\n      },\n      {\n        \u002F\u002F 调整根容器的边距，让标题在滚动到视口顶部 20% 时就触发高亮\n        rootMargin: '-20% 0px -80% 0px', \n        threshold: 0,\n      }\n    )\n\n    headings.value.forEach((item) => {\n      const el = document.getElementById(item.id)\n      if (el) observer?.observe(el)\n    })\n  }\n\n  onMounted(() => {\n    generateToc()\n  })\n\n  onUnmounted(() => {\n    observer?.disconnect()\n  })\n\n  return { headings, activeId }\n}\n",[1023],{"type":15,"tag":80,"props":1024,"children":1025},{"__ignoreMap":7},[1026,1054,1075,1082,1108,1133,1166,1174,1187,1204,1212,1220,1228,1236,1244,1262,1279,1287,1295,1302,1335,1366,1388,1395,1402,1409,1430,1442,1450,1457,1477,1493,1500,1507,1520],{"type":15,"tag":113,"props":1027,"children":1028},{"class":115,"line":116},[1029,1033,1038,1042,1046,1050],{"type":15,"tag":113,"props":1030,"children":1031},{"style":130},[1032],{"type":21,"value":306},{"type":15,"tag":113,"props":1034,"children":1035},{"style":172},[1036],{"type":21,"value":1037}," initObserver",{"type":15,"tag":113,"props":1039,"children":1040},{"style":130},[1041],{"type":21,"value":287},{"type":15,"tag":113,"props":1043,"children":1044},{"style":136},[1045],{"type":21,"value":442},{"type":15,"tag":113,"props":1047,"children":1048},{"style":130},[1049],{"type":21,"value":447},{"type":15,"tag":113,"props":1051,"children":1052},{"style":136},[1053],{"type":21,"value":180},{"type":15,"tag":113,"props":1055,"children":1056},{"class":115,"line":126},[1057,1061,1066,1071],{"type":15,"tag":113,"props":1058,"children":1059},{"style":130},[1060],{"type":21,"value":469},{"type":15,"tag":113,"props":1062,"children":1063},{"style":136},[1064],{"type":21,"value":1065}," (observer) observer.",{"type":15,"tag":113,"props":1067,"children":1068},{"style":172},[1069],{"type":21,"value":1070},"disconnect",{"type":15,"tag":113,"props":1072,"children":1073},{"style":136},[1074],{"type":21,"value":958},{"type":15,"tag":113,"props":1076,"children":1077},{"class":115,"line":153},[1078],{"type":15,"tag":113,"props":1079,"children":1080},{"emptyLinePlaceholder":157},[1081],{"type":21,"value":160},{"type":15,"tag":113,"props":1083,"children":1084},{"class":115,"line":163},[1085,1090,1094,1099,1103],{"type":15,"tag":113,"props":1086,"children":1087},{"style":136},[1088],{"type":21,"value":1089},"    observer ",{"type":15,"tag":113,"props":1091,"children":1092},{"style":130},[1093],{"type":21,"value":628},{"type":15,"tag":113,"props":1095,"children":1096},{"style":130},[1097],{"type":21,"value":1098}," new",{"type":15,"tag":113,"props":1100,"children":1101},{"style":172},[1102],{"type":21,"value":393},{"type":15,"tag":113,"props":1104,"children":1105},{"style":136},[1106],{"type":21,"value":1107},"(\n",{"type":15,"tag":113,"props":1109,"children":1110},{"class":115,"line":183},[1111,1116,1121,1125,1129],{"type":15,"tag":113,"props":1112,"children":1113},{"style":136},[1114],{"type":21,"value":1115},"      (",{"type":15,"tag":113,"props":1117,"children":1118},{"style":187},[1119],{"type":21,"value":1120},"entries",{"type":15,"tag":113,"props":1122,"children":1123},{"style":136},[1124],{"type":21,"value":662},{"type":15,"tag":113,"props":1126,"children":1127},{"style":130},[1128],{"type":21,"value":447},{"type":15,"tag":113,"props":1130,"children":1131},{"style":136},[1132],{"type":21,"value":180},{"type":15,"tag":113,"props":1134,"children":1135},{"class":115,"line":204},[1136,1141,1145,1149,1154,1158,1162],{"type":15,"tag":113,"props":1137,"children":1138},{"style":136},[1139],{"type":21,"value":1140},"        entries.",{"type":15,"tag":113,"props":1142,"children":1143},{"style":172},[1144],{"type":21,"value":867},{"type":15,"tag":113,"props":1146,"children":1147},{"style":136},[1148],{"type":21,"value":652},{"type":15,"tag":113,"props":1150,"children":1151},{"style":187},[1152],{"type":21,"value":1153},"entry",{"type":15,"tag":113,"props":1155,"children":1156},{"style":136},[1157],{"type":21,"value":662},{"type":15,"tag":113,"props":1159,"children":1160},{"style":130},[1161],{"type":21,"value":447},{"type":15,"tag":113,"props":1163,"children":1164},{"style":136},[1165],{"type":21,"value":180},{"type":15,"tag":113,"props":1167,"children":1168},{"class":115,"line":221},[1169],{"type":15,"tag":113,"props":1170,"children":1171},{"style":120},[1172],{"type":21,"value":1173},"          \u002F\u002F 当标题进入视口时，更新激活状态\n",{"type":15,"tag":113,"props":1175,"children":1176},{"class":115,"line":239},[1177,1182],{"type":15,"tag":113,"props":1178,"children":1179},{"style":130},[1180],{"type":21,"value":1181},"          if",{"type":15,"tag":113,"props":1183,"children":1184},{"style":136},[1185],{"type":21,"value":1186}," (entry.isIntersecting) {\n",{"type":15,"tag":113,"props":1188,"children":1189},{"class":115,"line":248},[1190,1195,1199],{"type":15,"tag":113,"props":1191,"children":1192},{"style":136},[1193],{"type":21,"value":1194},"            activeId.value ",{"type":15,"tag":113,"props":1196,"children":1197},{"style":130},[1198],{"type":21,"value":628},{"type":15,"tag":113,"props":1200,"children":1201},{"style":136},[1202],{"type":21,"value":1203}," entry.target.id\n",{"type":15,"tag":113,"props":1205,"children":1206},{"class":115,"line":256},[1207],{"type":15,"tag":113,"props":1208,"children":1209},{"style":136},[1210],{"type":21,"value":1211},"          }\n",{"type":15,"tag":113,"props":1213,"children":1214},{"class":115,"line":300},[1215],{"type":15,"tag":113,"props":1216,"children":1217},{"style":136},[1218],{"type":21,"value":1219},"        })\n",{"type":15,"tag":113,"props":1221,"children":1222},{"class":115,"line":338},[1223],{"type":15,"tag":113,"props":1224,"children":1225},{"style":136},[1226],{"type":21,"value":1227},"      },\n",{"type":15,"tag":113,"props":1229,"children":1230},{"class":115,"line":373},[1231],{"type":15,"tag":113,"props":1232,"children":1233},{"style":136},[1234],{"type":21,"value":1235},"      {\n",{"type":15,"tag":113,"props":1237,"children":1238},{"class":115,"line":415},[1239],{"type":15,"tag":113,"props":1240,"children":1241},{"style":120},[1242],{"type":21,"value":1243},"        \u002F\u002F 调整根容器的边距，让标题在滚动到视口顶部 20% 时就触发高亮\n",{"type":15,"tag":113,"props":1245,"children":1246},{"class":115,"line":423},[1247,1252,1257],{"type":15,"tag":113,"props":1248,"children":1249},{"style":136},[1250],{"type":21,"value":1251},"        rootMargin: ",{"type":15,"tag":113,"props":1253,"children":1254},{"style":147},[1255],{"type":21,"value":1256},"'-20% 0px -80% 0px'",{"type":15,"tag":113,"props":1258,"children":1259},{"style":136},[1260],{"type":21,"value":1261},", \n",{"type":15,"tag":113,"props":1263,"children":1264},{"class":115,"line":454},[1265,1270,1275],{"type":15,"tag":113,"props":1266,"children":1267},{"style":136},[1268],{"type":21,"value":1269},"        threshold: ",{"type":15,"tag":113,"props":1271,"children":1272},{"style":198},[1273],{"type":21,"value":1274},"0",{"type":15,"tag":113,"props":1276,"children":1277},{"style":136},[1278],{"type":21,"value":767},{"type":15,"tag":113,"props":1280,"children":1281},{"class":115,"line":463},[1282],{"type":15,"tag":113,"props":1283,"children":1284},{"style":136},[1285],{"type":21,"value":1286},"      }\n",{"type":15,"tag":113,"props":1288,"children":1289},{"class":115,"line":501},[1290],{"type":15,"tag":113,"props":1291,"children":1292},{"style":136},[1293],{"type":21,"value":1294},"    )\n",{"type":15,"tag":113,"props":1296,"children":1297},{"class":115,"line":510},[1298],{"type":15,"tag":113,"props":1299,"children":1300},{"emptyLinePlaceholder":157},[1301],{"type":21,"value":160},{"type":15,"tag":113,"props":1303,"children":1304},{"class":115,"line":543},[1305,1310,1314,1318,1323,1327,1331],{"type":15,"tag":113,"props":1306,"children":1307},{"style":136},[1308],{"type":21,"value":1309},"    headings.value.",{"type":15,"tag":113,"props":1311,"children":1312},{"style":172},[1313],{"type":21,"value":867},{"type":15,"tag":113,"props":1315,"children":1316},{"style":136},[1317],{"type":21,"value":652},{"type":15,"tag":113,"props":1319,"children":1320},{"style":187},[1321],{"type":21,"value":1322},"item",{"type":15,"tag":113,"props":1324,"children":1325},{"style":136},[1326],{"type":21,"value":662},{"type":15,"tag":113,"props":1328,"children":1329},{"style":130},[1330],{"type":21,"value":447},{"type":15,"tag":113,"props":1332,"children":1333},{"style":136},[1334],{"type":21,"value":180},{"type":15,"tag":113,"props":1336,"children":1337},{"class":115,"line":569},[1338,1343,1348,1352,1356,1361],{"type":15,"tag":113,"props":1339,"children":1340},{"style":130},[1341],{"type":21,"value":1342},"      const",{"type":15,"tag":113,"props":1344,"children":1345},{"style":198},[1346],{"type":21,"value":1347}," el",{"type":15,"tag":113,"props":1349,"children":1350},{"style":130},[1351],{"type":21,"value":287},{"type":15,"tag":113,"props":1353,"children":1354},{"style":136},[1355],{"type":21,"value":530},{"type":15,"tag":113,"props":1357,"children":1358},{"style":172},[1359],{"type":21,"value":1360},"getElementById",{"type":15,"tag":113,"props":1362,"children":1363},{"style":136},[1364],{"type":21,"value":1365},"(item.id)\n",{"type":15,"tag":113,"props":1367,"children":1368},{"class":115,"line":577},[1369,1373,1378,1383],{"type":15,"tag":113,"props":1370,"children":1371},{"style":130},[1372],{"type":21,"value":905},{"type":15,"tag":113,"props":1374,"children":1375},{"style":136},[1376],{"type":21,"value":1377}," (el) observer?.",{"type":15,"tag":113,"props":1379,"children":1380},{"style":172},[1381],{"type":21,"value":1382},"observe",{"type":15,"tag":113,"props":1384,"children":1385},{"style":136},[1386],{"type":21,"value":1387},"(el)\n",{"type":15,"tag":113,"props":1389,"children":1390},{"class":115,"line":617},[1391],{"type":15,"tag":113,"props":1392,"children":1393},{"style":136},[1394],{"type":21,"value":936},{"type":15,"tag":113,"props":1396,"children":1397},{"class":115,"line":674},[1398],{"type":15,"tag":113,"props":1399,"children":1400},{"style":136},[1401],{"type":21,"value":967},{"type":15,"tag":113,"props":1403,"children":1404},{"class":115,"line":770},[1405],{"type":15,"tag":113,"props":1406,"children":1407},{"emptyLinePlaceholder":157},[1408],{"type":21,"value":160},{"type":15,"tag":113,"props":1410,"children":1411},{"class":115,"line":792},[1412,1417,1422,1426],{"type":15,"tag":113,"props":1413,"children":1414},{"style":172},[1415],{"type":21,"value":1416},"  onMounted",{"type":15,"tag":113,"props":1418,"children":1419},{"style":136},[1420],{"type":21,"value":1421},"(() ",{"type":15,"tag":113,"props":1423,"children":1424},{"style":130},[1425],{"type":21,"value":447},{"type":15,"tag":113,"props":1427,"children":1428},{"style":136},[1429],{"type":21,"value":180},{"type":15,"tag":113,"props":1431,"children":1432},{"class":115,"line":830},[1433,1438],{"type":15,"tag":113,"props":1434,"children":1435},{"style":172},[1436],{"type":21,"value":1437},"    generateToc",{"type":15,"tag":113,"props":1439,"children":1440},{"style":136},[1441],{"type":21,"value":958},{"type":15,"tag":113,"props":1443,"children":1444},{"class":115,"line":839},[1445],{"type":15,"tag":113,"props":1446,"children":1447},{"style":136},[1448],{"type":21,"value":1449},"  })\n",{"type":15,"tag":113,"props":1451,"children":1452},{"class":115,"line":847},[1453],{"type":15,"tag":113,"props":1454,"children":1455},{"emptyLinePlaceholder":157},[1456],{"type":21,"value":160},{"type":15,"tag":113,"props":1458,"children":1459},{"class":115,"line":856},[1460,1465,1469,1473],{"type":15,"tag":113,"props":1461,"children":1462},{"style":172},[1463],{"type":21,"value":1464},"  onUnmounted",{"type":15,"tag":113,"props":1466,"children":1467},{"style":136},[1468],{"type":21,"value":1421},{"type":15,"tag":113,"props":1470,"children":1471},{"style":130},[1472],{"type":21,"value":447},{"type":15,"tag":113,"props":1474,"children":1475},{"style":136},[1476],{"type":21,"value":180},{"type":15,"tag":113,"props":1478,"children":1479},{"class":115,"line":899},[1480,1485,1489],{"type":15,"tag":113,"props":1481,"children":1482},{"style":136},[1483],{"type":21,"value":1484},"    observer?.",{"type":15,"tag":113,"props":1486,"children":1487},{"style":172},[1488],{"type":21,"value":1070},{"type":15,"tag":113,"props":1490,"children":1491},{"style":136},[1492],{"type":21,"value":958},{"type":15,"tag":113,"props":1494,"children":1495},{"class":115,"line":930},[1496],{"type":15,"tag":113,"props":1497,"children":1498},{"style":136},[1499],{"type":21,"value":1449},{"type":15,"tag":113,"props":1501,"children":1502},{"class":115,"line":939},[1503],{"type":15,"tag":113,"props":1504,"children":1505},{"emptyLinePlaceholder":157},[1506],{"type":21,"value":160},{"type":15,"tag":113,"props":1508,"children":1509},{"class":115,"line":947},[1510,1515],{"type":15,"tag":113,"props":1511,"children":1512},{"style":130},[1513],{"type":21,"value":1514},"  return",{"type":15,"tag":113,"props":1516,"children":1517},{"style":136},[1518],{"type":21,"value":1519}," { headings, activeId }\n",{"type":15,"tag":113,"props":1521,"children":1522},{"class":115,"line":961},[1523],{"type":15,"tag":113,"props":1524,"children":1525},{"style":136},[1526],{"type":21,"value":245},{"type":15,"tag":23,"props":1528,"children":1529},{},[1530,1535,1537,1543,1545,1551,1553,1559,1561,1567],{"type":15,"tag":29,"props":1531,"children":1532},{},[1533],{"type":21,"value":1534},"💡 踩坑记录：",{"type":21,"value":1536},"\n在 Nuxt 的 SSR 模式下，直接在 ",{"type":15,"tag":80,"props":1538,"children":1540},{"className":1539},[],[1541],{"type":21,"value":1542},"setup",{"type":21,"value":1544}," 阶段访问 ",{"type":15,"tag":80,"props":1546,"children":1548},{"className":1547},[],[1549],{"type":21,"value":1550},"document",{"type":21,"value":1552}," 会报错。必须确保 DOM 操作在 ",{"type":15,"tag":80,"props":1554,"children":1556},{"className":1555},[],[1557],{"type":21,"value":1558},"onMounted",{"type":21,"value":1560}," 钩子中执行，或者使用 ",{"type":15,"tag":80,"props":1562,"children":1564},{"className":1563},[],[1565],{"type":21,"value":1566},"import.meta.client",{"type":21,"value":1568}," 进行环境判断。",{"type":15,"tag":56,"props":1570,"children":1572},{"id":1571},"二-沉浸式阅读进度条",[1573],{"type":21,"value":1574},"二、 沉浸式阅读进度条",{"type":15,"tag":23,"props":1576,"children":1577},{},[1578],{"type":21,"value":1579},"进度条能给读者一个明确的心理预期：“这篇文章还有多少没看完”。实现思路很简单：计算当前滚动高度占页面总高度的百分比。",{"type":15,"tag":68,"props":1581,"children":1583},{"id":1582},"_1-基础逻辑与性能优化",[1584],{"type":21,"value":1585},"1. 基础逻辑与性能优化",{"type":15,"tag":23,"props":1587,"children":1588},{},[1589,1591,1596,1598,1604],{"type":21,"value":1590},"直接监听 ",{"type":15,"tag":80,"props":1592,"children":1594},{"className":1593},[],[1595],{"type":21,"value":1009},{"type":21,"value":1597}," 事件并频繁修改响应式数据会导致页面卡顿。我们需要结合 ",{"type":15,"tag":80,"props":1599,"children":1601},{"className":1600},[],[1602],{"type":21,"value":1603},"requestAnimationFrame",{"type":21,"value":1605}," 进行节流优化。",{"type":15,"tag":103,"props":1607,"children":1609},{"className":105,"code":1608,"language":107,"meta":7,"style":7},"\u002F\u002F composables\u002FuseReadingProgress.ts\nimport { ref, onMounted, onUnmounted } from 'vue'\n\nexport function useReadingProgress() {\n  const progress = ref(0)\n  let ticking = false\n\n  const updateProgress = () => {\n    const scrollTop = window.scrollY || document.documentElement.scrollTop\n    const docHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight\n    \n    \u002F\u002F 防止除以 0 或负数\n    progress.value = docHeight > 0 ? Math.min(100, (scrollTop \u002F docHeight) * 100) : 0\n    ticking = false\n  }\n\n  const onScroll = () => {\n    if (!ticking) {\n      window.requestAnimationFrame(updateProgress)\n      ticking = true\n    }\n  }\n\n  onMounted(() => {\n    window.addEventListener('scroll', onScroll, { passive: true })\n    updateProgress() \u002F\u002F 初始化\n  })\n\n  onUnmounted(() => {\n    window.removeEventListener('scroll', onScroll)\n  })\n\n  return { progress }\n}\n",[1610],{"type":15,"tag":80,"props":1611,"children":1612},{"__ignoreMap":7},[1613,1621,1640,1647,1668,1700,1721,1728,1756,1786,1817,1824,1832,1921,1937,1944,1951,1979,1999,2016,2033,2041,2048,2055,2074,2111,2129,2136,2143,2162,2187,2194,2201,2213],{"type":15,"tag":113,"props":1614,"children":1615},{"class":115,"line":116},[1616],{"type":15,"tag":113,"props":1617,"children":1618},{"style":120},[1619],{"type":21,"value":1620},"\u002F\u002F composables\u002FuseReadingProgress.ts\n",{"type":15,"tag":113,"props":1622,"children":1623},{"class":115,"line":126},[1624,1628,1632,1636],{"type":15,"tag":113,"props":1625,"children":1626},{"style":130},[1627],{"type":21,"value":133},{"type":15,"tag":113,"props":1629,"children":1630},{"style":136},[1631],{"type":21,"value":139},{"type":15,"tag":113,"props":1633,"children":1634},{"style":130},[1635],{"type":21,"value":144},{"type":15,"tag":113,"props":1637,"children":1638},{"style":147},[1639],{"type":21,"value":150},{"type":15,"tag":113,"props":1641,"children":1642},{"class":115,"line":153},[1643],{"type":15,"tag":113,"props":1644,"children":1645},{"emptyLinePlaceholder":157},[1646],{"type":21,"value":160},{"type":15,"tag":113,"props":1648,"children":1649},{"class":115,"line":163},[1650,1654,1658,1663],{"type":15,"tag":113,"props":1651,"children":1652},{"style":130},[1653],{"type":21,"value":262},{"type":15,"tag":113,"props":1655,"children":1656},{"style":130},[1657],{"type":21,"value":267},{"type":15,"tag":113,"props":1659,"children":1660},{"style":172},[1661],{"type":21,"value":1662}," useReadingProgress",{"type":15,"tag":113,"props":1664,"children":1665},{"style":136},[1666],{"type":21,"value":1667},"() {\n",{"type":15,"tag":113,"props":1669,"children":1670},{"class":115,"line":183},[1671,1675,1680,1684,1688,1692,1696],{"type":15,"tag":113,"props":1672,"children":1673},{"style":130},[1674],{"type":21,"value":306},{"type":15,"tag":113,"props":1676,"children":1677},{"style":198},[1678],{"type":21,"value":1679}," progress",{"type":15,"tag":113,"props":1681,"children":1682},{"style":130},[1683],{"type":21,"value":287},{"type":15,"tag":113,"props":1685,"children":1686},{"style":172},[1687],{"type":21,"value":320},{"type":15,"tag":113,"props":1689,"children":1690},{"style":136},[1691],{"type":21,"value":277},{"type":15,"tag":113,"props":1693,"children":1694},{"style":198},[1695],{"type":21,"value":1274},{"type":15,"tag":113,"props":1697,"children":1698},{"style":136},[1699],{"type":21,"value":370},{"type":15,"tag":113,"props":1701,"children":1702},{"class":115,"line":204},[1703,1707,1712,1716],{"type":15,"tag":113,"props":1704,"children":1705},{"style":130},[1706],{"type":21,"value":379},{"type":15,"tag":113,"props":1708,"children":1709},{"style":136},[1710],{"type":21,"value":1711}," ticking ",{"type":15,"tag":113,"props":1713,"children":1714},{"style":130},[1715],{"type":21,"value":628},{"type":15,"tag":113,"props":1717,"children":1718},{"style":198},[1719],{"type":21,"value":1720}," false\n",{"type":15,"tag":113,"props":1722,"children":1723},{"class":115,"line":221},[1724],{"type":15,"tag":113,"props":1725,"children":1726},{"emptyLinePlaceholder":157},[1727],{"type":21,"value":160},{"type":15,"tag":113,"props":1729,"children":1730},{"class":115,"line":239},[1731,1735,1740,1744,1748,1752],{"type":15,"tag":113,"props":1732,"children":1733},{"style":130},[1734],{"type":21,"value":306},{"type":15,"tag":113,"props":1736,"children":1737},{"style":172},[1738],{"type":21,"value":1739}," updateProgress",{"type":15,"tag":113,"props":1741,"children":1742},{"style":130},[1743],{"type":21,"value":287},{"type":15,"tag":113,"props":1745,"children":1746},{"style":136},[1747],{"type":21,"value":442},{"type":15,"tag":113,"props":1749,"children":1750},{"style":130},[1751],{"type":21,"value":447},{"type":15,"tag":113,"props":1753,"children":1754},{"style":136},[1755],{"type":21,"value":180},{"type":15,"tag":113,"props":1757,"children":1758},{"class":115,"line":248},[1759,1763,1768,1772,1777,1781],{"type":15,"tag":113,"props":1760,"children":1761},{"style":130},[1762],{"type":21,"value":516},{"type":15,"tag":113,"props":1764,"children":1765},{"style":198},[1766],{"type":21,"value":1767}," scrollTop",{"type":15,"tag":113,"props":1769,"children":1770},{"style":130},[1771],{"type":21,"value":287},{"type":15,"tag":113,"props":1773,"children":1774},{"style":136},[1775],{"type":21,"value":1776}," window.scrollY ",{"type":15,"tag":113,"props":1778,"children":1779},{"style":130},[1780],{"type":21,"value":685},{"type":15,"tag":113,"props":1782,"children":1783},{"style":136},[1784],{"type":21,"value":1785}," document.documentElement.scrollTop\n",{"type":15,"tag":113,"props":1787,"children":1788},{"class":115,"line":256},[1789,1793,1798,1802,1807,1812],{"type":15,"tag":113,"props":1790,"children":1791},{"style":130},[1792],{"type":21,"value":516},{"type":15,"tag":113,"props":1794,"children":1795},{"style":198},[1796],{"type":21,"value":1797}," docHeight",{"type":15,"tag":113,"props":1799,"children":1800},{"style":130},[1801],{"type":21,"value":287},{"type":15,"tag":113,"props":1803,"children":1804},{"style":136},[1805],{"type":21,"value":1806}," document.documentElement.scrollHeight ",{"type":15,"tag":113,"props":1808,"children":1809},{"style":130},[1810],{"type":21,"value":1811},"-",{"type":15,"tag":113,"props":1813,"children":1814},{"style":136},[1815],{"type":21,"value":1816}," document.documentElement.clientHeight\n",{"type":15,"tag":113,"props":1818,"children":1819},{"class":115,"line":300},[1820],{"type":15,"tag":113,"props":1821,"children":1822},{"style":136},[1823],{"type":21,"value":507},{"type":15,"tag":113,"props":1825,"children":1826},{"class":115,"line":338},[1827],{"type":15,"tag":113,"props":1828,"children":1829},{"style":120},[1830],{"type":21,"value":1831},"    \u002F\u002F 防止除以 0 或负数\n",{"type":15,"tag":113,"props":1833,"children":1834},{"class":115,"line":373},[1835,1840,1844,1849,1854,1859,1864,1869,1874,1878,1883,1888,1893,1898,1903,1908,1912,1916],{"type":15,"tag":113,"props":1836,"children":1837},{"style":136},[1838],{"type":21,"value":1839},"    progress.value ",{"type":15,"tag":113,"props":1841,"children":1842},{"style":130},[1843],{"type":21,"value":628},{"type":15,"tag":113,"props":1845,"children":1846},{"style":136},[1847],{"type":21,"value":1848}," docHeight ",{"type":15,"tag":113,"props":1850,"children":1851},{"style":130},[1852],{"type":21,"value":1853},">",{"type":15,"tag":113,"props":1855,"children":1856},{"style":198},[1857],{"type":21,"value":1858}," 0",{"type":15,"tag":113,"props":1860,"children":1861},{"style":130},[1862],{"type":21,"value":1863}," ?",{"type":15,"tag":113,"props":1865,"children":1866},{"style":136},[1867],{"type":21,"value":1868}," Math.",{"type":15,"tag":113,"props":1870,"children":1871},{"style":172},[1872],{"type":21,"value":1873},"min",{"type":15,"tag":113,"props":1875,"children":1876},{"style":136},[1877],{"type":21,"value":277},{"type":15,"tag":113,"props":1879,"children":1880},{"style":198},[1881],{"type":21,"value":1882},"100",{"type":15,"tag":113,"props":1884,"children":1885},{"style":136},[1886],{"type":21,"value":1887},", (scrollTop ",{"type":15,"tag":113,"props":1889,"children":1890},{"style":130},[1891],{"type":21,"value":1892},"\u002F",{"type":15,"tag":113,"props":1894,"children":1895},{"style":136},[1896],{"type":21,"value":1897}," docHeight) ",{"type":15,"tag":113,"props":1899,"children":1900},{"style":130},[1901],{"type":21,"value":1902},"*",{"type":15,"tag":113,"props":1904,"children":1905},{"style":198},[1906],{"type":21,"value":1907}," 100",{"type":15,"tag":113,"props":1909,"children":1910},{"style":136},[1911],{"type":21,"value":662},{"type":15,"tag":113,"props":1913,"children":1914},{"style":130},[1915],{"type":21,"value":195},{"type":15,"tag":113,"props":1917,"children":1918},{"style":198},[1919],{"type":21,"value":1920}," 0\n",{"type":15,"tag":113,"props":1922,"children":1923},{"class":115,"line":415},[1924,1929,1933],{"type":15,"tag":113,"props":1925,"children":1926},{"style":136},[1927],{"type":21,"value":1928},"    ticking ",{"type":15,"tag":113,"props":1930,"children":1931},{"style":130},[1932],{"type":21,"value":628},{"type":15,"tag":113,"props":1934,"children":1935},{"style":198},[1936],{"type":21,"value":1720},{"type":15,"tag":113,"props":1938,"children":1939},{"class":115,"line":423},[1940],{"type":15,"tag":113,"props":1941,"children":1942},{"style":136},[1943],{"type":21,"value":967},{"type":15,"tag":113,"props":1945,"children":1946},{"class":115,"line":454},[1947],{"type":15,"tag":113,"props":1948,"children":1949},{"emptyLinePlaceholder":157},[1950],{"type":21,"value":160},{"type":15,"tag":113,"props":1952,"children":1953},{"class":115,"line":463},[1954,1958,1963,1967,1971,1975],{"type":15,"tag":113,"props":1955,"children":1956},{"style":130},[1957],{"type":21,"value":306},{"type":15,"tag":113,"props":1959,"children":1960},{"style":172},[1961],{"type":21,"value":1962}," onScroll",{"type":15,"tag":113,"props":1964,"children":1965},{"style":130},[1966],{"type":21,"value":287},{"type":15,"tag":113,"props":1968,"children":1969},{"style":136},[1970],{"type":21,"value":442},{"type":15,"tag":113,"props":1972,"children":1973},{"style":130},[1974],{"type":21,"value":447},{"type":15,"tag":113,"props":1976,"children":1977},{"style":136},[1978],{"type":21,"value":180},{"type":15,"tag":113,"props":1980,"children":1981},{"class":115,"line":501},[1982,1986,1990,1994],{"type":15,"tag":113,"props":1983,"children":1984},{"style":130},[1985],{"type":21,"value":469},{"type":15,"tag":113,"props":1987,"children":1988},{"style":136},[1989],{"type":21,"value":474},{"type":15,"tag":113,"props":1991,"children":1992},{"style":130},[1993],{"type":21,"value":557},{"type":15,"tag":113,"props":1995,"children":1996},{"style":136},[1997],{"type":21,"value":1998},"ticking) {\n",{"type":15,"tag":113,"props":2000,"children":2001},{"class":115,"line":510},[2002,2007,2011],{"type":15,"tag":113,"props":2003,"children":2004},{"style":136},[2005],{"type":21,"value":2006},"      window.",{"type":15,"tag":113,"props":2008,"children":2009},{"style":172},[2010],{"type":21,"value":1603},{"type":15,"tag":113,"props":2012,"children":2013},{"style":136},[2014],{"type":21,"value":2015},"(updateProgress)\n",{"type":15,"tag":113,"props":2017,"children":2018},{"class":115,"line":543},[2019,2024,2028],{"type":15,"tag":113,"props":2020,"children":2021},{"style":136},[2022],{"type":21,"value":2023},"      ticking ",{"type":15,"tag":113,"props":2025,"children":2026},{"style":130},[2027],{"type":21,"value":628},{"type":15,"tag":113,"props":2029,"children":2030},{"style":198},[2031],{"type":21,"value":2032}," true\n",{"type":15,"tag":113,"props":2034,"children":2035},{"class":115,"line":569},[2036],{"type":15,"tag":113,"props":2037,"children":2038},{"style":136},[2039],{"type":21,"value":2040},"    }\n",{"type":15,"tag":113,"props":2042,"children":2043},{"class":115,"line":577},[2044],{"type":15,"tag":113,"props":2045,"children":2046},{"style":136},[2047],{"type":21,"value":967},{"type":15,"tag":113,"props":2049,"children":2050},{"class":115,"line":617},[2051],{"type":15,"tag":113,"props":2052,"children":2053},{"emptyLinePlaceholder":157},[2054],{"type":21,"value":160},{"type":15,"tag":113,"props":2056,"children":2057},{"class":115,"line":674},[2058,2062,2066,2070],{"type":15,"tag":113,"props":2059,"children":2060},{"style":172},[2061],{"type":21,"value":1416},{"type":15,"tag":113,"props":2063,"children":2064},{"style":136},[2065],{"type":21,"value":1421},{"type":15,"tag":113,"props":2067,"children":2068},{"style":130},[2069],{"type":21,"value":447},{"type":15,"tag":113,"props":2071,"children":2072},{"style":136},[2073],{"type":21,"value":180},{"type":15,"tag":113,"props":2075,"children":2076},{"class":115,"line":770},[2077,2082,2087,2091,2096,2101,2106],{"type":15,"tag":113,"props":2078,"children":2079},{"style":136},[2080],{"type":21,"value":2081},"    window.",{"type":15,"tag":113,"props":2083,"children":2084},{"style":172},[2085],{"type":21,"value":2086},"addEventListener",{"type":15,"tag":113,"props":2088,"children":2089},{"style":136},[2090],{"type":21,"value":277},{"type":15,"tag":113,"props":2092,"children":2093},{"style":147},[2094],{"type":21,"value":2095},"'scroll'",{"type":15,"tag":113,"props":2097,"children":2098},{"style":136},[2099],{"type":21,"value":2100},", onScroll, { passive: ",{"type":15,"tag":113,"props":2102,"children":2103},{"style":198},[2104],{"type":21,"value":2105},"true",{"type":15,"tag":113,"props":2107,"children":2108},{"style":136},[2109],{"type":21,"value":2110}," })\n",{"type":15,"tag":113,"props":2112,"children":2113},{"class":115,"line":792},[2114,2119,2124],{"type":15,"tag":113,"props":2115,"children":2116},{"style":172},[2117],{"type":21,"value":2118},"    updateProgress",{"type":15,"tag":113,"props":2120,"children":2121},{"style":136},[2122],{"type":21,"value":2123},"() ",{"type":15,"tag":113,"props":2125,"children":2126},{"style":120},[2127],{"type":21,"value":2128},"\u002F\u002F 初始化\n",{"type":15,"tag":113,"props":2130,"children":2131},{"class":115,"line":830},[2132],{"type":15,"tag":113,"props":2133,"children":2134},{"style":136},[2135],{"type":21,"value":1449},{"type":15,"tag":113,"props":2137,"children":2138},{"class":115,"line":839},[2139],{"type":15,"tag":113,"props":2140,"children":2141},{"emptyLinePlaceholder":157},[2142],{"type":21,"value":160},{"type":15,"tag":113,"props":2144,"children":2145},{"class":115,"line":847},[2146,2150,2154,2158],{"type":15,"tag":113,"props":2147,"children":2148},{"style":172},[2149],{"type":21,"value":1464},{"type":15,"tag":113,"props":2151,"children":2152},{"style":136},[2153],{"type":21,"value":1421},{"type":15,"tag":113,"props":2155,"children":2156},{"style":130},[2157],{"type":21,"value":447},{"type":15,"tag":113,"props":2159,"children":2160},{"style":136},[2161],{"type":21,"value":180},{"type":15,"tag":113,"props":2163,"children":2164},{"class":115,"line":856},[2165,2169,2174,2178,2182],{"type":15,"tag":113,"props":2166,"children":2167},{"style":136},[2168],{"type":21,"value":2081},{"type":15,"tag":113,"props":2170,"children":2171},{"style":172},[2172],{"type":21,"value":2173},"removeEventListener",{"type":15,"tag":113,"props":2175,"children":2176},{"style":136},[2177],{"type":21,"value":277},{"type":15,"tag":113,"props":2179,"children":2180},{"style":147},[2181],{"type":21,"value":2095},{"type":15,"tag":113,"props":2183,"children":2184},{"style":136},[2185],{"type":21,"value":2186},", onScroll)\n",{"type":15,"tag":113,"props":2188,"children":2189},{"class":115,"line":899},[2190],{"type":15,"tag":113,"props":2191,"children":2192},{"style":136},[2193],{"type":21,"value":1449},{"type":15,"tag":113,"props":2195,"children":2196},{"class":115,"line":930},[2197],{"type":15,"tag":113,"props":2198,"children":2199},{"emptyLinePlaceholder":157},[2200],{"type":21,"value":160},{"type":15,"tag":113,"props":2202,"children":2203},{"class":115,"line":939},[2204,2208],{"type":15,"tag":113,"props":2205,"children":2206},{"style":130},[2207],{"type":21,"value":1514},{"type":15,"tag":113,"props":2209,"children":2210},{"style":136},[2211],{"type":21,"value":2212}," { progress }\n",{"type":15,"tag":113,"props":2214,"children":2215},{"class":115,"line":947},[2216],{"type":15,"tag":113,"props":2217,"children":2218},{"style":136},[2219],{"type":21,"value":245},{"type":15,"tag":68,"props":2221,"children":2223},{"id":2222},"_2-结合-tailwind-css-v4-实现丝滑动画",[2224],{"type":21,"value":2225},"2. 结合 Tailwind CSS v4 实现丝滑动画",{"type":15,"tag":23,"props":2227,"children":2228},{},[2229,2231,2237],{"type":21,"value":2230},"在 Nuxt 4 中，我们可以直接使用 Tailwind CSS v4 来渲染进度条。利用 CSS 变量和 ",{"type":15,"tag":80,"props":2232,"children":2234},{"className":2233},[],[2235],{"type":21,"value":2236},"transition",{"type":21,"value":2238},"，可以让进度条的变化更加平滑。",{"type":15,"tag":103,"props":2240,"children":2244},{"className":2241,"code":2242,"language":2243,"meta":7,"style":7},"language-vue shiki shiki-themes github-light github-dark","\u003Ctemplate>\n  \u003Cdiv class=\"fixed top-0 left-0 w-full h-1 z-50 bg-gray-200 dark:bg-gray-800\">\n    \u003Cdiv \n      class=\"h-full bg-blue-500 transition-all duration-150 ease-out\"\n      :style=\"{ width: `${progress}%` }\"\n    \u002F>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup lang=\"ts\">\nconst { progress } = useReadingProgress()\n\u003C\u002Fscript>\n","vue",[2245],{"type":15,"tag":80,"props":2246,"children":2247},{"__ignoreMap":7},[2248,2266,2297,2314,2331,2383,2396,2412,2428,2435,2470,2504],{"type":15,"tag":113,"props":2249,"children":2250},{"class":115,"line":116},[2251,2255,2261],{"type":15,"tag":113,"props":2252,"children":2253},{"style":136},[2254],{"type":21,"value":325},{"type":15,"tag":113,"props":2256,"children":2258},{"style":2257},"--shiki-default:#22863A;--shiki-dark:#85E89D",[2259],{"type":21,"value":2260},"template",{"type":15,"tag":113,"props":2262,"children":2263},{"style":136},[2264],{"type":21,"value":2265},">\n",{"type":15,"tag":113,"props":2267,"children":2268},{"class":115,"line":126},[2269,2274,2279,2284,2288,2293],{"type":15,"tag":113,"props":2270,"children":2271},{"style":136},[2272],{"type":21,"value":2273},"  \u003C",{"type":15,"tag":113,"props":2275,"children":2276},{"style":2257},[2277],{"type":21,"value":2278},"div",{"type":15,"tag":113,"props":2280,"children":2281},{"style":172},[2282],{"type":21,"value":2283}," class",{"type":15,"tag":113,"props":2285,"children":2286},{"style":136},[2287],{"type":21,"value":628},{"type":15,"tag":113,"props":2289,"children":2290},{"style":147},[2291],{"type":21,"value":2292},"\"fixed top-0 left-0 w-full h-1 z-50 bg-gray-200 dark:bg-gray-800\"",{"type":15,"tag":113,"props":2294,"children":2295},{"style":136},[2296],{"type":21,"value":2265},{"type":15,"tag":113,"props":2298,"children":2299},{"class":115,"line":153},[2300,2305,2309],{"type":15,"tag":113,"props":2301,"children":2302},{"style":136},[2303],{"type":21,"value":2304},"    \u003C",{"type":15,"tag":113,"props":2306,"children":2307},{"style":2257},[2308],{"type":21,"value":2278},{"type":15,"tag":113,"props":2310,"children":2311},{"style":136},[2312],{"type":21,"value":2313}," \n",{"type":15,"tag":113,"props":2315,"children":2316},{"class":115,"line":163},[2317,2322,2326],{"type":15,"tag":113,"props":2318,"children":2319},{"style":172},[2320],{"type":21,"value":2321},"      class",{"type":15,"tag":113,"props":2323,"children":2324},{"style":136},[2325],{"type":21,"value":628},{"type":15,"tag":113,"props":2327,"children":2328},{"style":147},[2329],{"type":21,"value":2330},"\"h-full bg-blue-500 transition-all duration-150 ease-out\"\n",{"type":15,"tag":113,"props":2332,"children":2333},{"class":115,"line":183},[2334,2339,2344,2348,2353,2358,2363,2368,2373,2378],{"type":15,"tag":113,"props":2335,"children":2336},{"style":136},[2337],{"type":21,"value":2338},"      :",{"type":15,"tag":113,"props":2340,"children":2341},{"style":172},[2342],{"type":21,"value":2343},"style",{"type":15,"tag":113,"props":2345,"children":2346},{"style":136},[2347],{"type":21,"value":628},{"type":15,"tag":113,"props":2349,"children":2350},{"style":147},[2351],{"type":21,"value":2352},"\"",{"type":15,"tag":113,"props":2354,"children":2355},{"style":136},[2356],{"type":21,"value":2357},"{ width: ",{"type":15,"tag":113,"props":2359,"children":2360},{"style":147},[2361],{"type":21,"value":2362},"`${",{"type":15,"tag":113,"props":2364,"children":2365},{"style":136},[2366],{"type":21,"value":2367},"progress",{"type":15,"tag":113,"props":2369,"children":2370},{"style":147},[2371],{"type":21,"value":2372},"}%`",{"type":15,"tag":113,"props":2374,"children":2375},{"style":136},[2376],{"type":21,"value":2377}," }",{"type":15,"tag":113,"props":2379,"children":2380},{"style":147},[2381],{"type":21,"value":2382},"\"\n",{"type":15,"tag":113,"props":2384,"children":2385},{"class":115,"line":204},[2386,2392],{"type":15,"tag":113,"props":2387,"children":2389},{"style":2388},"--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic",[2390],{"type":21,"value":2391},"    \u002F",{"type":15,"tag":113,"props":2393,"children":2394},{"style":136},[2395],{"type":21,"value":2265},{"type":15,"tag":113,"props":2397,"children":2398},{"class":115,"line":221},[2399,2404,2408],{"type":15,"tag":113,"props":2400,"children":2401},{"style":136},[2402],{"type":21,"value":2403},"  \u003C\u002F",{"type":15,"tag":113,"props":2405,"children":2406},{"style":2257},[2407],{"type":21,"value":2278},{"type":15,"tag":113,"props":2409,"children":2410},{"style":136},[2411],{"type":21,"value":2265},{"type":15,"tag":113,"props":2413,"children":2414},{"class":115,"line":239},[2415,2420,2424],{"type":15,"tag":113,"props":2416,"children":2417},{"style":136},[2418],{"type":21,"value":2419},"\u003C\u002F",{"type":15,"tag":113,"props":2421,"children":2422},{"style":2257},[2423],{"type":21,"value":2260},{"type":15,"tag":113,"props":2425,"children":2426},{"style":136},[2427],{"type":21,"value":2265},{"type":15,"tag":113,"props":2429,"children":2430},{"class":115,"line":248},[2431],{"type":15,"tag":113,"props":2432,"children":2433},{"emptyLinePlaceholder":157},[2434],{"type":21,"value":160},{"type":15,"tag":113,"props":2436,"children":2437},{"class":115,"line":256},[2438,2442,2447,2452,2457,2461,2466],{"type":15,"tag":113,"props":2439,"children":2440},{"style":136},[2441],{"type":21,"value":325},{"type":15,"tag":113,"props":2443,"children":2444},{"style":2257},[2445],{"type":21,"value":2446},"script",{"type":15,"tag":113,"props":2448,"children":2449},{"style":172},[2450],{"type":21,"value":2451}," setup",{"type":15,"tag":113,"props":2453,"children":2454},{"style":172},[2455],{"type":21,"value":2456}," lang",{"type":15,"tag":113,"props":2458,"children":2459},{"style":136},[2460],{"type":21,"value":628},{"type":15,"tag":113,"props":2462,"children":2463},{"style":147},[2464],{"type":21,"value":2465},"\"ts\"",{"type":15,"tag":113,"props":2467,"children":2468},{"style":136},[2469],{"type":21,"value":2265},{"type":15,"tag":113,"props":2471,"children":2472},{"class":115,"line":300},[2473,2478,2483,2487,2492,2496,2500],{"type":15,"tag":113,"props":2474,"children":2475},{"style":130},[2476],{"type":21,"value":2477},"const",{"type":15,"tag":113,"props":2479,"children":2480},{"style":136},[2481],{"type":21,"value":2482}," { ",{"type":15,"tag":113,"props":2484,"children":2485},{"style":198},[2486],{"type":21,"value":2367},{"type":15,"tag":113,"props":2488,"children":2489},{"style":136},[2490],{"type":21,"value":2491}," } ",{"type":15,"tag":113,"props":2493,"children":2494},{"style":130},[2495],{"type":21,"value":628},{"type":15,"tag":113,"props":2497,"children":2498},{"style":172},[2499],{"type":21,"value":1662},{"type":15,"tag":113,"props":2501,"children":2502},{"style":136},[2503],{"type":21,"value":958},{"type":15,"tag":113,"props":2505,"children":2506},{"class":115,"line":338},[2507,2511,2515],{"type":15,"tag":113,"props":2508,"children":2509},{"style":136},[2510],{"type":21,"value":2419},{"type":15,"tag":113,"props":2512,"children":2513},{"style":2257},[2514],{"type":21,"value":2446},{"type":15,"tag":113,"props":2516,"children":2517},{"style":136},[2518],{"type":21,"value":2265},{"type":15,"tag":23,"props":2520,"children":2521},{},[2522],{"type":15,"tag":29,"props":2523,"children":2524},{},[2525],{"type":21,"value":2526},"💡 优化细节：",{"type":15,"tag":2528,"props":2529,"children":2530},"ol",{},[2531,2553],{"type":15,"tag":2532,"props":2533,"children":2534},"li",{},[2535,2537,2543,2545,2551],{"type":21,"value":2536},"使用 ",{"type":15,"tag":80,"props":2538,"children":2540},{"className":2539},[],[2541],{"type":21,"value":2542},"passive: true",{"type":21,"value":2544}," 监听滚动事件，告诉浏览器不会调用 ",{"type":15,"tag":80,"props":2546,"children":2548},{"className":2547},[],[2549],{"type":21,"value":2550},"preventDefault()",{"type":21,"value":2552},"，从而提升滚动性能。",{"type":15,"tag":2532,"props":2554,"children":2555},{},[2556,2558,2564],{"type":21,"value":2557},"进度条使用 ",{"type":15,"tag":80,"props":2559,"children":2561},{"className":2560},[],[2562],{"type":21,"value":2563},"transition-all duration-150",{"type":21,"value":2565},"，避免数值跳变带来的视觉突兀感。",{"type":15,"tag":56,"props":2567,"children":2569},{"id":2568},"三-总结",[2570],{"type":21,"value":2571},"三、 总结",{"type":15,"tag":23,"props":2573,"children":2574},{},[2575,2577,2582],{"type":21,"value":2576},"通过这次重构，我深刻体会到：",{"type":15,"tag":29,"props":2578,"children":2579},{},[2580],{"type":21,"value":2581},"优秀的阅读体验是由无数个细节堆砌而成的",{"type":21,"value":2583},"。",{"type":15,"tag":2585,"props":2586,"children":2587},"ul",{},[2588,2598,2610],{"type":15,"tag":2532,"props":2589,"children":2590},{},[2591,2596],{"type":15,"tag":29,"props":2592,"children":2593},{},[2594],{"type":21,"value":2595},"Intersection Observer",{"type":21,"value":2597}," 替代传统的滚动监听，是处理目录高亮的最佳实践。",{"type":15,"tag":2532,"props":2599,"children":2600},{},[2601,2603,2608],{"type":21,"value":2602},"在 SSR 框架（如 Nuxt）中，时刻牢记",{"type":15,"tag":29,"props":2604,"children":2605},{},[2606],{"type":21,"value":2607},"客户端与服务端的环境差异",{"type":21,"value":2609},"，避免 hydration mismatch（水合不匹配）错误。",{"type":15,"tag":2532,"props":2611,"children":2612},{},[2613,2615,2620,2622,2627],{"type":21,"value":2614},"善用 ",{"type":15,"tag":80,"props":2616,"children":2618},{"className":2617},[],[2619],{"type":21,"value":1603},{"type":21,"value":2621}," 和 CSS ",{"type":15,"tag":80,"props":2623,"children":2625},{"className":2624},[],[2626],{"type":21,"value":2236},{"type":21,"value":2628},"，可以用极低的成本换取丝滑的视觉体验。",{"type":15,"tag":23,"props":2630,"children":2631},{},[2632,2634,2643],{"type":21,"value":2633},"目前这两个功能已经在 ",{"type":15,"tag":2635,"props":2636,"children":2640},"a",{"href":2637,"rel":2638},"https:\u002F\u002Fninglab.top",[2639],"nofollow",[2641],{"type":21,"value":2642},"ninglab.top",{"type":21,"value":2644}," 上线，阅读体验有了显著提升。下一步，我计划引入 Giscus 评论系统，让博客真正“活”起来。",{"type":15,"tag":23,"props":2646,"children":2647},{},[2648],{"type":21,"value":2649},"如果你也在重构博客，或者对 Nuxt 4 的某些特性有疑问，欢迎在评论区交流！",{"type":15,"tag":2343,"props":2651,"children":2652},{},[2653],{"type":21,"value":2654},"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);}",{"title":7,"searchDepth":126,"depth":126,"links":2656},[2657,2661,2665],{"id":58,"depth":126,"text":61,"children":2658},[2659,2660],{"id":70,"depth":153,"text":73},{"id":995,"depth":153,"text":998},{"id":1571,"depth":126,"text":1574,"children":2662},[2663,2664],{"id":1582,"depth":153,"text":1585},{"id":2222,"depth":153,"text":2225},{"id":2568,"depth":126,"text":2571},"markdown","content:blog:3-post.md","content","blog\u002F3-post.md","blog\u002F3-post","md","2LK7M1",[2674,4950,7404],{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"body":2675,"_type":2666,"_id":2667,"_source":2668,"_file":2669,"_stem":2670,"_extension":2671,"code":2672},{"type":12,"children":2676,"toc":4939},[2677,2681,2690,2704,2708,2712,2716,2738,3470,3474,3489,3952,3984,3988,3992,3996,4012,4576,4580,4590,4836,4843,4872,4876,4885,4921,4931,4935],{"type":15,"tag":16,"props":2678,"children":2679},{"id":18},[2680],{"type":21,"value":8},{"type":15,"tag":23,"props":2682,"children":2683},{},[2684,2685,2689],{"type":21,"value":27},{"type":15,"tag":29,"props":2686,"children":2687},{},[2688],{"type":21,"value":33},{"type":21,"value":35},{"type":15,"tag":23,"props":2691,"children":2692},{},[2693,2694,2703],{"type":21,"value":40},{"type":15,"tag":29,"props":2695,"children":2696},{},[2697,2698,2702],{"type":21,"value":45},{"type":15,"tag":29,"props":2699,"children":2700},{},[2701],{"type":21,"value":50},{"type":21,"value":52},{"type":21,"value":54},{"type":15,"tag":56,"props":2705,"children":2706},{"id":58},[2707],{"type":21,"value":61},{"type":15,"tag":23,"props":2709,"children":2710},{},[2711],{"type":21,"value":66},{"type":15,"tag":68,"props":2713,"children":2714},{"id":70},[2715],{"type":21,"value":73},{"type":15,"tag":23,"props":2717,"children":2718},{},[2719,2720,2725,2726,2731,2732,2737],{"type":21,"value":78},{"type":15,"tag":80,"props":2721,"children":2723},{"className":2722},[],[2724],{"type":21,"value":85},{"type":21,"value":87},{"type":15,"tag":80,"props":2727,"children":2729},{"className":2728},[],[2730],{"type":21,"value":56},{"type":21,"value":94},{"type":15,"tag":80,"props":2733,"children":2735},{"className":2734},[],[2736],{"type":21,"value":68},{"type":21,"value":101},{"type":15,"tag":103,"props":2739,"children":2740},{"className":105,"code":106,"language":107,"meta":7,"style":7},[2741],{"type":15,"tag":80,"props":2742,"children":2743},{"__ignoreMap":7},[2744,2751,2770,2777,2792,2807,2822,2837,2844,2851,2886,2917,2948,2983,2990,3017,3024,3055,3062,3089,3112,3119,3154,3201,3280,3299,3330,3337,3344,3351,3390,3417,3424,3431,3442,3449,3456,3463],{"type":15,"tag":113,"props":2745,"children":2746},{"class":115,"line":116},[2747],{"type":15,"tag":113,"props":2748,"children":2749},{"style":120},[2750],{"type":21,"value":123},{"type":15,"tag":113,"props":2752,"children":2753},{"class":115,"line":126},[2754,2758,2762,2766],{"type":15,"tag":113,"props":2755,"children":2756},{"style":130},[2757],{"type":21,"value":133},{"type":15,"tag":113,"props":2759,"children":2760},{"style":136},[2761],{"type":21,"value":139},{"type":15,"tag":113,"props":2763,"children":2764},{"style":130},[2765],{"type":21,"value":144},{"type":15,"tag":113,"props":2767,"children":2768},{"style":147},[2769],{"type":21,"value":150},{"type":15,"tag":113,"props":2771,"children":2772},{"class":115,"line":153},[2773],{"type":15,"tag":113,"props":2774,"children":2775},{"emptyLinePlaceholder":157},[2776],{"type":21,"value":160},{"type":15,"tag":113,"props":2778,"children":2779},{"class":115,"line":163},[2780,2784,2788],{"type":15,"tag":113,"props":2781,"children":2782},{"style":130},[2783],{"type":21,"value":169},{"type":15,"tag":113,"props":2785,"children":2786},{"style":172},[2787],{"type":21,"value":175},{"type":15,"tag":113,"props":2789,"children":2790},{"style":136},[2791],{"type":21,"value":180},{"type":15,"tag":113,"props":2793,"children":2794},{"class":115,"line":183},[2795,2799,2803],{"type":15,"tag":113,"props":2796,"children":2797},{"style":187},[2798],{"type":21,"value":190},{"type":15,"tag":113,"props":2800,"children":2801},{"style":130},[2802],{"type":21,"value":195},{"type":15,"tag":113,"props":2804,"children":2805},{"style":198},[2806],{"type":21,"value":201},{"type":15,"tag":113,"props":2808,"children":2809},{"class":115,"line":204},[2810,2814,2818],{"type":15,"tag":113,"props":2811,"children":2812},{"style":187},[2813],{"type":21,"value":210},{"type":15,"tag":113,"props":2815,"children":2816},{"style":130},[2817],{"type":21,"value":195},{"type":15,"tag":113,"props":2819,"children":2820},{"style":198},[2821],{"type":21,"value":201},{"type":15,"tag":113,"props":2823,"children":2824},{"class":115,"line":221},[2825,2829,2833],{"type":15,"tag":113,"props":2826,"children":2827},{"style":187},[2828],{"type":21,"value":227},{"type":15,"tag":113,"props":2830,"children":2831},{"style":130},[2832],{"type":21,"value":195},{"type":15,"tag":113,"props":2834,"children":2835},{"style":198},[2836],{"type":21,"value":236},{"type":15,"tag":113,"props":2838,"children":2839},{"class":115,"line":239},[2840],{"type":15,"tag":113,"props":2841,"children":2842},{"style":136},[2843],{"type":21,"value":245},{"type":15,"tag":113,"props":2845,"children":2846},{"class":115,"line":248},[2847],{"type":15,"tag":113,"props":2848,"children":2849},{"emptyLinePlaceholder":157},[2850],{"type":21,"value":160},{"type":15,"tag":113,"props":2852,"children":2853},{"class":115,"line":256},[2854,2858,2862,2866,2870,2874,2878,2882],{"type":15,"tag":113,"props":2855,"children":2856},{"style":130},[2857],{"type":21,"value":262},{"type":15,"tag":113,"props":2859,"children":2860},{"style":130},[2861],{"type":21,"value":267},{"type":15,"tag":113,"props":2863,"children":2864},{"style":172},[2865],{"type":21,"value":272},{"type":15,"tag":113,"props":2867,"children":2868},{"style":136},[2869],{"type":21,"value":277},{"type":15,"tag":113,"props":2871,"children":2872},{"style":187},[2873],{"type":21,"value":282},{"type":15,"tag":113,"props":2875,"children":2876},{"style":130},[2877],{"type":21,"value":287},{"type":15,"tag":113,"props":2879,"children":2880},{"style":147},[2881],{"type":21,"value":292},{"type":15,"tag":113,"props":2883,"children":2884},{"style":136},[2885],{"type":21,"value":297},{"type":15,"tag":113,"props":2887,"children":2888},{"class":115,"line":300},[2889,2893,2897,2901,2905,2909,2913],{"type":15,"tag":113,"props":2890,"children":2891},{"style":130},[2892],{"type":21,"value":306},{"type":15,"tag":113,"props":2894,"children":2895},{"style":198},[2896],{"type":21,"value":311},{"type":15,"tag":113,"props":2898,"children":2899},{"style":130},[2900],{"type":21,"value":287},{"type":15,"tag":113,"props":2902,"children":2903},{"style":172},[2904],{"type":21,"value":320},{"type":15,"tag":113,"props":2906,"children":2907},{"style":136},[2908],{"type":21,"value":325},{"type":15,"tag":113,"props":2910,"children":2911},{"style":172},[2912],{"type":21,"value":330},{"type":15,"tag":113,"props":2914,"children":2915},{"style":136},[2916],{"type":21,"value":335},{"type":15,"tag":113,"props":2918,"children":2919},{"class":115,"line":338},[2920,2924,2928,2932,2936,2940,2944],{"type":15,"tag":113,"props":2921,"children":2922},{"style":130},[2923],{"type":21,"value":306},{"type":15,"tag":113,"props":2925,"children":2926},{"style":198},[2927],{"type":21,"value":348},{"type":15,"tag":113,"props":2929,"children":2930},{"style":130},[2931],{"type":21,"value":287},{"type":15,"tag":113,"props":2933,"children":2934},{"style":172},[2935],{"type":21,"value":320},{"type":15,"tag":113,"props":2937,"children":2938},{"style":136},[2939],{"type":21,"value":277},{"type":15,"tag":113,"props":2941,"children":2942},{"style":147},[2943],{"type":21,"value":365},{"type":15,"tag":113,"props":2945,"children":2946},{"style":136},[2947],{"type":21,"value":370},{"type":15,"tag":113,"props":2949,"children":2950},{"class":115,"line":373},[2951,2955,2959,2963,2967,2971,2975,2979],{"type":15,"tag":113,"props":2952,"children":2953},{"style":130},[2954],{"type":21,"value":379},{"type":15,"tag":113,"props":2956,"children":2957},{"style":136},[2958],{"type":21,"value":384},{"type":15,"tag":113,"props":2960,"children":2961},{"style":130},[2962],{"type":21,"value":195},{"type":15,"tag":113,"props":2964,"children":2965},{"style":172},[2966],{"type":21,"value":393},{"type":15,"tag":113,"props":2968,"children":2969},{"style":130},[2970],{"type":21,"value":398},{"type":15,"tag":113,"props":2972,"children":2973},{"style":198},[2974],{"type":21,"value":403},{"type":15,"tag":113,"props":2976,"children":2977},{"style":130},[2978],{"type":21,"value":287},{"type":15,"tag":113,"props":2980,"children":2981},{"style":198},[2982],{"type":21,"value":412},{"type":15,"tag":113,"props":2984,"children":2985},{"class":115,"line":415},[2986],{"type":15,"tag":113,"props":2987,"children":2988},{"emptyLinePlaceholder":157},[2989],{"type":21,"value":160},{"type":15,"tag":113,"props":2991,"children":2992},{"class":115,"line":423},[2993,2997,3001,3005,3009,3013],{"type":15,"tag":113,"props":2994,"children":2995},{"style":130},[2996],{"type":21,"value":306},{"type":15,"tag":113,"props":2998,"children":2999},{"style":172},[3000],{"type":21,"value":433},{"type":15,"tag":113,"props":3002,"children":3003},{"style":130},[3004],{"type":21,"value":287},{"type":15,"tag":113,"props":3006,"children":3007},{"style":136},[3008],{"type":21,"value":442},{"type":15,"tag":113,"props":3010,"children":3011},{"style":130},[3012],{"type":21,"value":447},{"type":15,"tag":113,"props":3014,"children":3015},{"style":136},[3016],{"type":21,"value":180},{"type":15,"tag":113,"props":3018,"children":3019},{"class":115,"line":454},[3020],{"type":15,"tag":113,"props":3021,"children":3022},{"style":120},[3023],{"type":21,"value":460},{"type":15,"tag":113,"props":3025,"children":3026},{"class":115,"line":463},[3027,3031,3035,3039,3043,3047,3051],{"type":15,"tag":113,"props":3028,"children":3029},{"style":130},[3030],{"type":21,"value":469},{"type":15,"tag":113,"props":3032,"children":3033},{"style":136},[3034],{"type":21,"value":474},{"type":15,"tag":113,"props":3036,"children":3037},{"style":130},[3038],{"type":21,"value":133},{"type":15,"tag":113,"props":3040,"children":3041},{"style":136},[3042],{"type":21,"value":483},{"type":15,"tag":113,"props":3044,"children":3045},{"style":198},[3046],{"type":21,"value":488},{"type":15,"tag":113,"props":3048,"children":3049},{"style":136},[3050],{"type":21,"value":493},{"type":15,"tag":113,"props":3052,"children":3053},{"style":130},[3054],{"type":21,"value":498},{"type":15,"tag":113,"props":3056,"children":3057},{"class":115,"line":501},[3058],{"type":15,"tag":113,"props":3059,"children":3060},{"style":136},[3061],{"type":21,"value":507},{"type":15,"tag":113,"props":3063,"children":3064},{"class":115,"line":510},[3065,3069,3073,3077,3081,3085],{"type":15,"tag":113,"props":3066,"children":3067},{"style":130},[3068],{"type":21,"value":516},{"type":15,"tag":113,"props":3070,"children":3071},{"style":198},[3072],{"type":21,"value":521},{"type":15,"tag":113,"props":3074,"children":3075},{"style":130},[3076],{"type":21,"value":287},{"type":15,"tag":113,"props":3078,"children":3079},{"style":136},[3080],{"type":21,"value":530},{"type":15,"tag":113,"props":3082,"children":3083},{"style":172},[3084],{"type":21,"value":535},{"type":15,"tag":113,"props":3086,"children":3087},{"style":136},[3088],{"type":21,"value":540},{"type":15,"tag":113,"props":3090,"children":3091},{"class":115,"line":543},[3092,3096,3100,3104,3108],{"type":15,"tag":113,"props":3093,"children":3094},{"style":130},[3095],{"type":21,"value":469},{"type":15,"tag":113,"props":3097,"children":3098},{"style":136},[3099],{"type":21,"value":474},{"type":15,"tag":113,"props":3101,"children":3102},{"style":130},[3103],{"type":21,"value":557},{"type":15,"tag":113,"props":3105,"children":3106},{"style":136},[3107],{"type":21,"value":562},{"type":15,"tag":113,"props":3109,"children":3110},{"style":130},[3111],{"type":21,"value":498},{"type":15,"tag":113,"props":3113,"children":3114},{"class":115,"line":569},[3115],{"type":15,"tag":113,"props":3116,"children":3117},{"emptyLinePlaceholder":157},[3118],{"type":21,"value":160},{"type":15,"tag":113,"props":3120,"children":3121},{"class":115,"line":577},[3122,3126,3130,3134,3138,3142,3146,3150],{"type":15,"tag":113,"props":3123,"children":3124},{"style":130},[3125],{"type":21,"value":516},{"type":15,"tag":113,"props":3127,"children":3128},{"style":198},[3129],{"type":21,"value":587},{"type":15,"tag":113,"props":3131,"children":3132},{"style":130},[3133],{"type":21,"value":287},{"type":15,"tag":113,"props":3135,"children":3136},{"style":136},[3137],{"type":21,"value":596},{"type":15,"tag":113,"props":3139,"children":3140},{"style":172},[3141],{"type":21,"value":601},{"type":15,"tag":113,"props":3143,"children":3144},{"style":136},[3145],{"type":21,"value":277},{"type":15,"tag":113,"props":3147,"children":3148},{"style":147},[3149],{"type":21,"value":610},{"type":15,"tag":113,"props":3151,"children":3152},{"style":136},[3153],{"type":21,"value":370},{"type":15,"tag":113,"props":3155,"children":3156},{"class":115,"line":617},[3157,3161,3165,3169,3173,3177,3181,3185,3189,3193,3197],{"type":15,"tag":113,"props":3158,"children":3159},{"style":136},[3160],{"type":21,"value":623},{"type":15,"tag":113,"props":3162,"children":3163},{"style":130},[3164],{"type":21,"value":628},{"type":15,"tag":113,"props":3166,"children":3167},{"style":136},[3168],{"type":21,"value":633},{"type":15,"tag":113,"props":3170,"children":3171},{"style":172},[3172],{"type":21,"value":144},{"type":15,"tag":113,"props":3174,"children":3175},{"style":136},[3176],{"type":21,"value":642},{"type":15,"tag":113,"props":3178,"children":3179},{"style":172},[3180],{"type":21,"value":647},{"type":15,"tag":113,"props":3182,"children":3183},{"style":136},[3184],{"type":21,"value":652},{"type":15,"tag":113,"props":3186,"children":3187},{"style":187},[3188],{"type":21,"value":657},{"type":15,"tag":113,"props":3190,"children":3191},{"style":136},[3192],{"type":21,"value":662},{"type":15,"tag":113,"props":3194,"children":3195},{"style":130},[3196],{"type":21,"value":447},{"type":15,"tag":113,"props":3198,"children":3199},{"style":136},[3200],{"type":21,"value":671},{"type":15,"tag":113,"props":3202,"children":3203},{"class":115,"line":674},[3204,3208,3212,3216,3220,3224,3228,3232,3236,3240,3244,3248,3252,3256,3260,3264,3268,3272,3276],{"type":15,"tag":113,"props":3205,"children":3206},{"style":136},[3207],{"type":21,"value":680},{"type":15,"tag":113,"props":3209,"children":3210},{"style":130},[3211],{"type":21,"value":685},{"type":15,"tag":113,"props":3213,"children":3214},{"style":147},[3215],{"type":21,"value":690},{"type":15,"tag":113,"props":3217,"children":3218},{"style":136},[3219],{"type":21,"value":695},{"type":15,"tag":113,"props":3221,"children":3222},{"style":147},[3223],{"type":21,"value":483},{"type":15,"tag":113,"props":3225,"children":3226},{"style":172},[3227],{"type":21,"value":704},{"type":15,"tag":113,"props":3229,"children":3230},{"style":147},[3231],{"type":21,"value":709},{"type":15,"tag":113,"props":3233,"children":3234},{"style":172},[3235],{"type":21,"value":714},{"type":15,"tag":113,"props":3237,"children":3238},{"style":147},[3239],{"type":21,"value":277},{"type":15,"tag":113,"props":3241,"children":3242},{"style":198},[3243],{"type":21,"value":723},{"type":15,"tag":113,"props":3245,"children":3246},{"style":147},[3247],{"type":21,"value":728},{"type":15,"tag":113,"props":3249,"children":3250},{"style":172},[3251],{"type":21,"value":733},{"type":15,"tag":113,"props":3253,"children":3254},{"style":147},[3255],{"type":21,"value":277},{"type":15,"tag":113,"props":3257,"children":3258},{"style":198},[3259],{"type":21,"value":742},{"type":15,"tag":113,"props":3261,"children":3262},{"style":147},[3263],{"type":21,"value":747},{"type":15,"tag":113,"props":3265,"children":3266},{"style":198},[3267],{"type":21,"value":752},{"type":15,"tag":113,"props":3269,"children":3270},{"style":147},[3271],{"type":21,"value":757},{"type":15,"tag":113,"props":3273,"children":3274},{"style":147},[3275],{"type":21,"value":762},{"type":15,"tag":113,"props":3277,"children":3278},{"style":136},[3279],{"type":21,"value":767},{"type":15,"tag":113,"props":3281,"children":3282},{"class":115,"line":770},[3283,3287,3291,3295],{"type":15,"tag":113,"props":3284,"children":3285},{"style":136},[3286],{"type":21,"value":776},{"type":15,"tag":113,"props":3288,"children":3289},{"style":130},[3290],{"type":21,"value":685},{"type":15,"tag":113,"props":3292,"children":3293},{"style":147},[3294],{"type":21,"value":785},{"type":15,"tag":113,"props":3296,"children":3297},{"style":136},[3298],{"type":21,"value":767},{"type":15,"tag":113,"props":3300,"children":3301},{"class":115,"line":792},[3302,3306,3310,3314,3318,3322,3326],{"type":15,"tag":113,"props":3303,"children":3304},{"style":136},[3305],{"type":21,"value":798},{"type":15,"tag":113,"props":3307,"children":3308},{"style":172},[3309],{"type":21,"value":803},{"type":15,"tag":113,"props":3311,"children":3312},{"style":136},[3313],{"type":21,"value":808},{"type":15,"tag":113,"props":3315,"children":3316},{"style":172},[3317],{"type":21,"value":813},{"type":15,"tag":113,"props":3319,"children":3320},{"style":136},[3321],{"type":21,"value":277},{"type":15,"tag":113,"props":3323,"children":3324},{"style":198},[3325],{"type":21,"value":822},{"type":15,"tag":113,"props":3327,"children":3328},{"style":136},[3329],{"type":21,"value":827},{"type":15,"tag":113,"props":3331,"children":3332},{"class":115,"line":830},[3333],{"type":15,"tag":113,"props":3334,"children":3335},{"style":136},[3336],{"type":21,"value":836},{"type":15,"tag":113,"props":3338,"children":3339},{"class":115,"line":839},[3340],{"type":15,"tag":113,"props":3341,"children":3342},{"emptyLinePlaceholder":157},[3343],{"type":21,"value":160},{"type":15,"tag":113,"props":3345,"children":3346},{"class":115,"line":847},[3347],{"type":15,"tag":113,"props":3348,"children":3349},{"style":120},[3350],{"type":21,"value":853},{"type":15,"tag":113,"props":3352,"children":3353},{"class":115,"line":856},[3354,3358,3362,3366,3370,3374,3378,3382,3386],{"type":15,"tag":113,"props":3355,"children":3356},{"style":136},[3357],{"type":21,"value":862},{"type":15,"tag":113,"props":3359,"children":3360},{"style":172},[3361],{"type":21,"value":867},{"type":15,"tag":113,"props":3363,"children":3364},{"style":136},[3365],{"type":21,"value":652},{"type":15,"tag":113,"props":3367,"children":3368},{"style":187},[3369],{"type":21,"value":657},{"type":15,"tag":113,"props":3371,"children":3372},{"style":136},[3373],{"type":21,"value":747},{"type":15,"tag":113,"props":3375,"children":3376},{"style":187},[3377],{"type":21,"value":884},{"type":15,"tag":113,"props":3379,"children":3380},{"style":136},[3381],{"type":21,"value":662},{"type":15,"tag":113,"props":3383,"children":3384},{"style":130},[3385],{"type":21,"value":447},{"type":15,"tag":113,"props":3387,"children":3388},{"style":136},[3389],{"type":21,"value":180},{"type":15,"tag":113,"props":3391,"children":3392},{"class":115,"line":899},[3393,3397,3401,3405,3409,3413],{"type":15,"tag":113,"props":3394,"children":3395},{"style":130},[3396],{"type":21,"value":905},{"type":15,"tag":113,"props":3398,"children":3399},{"style":136},[3400],{"type":21,"value":474},{"type":15,"tag":113,"props":3402,"children":3403},{"style":130},[3404],{"type":21,"value":557},{"type":15,"tag":113,"props":3406,"children":3407},{"style":136},[3408],{"type":21,"value":918},{"type":15,"tag":113,"props":3410,"children":3411},{"style":130},[3412],{"type":21,"value":628},{"type":15,"tag":113,"props":3414,"children":3415},{"style":136},[3416],{"type":21,"value":927},{"type":15,"tag":113,"props":3418,"children":3419},{"class":115,"line":930},[3420],{"type":15,"tag":113,"props":3421,"children":3422},{"style":136},[3423],{"type":21,"value":936},{"type":15,"tag":113,"props":3425,"children":3426},{"class":115,"line":939},[3427],{"type":15,"tag":113,"props":3428,"children":3429},{"style":136},[3430],{"type":21,"value":507},{"type":15,"tag":113,"props":3432,"children":3433},{"class":115,"line":947},[3434,3438],{"type":15,"tag":113,"props":3435,"children":3436},{"style":172},[3437],{"type":21,"value":953},{"type":15,"tag":113,"props":3439,"children":3440},{"style":136},[3441],{"type":21,"value":958},{"type":15,"tag":113,"props":3443,"children":3444},{"class":115,"line":961},[3445],{"type":15,"tag":113,"props":3446,"children":3447},{"style":136},[3448],{"type":21,"value":967},{"type":15,"tag":113,"props":3450,"children":3451},{"class":115,"line":970},[3452],{"type":15,"tag":113,"props":3453,"children":3454},{"emptyLinePlaceholder":157},[3455],{"type":21,"value":160},{"type":15,"tag":113,"props":3457,"children":3458},{"class":115,"line":978},[3459],{"type":15,"tag":113,"props":3460,"children":3461},{"style":120},[3462],{"type":21,"value":984},{"type":15,"tag":113,"props":3464,"children":3465},{"class":115,"line":987},[3466],{"type":15,"tag":113,"props":3467,"children":3468},{"style":136},[3469],{"type":21,"value":245},{"type":15,"tag":68,"props":3471,"children":3472},{"id":995},[3473],{"type":21,"value":998},{"type":15,"tag":23,"props":3475,"children":3476},{},[3477,3478,3483,3484,3488],{"type":21,"value":1003},{"type":15,"tag":80,"props":3479,"children":3481},{"className":3480},[],[3482],{"type":21,"value":1009},{"type":21,"value":1011},{"type":15,"tag":29,"props":3485,"children":3486},{},[3487],{"type":21,"value":1016},{"type":21,"value":1018},{"type":15,"tag":103,"props":3490,"children":3491},{"className":105,"code":1021,"language":107,"meta":7,"style":7},[3492],{"type":15,"tag":80,"props":3493,"children":3494},{"__ignoreMap":7},[3495,3522,3541,3548,3571,3594,3625,3632,3643,3658,3665,3672,3679,3686,3693,3708,3723,3730,3737,3744,3775,3802,3821,3828,3835,3842,3861,3872,3879,3886,3905,3920,3927,3934,3945],{"type":15,"tag":113,"props":3496,"children":3497},{"class":115,"line":116},[3498,3502,3506,3510,3514,3518],{"type":15,"tag":113,"props":3499,"children":3500},{"style":130},[3501],{"type":21,"value":306},{"type":15,"tag":113,"props":3503,"children":3504},{"style":172},[3505],{"type":21,"value":1037},{"type":15,"tag":113,"props":3507,"children":3508},{"style":130},[3509],{"type":21,"value":287},{"type":15,"tag":113,"props":3511,"children":3512},{"style":136},[3513],{"type":21,"value":442},{"type":15,"tag":113,"props":3515,"children":3516},{"style":130},[3517],{"type":21,"value":447},{"type":15,"tag":113,"props":3519,"children":3520},{"style":136},[3521],{"type":21,"value":180},{"type":15,"tag":113,"props":3523,"children":3524},{"class":115,"line":126},[3525,3529,3533,3537],{"type":15,"tag":113,"props":3526,"children":3527},{"style":130},[3528],{"type":21,"value":469},{"type":15,"tag":113,"props":3530,"children":3531},{"style":136},[3532],{"type":21,"value":1065},{"type":15,"tag":113,"props":3534,"children":3535},{"style":172},[3536],{"type":21,"value":1070},{"type":15,"tag":113,"props":3538,"children":3539},{"style":136},[3540],{"type":21,"value":958},{"type":15,"tag":113,"props":3542,"children":3543},{"class":115,"line":153},[3544],{"type":15,"tag":113,"props":3545,"children":3546},{"emptyLinePlaceholder":157},[3547],{"type":21,"value":160},{"type":15,"tag":113,"props":3549,"children":3550},{"class":115,"line":163},[3551,3555,3559,3563,3567],{"type":15,"tag":113,"props":3552,"children":3553},{"style":136},[3554],{"type":21,"value":1089},{"type":15,"tag":113,"props":3556,"children":3557},{"style":130},[3558],{"type":21,"value":628},{"type":15,"tag":113,"props":3560,"children":3561},{"style":130},[3562],{"type":21,"value":1098},{"type":15,"tag":113,"props":3564,"children":3565},{"style":172},[3566],{"type":21,"value":393},{"type":15,"tag":113,"props":3568,"children":3569},{"style":136},[3570],{"type":21,"value":1107},{"type":15,"tag":113,"props":3572,"children":3573},{"class":115,"line":183},[3574,3578,3582,3586,3590],{"type":15,"tag":113,"props":3575,"children":3576},{"style":136},[3577],{"type":21,"value":1115},{"type":15,"tag":113,"props":3579,"children":3580},{"style":187},[3581],{"type":21,"value":1120},{"type":15,"tag":113,"props":3583,"children":3584},{"style":136},[3585],{"type":21,"value":662},{"type":15,"tag":113,"props":3587,"children":3588},{"style":130},[3589],{"type":21,"value":447},{"type":15,"tag":113,"props":3591,"children":3592},{"style":136},[3593],{"type":21,"value":180},{"type":15,"tag":113,"props":3595,"children":3596},{"class":115,"line":204},[3597,3601,3605,3609,3613,3617,3621],{"type":15,"tag":113,"props":3598,"children":3599},{"style":136},[3600],{"type":21,"value":1140},{"type":15,"tag":113,"props":3602,"children":3603},{"style":172},[3604],{"type":21,"value":867},{"type":15,"tag":113,"props":3606,"children":3607},{"style":136},[3608],{"type":21,"value":652},{"type":15,"tag":113,"props":3610,"children":3611},{"style":187},[3612],{"type":21,"value":1153},{"type":15,"tag":113,"props":3614,"children":3615},{"style":136},[3616],{"type":21,"value":662},{"type":15,"tag":113,"props":3618,"children":3619},{"style":130},[3620],{"type":21,"value":447},{"type":15,"tag":113,"props":3622,"children":3623},{"style":136},[3624],{"type":21,"value":180},{"type":15,"tag":113,"props":3626,"children":3627},{"class":115,"line":221},[3628],{"type":15,"tag":113,"props":3629,"children":3630},{"style":120},[3631],{"type":21,"value":1173},{"type":15,"tag":113,"props":3633,"children":3634},{"class":115,"line":239},[3635,3639],{"type":15,"tag":113,"props":3636,"children":3637},{"style":130},[3638],{"type":21,"value":1181},{"type":15,"tag":113,"props":3640,"children":3641},{"style":136},[3642],{"type":21,"value":1186},{"type":15,"tag":113,"props":3644,"children":3645},{"class":115,"line":248},[3646,3650,3654],{"type":15,"tag":113,"props":3647,"children":3648},{"style":136},[3649],{"type":21,"value":1194},{"type":15,"tag":113,"props":3651,"children":3652},{"style":130},[3653],{"type":21,"value":628},{"type":15,"tag":113,"props":3655,"children":3656},{"style":136},[3657],{"type":21,"value":1203},{"type":15,"tag":113,"props":3659,"children":3660},{"class":115,"line":256},[3661],{"type":15,"tag":113,"props":3662,"children":3663},{"style":136},[3664],{"type":21,"value":1211},{"type":15,"tag":113,"props":3666,"children":3667},{"class":115,"line":300},[3668],{"type":15,"tag":113,"props":3669,"children":3670},{"style":136},[3671],{"type":21,"value":1219},{"type":15,"tag":113,"props":3673,"children":3674},{"class":115,"line":338},[3675],{"type":15,"tag":113,"props":3676,"children":3677},{"style":136},[3678],{"type":21,"value":1227},{"type":15,"tag":113,"props":3680,"children":3681},{"class":115,"line":373},[3682],{"type":15,"tag":113,"props":3683,"children":3684},{"style":136},[3685],{"type":21,"value":1235},{"type":15,"tag":113,"props":3687,"children":3688},{"class":115,"line":415},[3689],{"type":15,"tag":113,"props":3690,"children":3691},{"style":120},[3692],{"type":21,"value":1243},{"type":15,"tag":113,"props":3694,"children":3695},{"class":115,"line":423},[3696,3700,3704],{"type":15,"tag":113,"props":3697,"children":3698},{"style":136},[3699],{"type":21,"value":1251},{"type":15,"tag":113,"props":3701,"children":3702},{"style":147},[3703],{"type":21,"value":1256},{"type":15,"tag":113,"props":3705,"children":3706},{"style":136},[3707],{"type":21,"value":1261},{"type":15,"tag":113,"props":3709,"children":3710},{"class":115,"line":454},[3711,3715,3719],{"type":15,"tag":113,"props":3712,"children":3713},{"style":136},[3714],{"type":21,"value":1269},{"type":15,"tag":113,"props":3716,"children":3717},{"style":198},[3718],{"type":21,"value":1274},{"type":15,"tag":113,"props":3720,"children":3721},{"style":136},[3722],{"type":21,"value":767},{"type":15,"tag":113,"props":3724,"children":3725},{"class":115,"line":463},[3726],{"type":15,"tag":113,"props":3727,"children":3728},{"style":136},[3729],{"type":21,"value":1286},{"type":15,"tag":113,"props":3731,"children":3732},{"class":115,"line":501},[3733],{"type":15,"tag":113,"props":3734,"children":3735},{"style":136},[3736],{"type":21,"value":1294},{"type":15,"tag":113,"props":3738,"children":3739},{"class":115,"line":510},[3740],{"type":15,"tag":113,"props":3741,"children":3742},{"emptyLinePlaceholder":157},[3743],{"type":21,"value":160},{"type":15,"tag":113,"props":3745,"children":3746},{"class":115,"line":543},[3747,3751,3755,3759,3763,3767,3771],{"type":15,"tag":113,"props":3748,"children":3749},{"style":136},[3750],{"type":21,"value":1309},{"type":15,"tag":113,"props":3752,"children":3753},{"style":172},[3754],{"type":21,"value":867},{"type":15,"tag":113,"props":3756,"children":3757},{"style":136},[3758],{"type":21,"value":652},{"type":15,"tag":113,"props":3760,"children":3761},{"style":187},[3762],{"type":21,"value":1322},{"type":15,"tag":113,"props":3764,"children":3765},{"style":136},[3766],{"type":21,"value":662},{"type":15,"tag":113,"props":3768,"children":3769},{"style":130},[3770],{"type":21,"value":447},{"type":15,"tag":113,"props":3772,"children":3773},{"style":136},[3774],{"type":21,"value":180},{"type":15,"tag":113,"props":3776,"children":3777},{"class":115,"line":569},[3778,3782,3786,3790,3794,3798],{"type":15,"tag":113,"props":3779,"children":3780},{"style":130},[3781],{"type":21,"value":1342},{"type":15,"tag":113,"props":3783,"children":3784},{"style":198},[3785],{"type":21,"value":1347},{"type":15,"tag":113,"props":3787,"children":3788},{"style":130},[3789],{"type":21,"value":287},{"type":15,"tag":113,"props":3791,"children":3792},{"style":136},[3793],{"type":21,"value":530},{"type":15,"tag":113,"props":3795,"children":3796},{"style":172},[3797],{"type":21,"value":1360},{"type":15,"tag":113,"props":3799,"children":3800},{"style":136},[3801],{"type":21,"value":1365},{"type":15,"tag":113,"props":3803,"children":3804},{"class":115,"line":577},[3805,3809,3813,3817],{"type":15,"tag":113,"props":3806,"children":3807},{"style":130},[3808],{"type":21,"value":905},{"type":15,"tag":113,"props":3810,"children":3811},{"style":136},[3812],{"type":21,"value":1377},{"type":15,"tag":113,"props":3814,"children":3815},{"style":172},[3816],{"type":21,"value":1382},{"type":15,"tag":113,"props":3818,"children":3819},{"style":136},[3820],{"type":21,"value":1387},{"type":15,"tag":113,"props":3822,"children":3823},{"class":115,"line":617},[3824],{"type":15,"tag":113,"props":3825,"children":3826},{"style":136},[3827],{"type":21,"value":936},{"type":15,"tag":113,"props":3829,"children":3830},{"class":115,"line":674},[3831],{"type":15,"tag":113,"props":3832,"children":3833},{"style":136},[3834],{"type":21,"value":967},{"type":15,"tag":113,"props":3836,"children":3837},{"class":115,"line":770},[3838],{"type":15,"tag":113,"props":3839,"children":3840},{"emptyLinePlaceholder":157},[3841],{"type":21,"value":160},{"type":15,"tag":113,"props":3843,"children":3844},{"class":115,"line":792},[3845,3849,3853,3857],{"type":15,"tag":113,"props":3846,"children":3847},{"style":172},[3848],{"type":21,"value":1416},{"type":15,"tag":113,"props":3850,"children":3851},{"style":136},[3852],{"type":21,"value":1421},{"type":15,"tag":113,"props":3854,"children":3855},{"style":130},[3856],{"type":21,"value":447},{"type":15,"tag":113,"props":3858,"children":3859},{"style":136},[3860],{"type":21,"value":180},{"type":15,"tag":113,"props":3862,"children":3863},{"class":115,"line":830},[3864,3868],{"type":15,"tag":113,"props":3865,"children":3866},{"style":172},[3867],{"type":21,"value":1437},{"type":15,"tag":113,"props":3869,"children":3870},{"style":136},[3871],{"type":21,"value":958},{"type":15,"tag":113,"props":3873,"children":3874},{"class":115,"line":839},[3875],{"type":15,"tag":113,"props":3876,"children":3877},{"style":136},[3878],{"type":21,"value":1449},{"type":15,"tag":113,"props":3880,"children":3881},{"class":115,"line":847},[3882],{"type":15,"tag":113,"props":3883,"children":3884},{"emptyLinePlaceholder":157},[3885],{"type":21,"value":160},{"type":15,"tag":113,"props":3887,"children":3888},{"class":115,"line":856},[3889,3893,3897,3901],{"type":15,"tag":113,"props":3890,"children":3891},{"style":172},[3892],{"type":21,"value":1464},{"type":15,"tag":113,"props":3894,"children":3895},{"style":136},[3896],{"type":21,"value":1421},{"type":15,"tag":113,"props":3898,"children":3899},{"style":130},[3900],{"type":21,"value":447},{"type":15,"tag":113,"props":3902,"children":3903},{"style":136},[3904],{"type":21,"value":180},{"type":15,"tag":113,"props":3906,"children":3907},{"class":115,"line":899},[3908,3912,3916],{"type":15,"tag":113,"props":3909,"children":3910},{"style":136},[3911],{"type":21,"value":1484},{"type":15,"tag":113,"props":3913,"children":3914},{"style":172},[3915],{"type":21,"value":1070},{"type":15,"tag":113,"props":3917,"children":3918},{"style":136},[3919],{"type":21,"value":958},{"type":15,"tag":113,"props":3921,"children":3922},{"class":115,"line":930},[3923],{"type":15,"tag":113,"props":3924,"children":3925},{"style":136},[3926],{"type":21,"value":1449},{"type":15,"tag":113,"props":3928,"children":3929},{"class":115,"line":939},[3930],{"type":15,"tag":113,"props":3931,"children":3932},{"emptyLinePlaceholder":157},[3933],{"type":21,"value":160},{"type":15,"tag":113,"props":3935,"children":3936},{"class":115,"line":947},[3937,3941],{"type":15,"tag":113,"props":3938,"children":3939},{"style":130},[3940],{"type":21,"value":1514},{"type":15,"tag":113,"props":3942,"children":3943},{"style":136},[3944],{"type":21,"value":1519},{"type":15,"tag":113,"props":3946,"children":3947},{"class":115,"line":961},[3948],{"type":15,"tag":113,"props":3949,"children":3950},{"style":136},[3951],{"type":21,"value":245},{"type":15,"tag":23,"props":3953,"children":3954},{},[3955,3959,3960,3965,3966,3971,3972,3977,3978,3983],{"type":15,"tag":29,"props":3956,"children":3957},{},[3958],{"type":21,"value":1534},{"type":21,"value":1536},{"type":15,"tag":80,"props":3961,"children":3963},{"className":3962},[],[3964],{"type":21,"value":1542},{"type":21,"value":1544},{"type":15,"tag":80,"props":3967,"children":3969},{"className":3968},[],[3970],{"type":21,"value":1550},{"type":21,"value":1552},{"type":15,"tag":80,"props":3973,"children":3975},{"className":3974},[],[3976],{"type":21,"value":1558},{"type":21,"value":1560},{"type":15,"tag":80,"props":3979,"children":3981},{"className":3980},[],[3982],{"type":21,"value":1566},{"type":21,"value":1568},{"type":15,"tag":56,"props":3985,"children":3986},{"id":1571},[3987],{"type":21,"value":1574},{"type":15,"tag":23,"props":3989,"children":3990},{},[3991],{"type":21,"value":1579},{"type":15,"tag":68,"props":3993,"children":3994},{"id":1582},[3995],{"type":21,"value":1585},{"type":15,"tag":23,"props":3997,"children":3998},{},[3999,4000,4005,4006,4011],{"type":21,"value":1590},{"type":15,"tag":80,"props":4001,"children":4003},{"className":4002},[],[4004],{"type":21,"value":1009},{"type":21,"value":1597},{"type":15,"tag":80,"props":4007,"children":4009},{"className":4008},[],[4010],{"type":21,"value":1603},{"type":21,"value":1605},{"type":15,"tag":103,"props":4013,"children":4014},{"className":105,"code":1608,"language":107,"meta":7,"style":7},[4015],{"type":15,"tag":80,"props":4016,"children":4017},{"__ignoreMap":7},[4018,4025,4044,4051,4070,4101,4120,4127,4154,4181,4208,4215,4222,4297,4312,4319,4326,4353,4372,4387,4402,4409,4416,4423,4442,4473,4488,4495,4502,4521,4544,4551,4558,4569],{"type":15,"tag":113,"props":4019,"children":4020},{"class":115,"line":116},[4021],{"type":15,"tag":113,"props":4022,"children":4023},{"style":120},[4024],{"type":21,"value":1620},{"type":15,"tag":113,"props":4026,"children":4027},{"class":115,"line":126},[4028,4032,4036,4040],{"type":15,"tag":113,"props":4029,"children":4030},{"style":130},[4031],{"type":21,"value":133},{"type":15,"tag":113,"props":4033,"children":4034},{"style":136},[4035],{"type":21,"value":139},{"type":15,"tag":113,"props":4037,"children":4038},{"style":130},[4039],{"type":21,"value":144},{"type":15,"tag":113,"props":4041,"children":4042},{"style":147},[4043],{"type":21,"value":150},{"type":15,"tag":113,"props":4045,"children":4046},{"class":115,"line":153},[4047],{"type":15,"tag":113,"props":4048,"children":4049},{"emptyLinePlaceholder":157},[4050],{"type":21,"value":160},{"type":15,"tag":113,"props":4052,"children":4053},{"class":115,"line":163},[4054,4058,4062,4066],{"type":15,"tag":113,"props":4055,"children":4056},{"style":130},[4057],{"type":21,"value":262},{"type":15,"tag":113,"props":4059,"children":4060},{"style":130},[4061],{"type":21,"value":267},{"type":15,"tag":113,"props":4063,"children":4064},{"style":172},[4065],{"type":21,"value":1662},{"type":15,"tag":113,"props":4067,"children":4068},{"style":136},[4069],{"type":21,"value":1667},{"type":15,"tag":113,"props":4071,"children":4072},{"class":115,"line":183},[4073,4077,4081,4085,4089,4093,4097],{"type":15,"tag":113,"props":4074,"children":4075},{"style":130},[4076],{"type":21,"value":306},{"type":15,"tag":113,"props":4078,"children":4079},{"style":198},[4080],{"type":21,"value":1679},{"type":15,"tag":113,"props":4082,"children":4083},{"style":130},[4084],{"type":21,"value":287},{"type":15,"tag":113,"props":4086,"children":4087},{"style":172},[4088],{"type":21,"value":320},{"type":15,"tag":113,"props":4090,"children":4091},{"style":136},[4092],{"type":21,"value":277},{"type":15,"tag":113,"props":4094,"children":4095},{"style":198},[4096],{"type":21,"value":1274},{"type":15,"tag":113,"props":4098,"children":4099},{"style":136},[4100],{"type":21,"value":370},{"type":15,"tag":113,"props":4102,"children":4103},{"class":115,"line":204},[4104,4108,4112,4116],{"type":15,"tag":113,"props":4105,"children":4106},{"style":130},[4107],{"type":21,"value":379},{"type":15,"tag":113,"props":4109,"children":4110},{"style":136},[4111],{"type":21,"value":1711},{"type":15,"tag":113,"props":4113,"children":4114},{"style":130},[4115],{"type":21,"value":628},{"type":15,"tag":113,"props":4117,"children":4118},{"style":198},[4119],{"type":21,"value":1720},{"type":15,"tag":113,"props":4121,"children":4122},{"class":115,"line":221},[4123],{"type":15,"tag":113,"props":4124,"children":4125},{"emptyLinePlaceholder":157},[4126],{"type":21,"value":160},{"type":15,"tag":113,"props":4128,"children":4129},{"class":115,"line":239},[4130,4134,4138,4142,4146,4150],{"type":15,"tag":113,"props":4131,"children":4132},{"style":130},[4133],{"type":21,"value":306},{"type":15,"tag":113,"props":4135,"children":4136},{"style":172},[4137],{"type":21,"value":1739},{"type":15,"tag":113,"props":4139,"children":4140},{"style":130},[4141],{"type":21,"value":287},{"type":15,"tag":113,"props":4143,"children":4144},{"style":136},[4145],{"type":21,"value":442},{"type":15,"tag":113,"props":4147,"children":4148},{"style":130},[4149],{"type":21,"value":447},{"type":15,"tag":113,"props":4151,"children":4152},{"style":136},[4153],{"type":21,"value":180},{"type":15,"tag":113,"props":4155,"children":4156},{"class":115,"line":248},[4157,4161,4165,4169,4173,4177],{"type":15,"tag":113,"props":4158,"children":4159},{"style":130},[4160],{"type":21,"value":516},{"type":15,"tag":113,"props":4162,"children":4163},{"style":198},[4164],{"type":21,"value":1767},{"type":15,"tag":113,"props":4166,"children":4167},{"style":130},[4168],{"type":21,"value":287},{"type":15,"tag":113,"props":4170,"children":4171},{"style":136},[4172],{"type":21,"value":1776},{"type":15,"tag":113,"props":4174,"children":4175},{"style":130},[4176],{"type":21,"value":685},{"type":15,"tag":113,"props":4178,"children":4179},{"style":136},[4180],{"type":21,"value":1785},{"type":15,"tag":113,"props":4182,"children":4183},{"class":115,"line":256},[4184,4188,4192,4196,4200,4204],{"type":15,"tag":113,"props":4185,"children":4186},{"style":130},[4187],{"type":21,"value":516},{"type":15,"tag":113,"props":4189,"children":4190},{"style":198},[4191],{"type":21,"value":1797},{"type":15,"tag":113,"props":4193,"children":4194},{"style":130},[4195],{"type":21,"value":287},{"type":15,"tag":113,"props":4197,"children":4198},{"style":136},[4199],{"type":21,"value":1806},{"type":15,"tag":113,"props":4201,"children":4202},{"style":130},[4203],{"type":21,"value":1811},{"type":15,"tag":113,"props":4205,"children":4206},{"style":136},[4207],{"type":21,"value":1816},{"type":15,"tag":113,"props":4209,"children":4210},{"class":115,"line":300},[4211],{"type":15,"tag":113,"props":4212,"children":4213},{"style":136},[4214],{"type":21,"value":507},{"type":15,"tag":113,"props":4216,"children":4217},{"class":115,"line":338},[4218],{"type":15,"tag":113,"props":4219,"children":4220},{"style":120},[4221],{"type":21,"value":1831},{"type":15,"tag":113,"props":4223,"children":4224},{"class":115,"line":373},[4225,4229,4233,4237,4241,4245,4249,4253,4257,4261,4265,4269,4273,4277,4281,4285,4289,4293],{"type":15,"tag":113,"props":4226,"children":4227},{"style":136},[4228],{"type":21,"value":1839},{"type":15,"tag":113,"props":4230,"children":4231},{"style":130},[4232],{"type":21,"value":628},{"type":15,"tag":113,"props":4234,"children":4235},{"style":136},[4236],{"type":21,"value":1848},{"type":15,"tag":113,"props":4238,"children":4239},{"style":130},[4240],{"type":21,"value":1853},{"type":15,"tag":113,"props":4242,"children":4243},{"style":198},[4244],{"type":21,"value":1858},{"type":15,"tag":113,"props":4246,"children":4247},{"style":130},[4248],{"type":21,"value":1863},{"type":15,"tag":113,"props":4250,"children":4251},{"style":136},[4252],{"type":21,"value":1868},{"type":15,"tag":113,"props":4254,"children":4255},{"style":172},[4256],{"type":21,"value":1873},{"type":15,"tag":113,"props":4258,"children":4259},{"style":136},[4260],{"type":21,"value":277},{"type":15,"tag":113,"props":4262,"children":4263},{"style":198},[4264],{"type":21,"value":1882},{"type":15,"tag":113,"props":4266,"children":4267},{"style":136},[4268],{"type":21,"value":1887},{"type":15,"tag":113,"props":4270,"children":4271},{"style":130},[4272],{"type":21,"value":1892},{"type":15,"tag":113,"props":4274,"children":4275},{"style":136},[4276],{"type":21,"value":1897},{"type":15,"tag":113,"props":4278,"children":4279},{"style":130},[4280],{"type":21,"value":1902},{"type":15,"tag":113,"props":4282,"children":4283},{"style":198},[4284],{"type":21,"value":1907},{"type":15,"tag":113,"props":4286,"children":4287},{"style":136},[4288],{"type":21,"value":662},{"type":15,"tag":113,"props":4290,"children":4291},{"style":130},[4292],{"type":21,"value":195},{"type":15,"tag":113,"props":4294,"children":4295},{"style":198},[4296],{"type":21,"value":1920},{"type":15,"tag":113,"props":4298,"children":4299},{"class":115,"line":415},[4300,4304,4308],{"type":15,"tag":113,"props":4301,"children":4302},{"style":136},[4303],{"type":21,"value":1928},{"type":15,"tag":113,"props":4305,"children":4306},{"style":130},[4307],{"type":21,"value":628},{"type":15,"tag":113,"props":4309,"children":4310},{"style":198},[4311],{"type":21,"value":1720},{"type":15,"tag":113,"props":4313,"children":4314},{"class":115,"line":423},[4315],{"type":15,"tag":113,"props":4316,"children":4317},{"style":136},[4318],{"type":21,"value":967},{"type":15,"tag":113,"props":4320,"children":4321},{"class":115,"line":454},[4322],{"type":15,"tag":113,"props":4323,"children":4324},{"emptyLinePlaceholder":157},[4325],{"type":21,"value":160},{"type":15,"tag":113,"props":4327,"children":4328},{"class":115,"line":463},[4329,4333,4337,4341,4345,4349],{"type":15,"tag":113,"props":4330,"children":4331},{"style":130},[4332],{"type":21,"value":306},{"type":15,"tag":113,"props":4334,"children":4335},{"style":172},[4336],{"type":21,"value":1962},{"type":15,"tag":113,"props":4338,"children":4339},{"style":130},[4340],{"type":21,"value":287},{"type":15,"tag":113,"props":4342,"children":4343},{"style":136},[4344],{"type":21,"value":442},{"type":15,"tag":113,"props":4346,"children":4347},{"style":130},[4348],{"type":21,"value":447},{"type":15,"tag":113,"props":4350,"children":4351},{"style":136},[4352],{"type":21,"value":180},{"type":15,"tag":113,"props":4354,"children":4355},{"class":115,"line":501},[4356,4360,4364,4368],{"type":15,"tag":113,"props":4357,"children":4358},{"style":130},[4359],{"type":21,"value":469},{"type":15,"tag":113,"props":4361,"children":4362},{"style":136},[4363],{"type":21,"value":474},{"type":15,"tag":113,"props":4365,"children":4366},{"style":130},[4367],{"type":21,"value":557},{"type":15,"tag":113,"props":4369,"children":4370},{"style":136},[4371],{"type":21,"value":1998},{"type":15,"tag":113,"props":4373,"children":4374},{"class":115,"line":510},[4375,4379,4383],{"type":15,"tag":113,"props":4376,"children":4377},{"style":136},[4378],{"type":21,"value":2006},{"type":15,"tag":113,"props":4380,"children":4381},{"style":172},[4382],{"type":21,"value":1603},{"type":15,"tag":113,"props":4384,"children":4385},{"style":136},[4386],{"type":21,"value":2015},{"type":15,"tag":113,"props":4388,"children":4389},{"class":115,"line":543},[4390,4394,4398],{"type":15,"tag":113,"props":4391,"children":4392},{"style":136},[4393],{"type":21,"value":2023},{"type":15,"tag":113,"props":4395,"children":4396},{"style":130},[4397],{"type":21,"value":628},{"type":15,"tag":113,"props":4399,"children":4400},{"style":198},[4401],{"type":21,"value":2032},{"type":15,"tag":113,"props":4403,"children":4404},{"class":115,"line":569},[4405],{"type":15,"tag":113,"props":4406,"children":4407},{"style":136},[4408],{"type":21,"value":2040},{"type":15,"tag":113,"props":4410,"children":4411},{"class":115,"line":577},[4412],{"type":15,"tag":113,"props":4413,"children":4414},{"style":136},[4415],{"type":21,"value":967},{"type":15,"tag":113,"props":4417,"children":4418},{"class":115,"line":617},[4419],{"type":15,"tag":113,"props":4420,"children":4421},{"emptyLinePlaceholder":157},[4422],{"type":21,"value":160},{"type":15,"tag":113,"props":4424,"children":4425},{"class":115,"line":674},[4426,4430,4434,4438],{"type":15,"tag":113,"props":4427,"children":4428},{"style":172},[4429],{"type":21,"value":1416},{"type":15,"tag":113,"props":4431,"children":4432},{"style":136},[4433],{"type":21,"value":1421},{"type":15,"tag":113,"props":4435,"children":4436},{"style":130},[4437],{"type":21,"value":447},{"type":15,"tag":113,"props":4439,"children":4440},{"style":136},[4441],{"type":21,"value":180},{"type":15,"tag":113,"props":4443,"children":4444},{"class":115,"line":770},[4445,4449,4453,4457,4461,4465,4469],{"type":15,"tag":113,"props":4446,"children":4447},{"style":136},[4448],{"type":21,"value":2081},{"type":15,"tag":113,"props":4450,"children":4451},{"style":172},[4452],{"type":21,"value":2086},{"type":15,"tag":113,"props":4454,"children":4455},{"style":136},[4456],{"type":21,"value":277},{"type":15,"tag":113,"props":4458,"children":4459},{"style":147},[4460],{"type":21,"value":2095},{"type":15,"tag":113,"props":4462,"children":4463},{"style":136},[4464],{"type":21,"value":2100},{"type":15,"tag":113,"props":4466,"children":4467},{"style":198},[4468],{"type":21,"value":2105},{"type":15,"tag":113,"props":4470,"children":4471},{"style":136},[4472],{"type":21,"value":2110},{"type":15,"tag":113,"props":4474,"children":4475},{"class":115,"line":792},[4476,4480,4484],{"type":15,"tag":113,"props":4477,"children":4478},{"style":172},[4479],{"type":21,"value":2118},{"type":15,"tag":113,"props":4481,"children":4482},{"style":136},[4483],{"type":21,"value":2123},{"type":15,"tag":113,"props":4485,"children":4486},{"style":120},[4487],{"type":21,"value":2128},{"type":15,"tag":113,"props":4489,"children":4490},{"class":115,"line":830},[4491],{"type":15,"tag":113,"props":4492,"children":4493},{"style":136},[4494],{"type":21,"value":1449},{"type":15,"tag":113,"props":4496,"children":4497},{"class":115,"line":839},[4498],{"type":15,"tag":113,"props":4499,"children":4500},{"emptyLinePlaceholder":157},[4501],{"type":21,"value":160},{"type":15,"tag":113,"props":4503,"children":4504},{"class":115,"line":847},[4505,4509,4513,4517],{"type":15,"tag":113,"props":4506,"children":4507},{"style":172},[4508],{"type":21,"value":1464},{"type":15,"tag":113,"props":4510,"children":4511},{"style":136},[4512],{"type":21,"value":1421},{"type":15,"tag":113,"props":4514,"children":4515},{"style":130},[4516],{"type":21,"value":447},{"type":15,"tag":113,"props":4518,"children":4519},{"style":136},[4520],{"type":21,"value":180},{"type":15,"tag":113,"props":4522,"children":4523},{"class":115,"line":856},[4524,4528,4532,4536,4540],{"type":15,"tag":113,"props":4525,"children":4526},{"style":136},[4527],{"type":21,"value":2081},{"type":15,"tag":113,"props":4529,"children":4530},{"style":172},[4531],{"type":21,"value":2173},{"type":15,"tag":113,"props":4533,"children":4534},{"style":136},[4535],{"type":21,"value":277},{"type":15,"tag":113,"props":4537,"children":4538},{"style":147},[4539],{"type":21,"value":2095},{"type":15,"tag":113,"props":4541,"children":4542},{"style":136},[4543],{"type":21,"value":2186},{"type":15,"tag":113,"props":4545,"children":4546},{"class":115,"line":899},[4547],{"type":15,"tag":113,"props":4548,"children":4549},{"style":136},[4550],{"type":21,"value":1449},{"type":15,"tag":113,"props":4552,"children":4553},{"class":115,"line":930},[4554],{"type":15,"tag":113,"props":4555,"children":4556},{"emptyLinePlaceholder":157},[4557],{"type":21,"value":160},{"type":15,"tag":113,"props":4559,"children":4560},{"class":115,"line":939},[4561,4565],{"type":15,"tag":113,"props":4562,"children":4563},{"style":130},[4564],{"type":21,"value":1514},{"type":15,"tag":113,"props":4566,"children":4567},{"style":136},[4568],{"type":21,"value":2212},{"type":15,"tag":113,"props":4570,"children":4571},{"class":115,"line":947},[4572],{"type":15,"tag":113,"props":4573,"children":4574},{"style":136},[4575],{"type":21,"value":245},{"type":15,"tag":68,"props":4577,"children":4578},{"id":2222},[4579],{"type":21,"value":2225},{"type":15,"tag":23,"props":4581,"children":4582},{},[4583,4584,4589],{"type":21,"value":2230},{"type":15,"tag":80,"props":4585,"children":4587},{"className":4586},[],[4588],{"type":21,"value":2236},{"type":21,"value":2238},{"type":15,"tag":103,"props":4591,"children":4592},{"className":2241,"code":2242,"language":2243,"meta":7,"style":7},[4593],{"type":15,"tag":80,"props":4594,"children":4595},{"__ignoreMap":7},[4596,4611,4638,4653,4668,4711,4722,4737,4752,4759,4790,4821],{"type":15,"tag":113,"props":4597,"children":4598},{"class":115,"line":116},[4599,4603,4607],{"type":15,"tag":113,"props":4600,"children":4601},{"style":136},[4602],{"type":21,"value":325},{"type":15,"tag":113,"props":4604,"children":4605},{"style":2257},[4606],{"type":21,"value":2260},{"type":15,"tag":113,"props":4608,"children":4609},{"style":136},[4610],{"type":21,"value":2265},{"type":15,"tag":113,"props":4612,"children":4613},{"class":115,"line":126},[4614,4618,4622,4626,4630,4634],{"type":15,"tag":113,"props":4615,"children":4616},{"style":136},[4617],{"type":21,"value":2273},{"type":15,"tag":113,"props":4619,"children":4620},{"style":2257},[4621],{"type":21,"value":2278},{"type":15,"tag":113,"props":4623,"children":4624},{"style":172},[4625],{"type":21,"value":2283},{"type":15,"tag":113,"props":4627,"children":4628},{"style":136},[4629],{"type":21,"value":628},{"type":15,"tag":113,"props":4631,"children":4632},{"style":147},[4633],{"type":21,"value":2292},{"type":15,"tag":113,"props":4635,"children":4636},{"style":136},[4637],{"type":21,"value":2265},{"type":15,"tag":113,"props":4639,"children":4640},{"class":115,"line":153},[4641,4645,4649],{"type":15,"tag":113,"props":4642,"children":4643},{"style":136},[4644],{"type":21,"value":2304},{"type":15,"tag":113,"props":4646,"children":4647},{"style":2257},[4648],{"type":21,"value":2278},{"type":15,"tag":113,"props":4650,"children":4651},{"style":136},[4652],{"type":21,"value":2313},{"type":15,"tag":113,"props":4654,"children":4655},{"class":115,"line":163},[4656,4660,4664],{"type":15,"tag":113,"props":4657,"children":4658},{"style":172},[4659],{"type":21,"value":2321},{"type":15,"tag":113,"props":4661,"children":4662},{"style":136},[4663],{"type":21,"value":628},{"type":15,"tag":113,"props":4665,"children":4666},{"style":147},[4667],{"type":21,"value":2330},{"type":15,"tag":113,"props":4669,"children":4670},{"class":115,"line":183},[4671,4675,4679,4683,4687,4691,4695,4699,4703,4707],{"type":15,"tag":113,"props":4672,"children":4673},{"style":136},[4674],{"type":21,"value":2338},{"type":15,"tag":113,"props":4676,"children":4677},{"style":172},[4678],{"type":21,"value":2343},{"type":15,"tag":113,"props":4680,"children":4681},{"style":136},[4682],{"type":21,"value":628},{"type":15,"tag":113,"props":4684,"children":4685},{"style":147},[4686],{"type":21,"value":2352},{"type":15,"tag":113,"props":4688,"children":4689},{"style":136},[4690],{"type":21,"value":2357},{"type":15,"tag":113,"props":4692,"children":4693},{"style":147},[4694],{"type":21,"value":2362},{"type":15,"tag":113,"props":4696,"children":4697},{"style":136},[4698],{"type":21,"value":2367},{"type":15,"tag":113,"props":4700,"children":4701},{"style":147},[4702],{"type":21,"value":2372},{"type":15,"tag":113,"props":4704,"children":4705},{"style":136},[4706],{"type":21,"value":2377},{"type":15,"tag":113,"props":4708,"children":4709},{"style":147},[4710],{"type":21,"value":2382},{"type":15,"tag":113,"props":4712,"children":4713},{"class":115,"line":204},[4714,4718],{"type":15,"tag":113,"props":4715,"children":4716},{"style":2388},[4717],{"type":21,"value":2391},{"type":15,"tag":113,"props":4719,"children":4720},{"style":136},[4721],{"type":21,"value":2265},{"type":15,"tag":113,"props":4723,"children":4724},{"class":115,"line":221},[4725,4729,4733],{"type":15,"tag":113,"props":4726,"children":4727},{"style":136},[4728],{"type":21,"value":2403},{"type":15,"tag":113,"props":4730,"children":4731},{"style":2257},[4732],{"type":21,"value":2278},{"type":15,"tag":113,"props":4734,"children":4735},{"style":136},[4736],{"type":21,"value":2265},{"type":15,"tag":113,"props":4738,"children":4739},{"class":115,"line":239},[4740,4744,4748],{"type":15,"tag":113,"props":4741,"children":4742},{"style":136},[4743],{"type":21,"value":2419},{"type":15,"tag":113,"props":4745,"children":4746},{"style":2257},[4747],{"type":21,"value":2260},{"type":15,"tag":113,"props":4749,"children":4750},{"style":136},[4751],{"type":21,"value":2265},{"type":15,"tag":113,"props":4753,"children":4754},{"class":115,"line":248},[4755],{"type":15,"tag":113,"props":4756,"children":4757},{"emptyLinePlaceholder":157},[4758],{"type":21,"value":160},{"type":15,"tag":113,"props":4760,"children":4761},{"class":115,"line":256},[4762,4766,4770,4774,4778,4782,4786],{"type":15,"tag":113,"props":4763,"children":4764},{"style":136},[4765],{"type":21,"value":325},{"type":15,"tag":113,"props":4767,"children":4768},{"style":2257},[4769],{"type":21,"value":2446},{"type":15,"tag":113,"props":4771,"children":4772},{"style":172},[4773],{"type":21,"value":2451},{"type":15,"tag":113,"props":4775,"children":4776},{"style":172},[4777],{"type":21,"value":2456},{"type":15,"tag":113,"props":4779,"children":4780},{"style":136},[4781],{"type":21,"value":628},{"type":15,"tag":113,"props":4783,"children":4784},{"style":147},[4785],{"type":21,"value":2465},{"type":15,"tag":113,"props":4787,"children":4788},{"style":136},[4789],{"type":21,"value":2265},{"type":15,"tag":113,"props":4791,"children":4792},{"class":115,"line":300},[4793,4797,4801,4805,4809,4813,4817],{"type":15,"tag":113,"props":4794,"children":4795},{"style":130},[4796],{"type":21,"value":2477},{"type":15,"tag":113,"props":4798,"children":4799},{"style":136},[4800],{"type":21,"value":2482},{"type":15,"tag":113,"props":4802,"children":4803},{"style":198},[4804],{"type":21,"value":2367},{"type":15,"tag":113,"props":4806,"children":4807},{"style":136},[4808],{"type":21,"value":2491},{"type":15,"tag":113,"props":4810,"children":4811},{"style":130},[4812],{"type":21,"value":628},{"type":15,"tag":113,"props":4814,"children":4815},{"style":172},[4816],{"type":21,"value":1662},{"type":15,"tag":113,"props":4818,"children":4819},{"style":136},[4820],{"type":21,"value":958},{"type":15,"tag":113,"props":4822,"children":4823},{"class":115,"line":338},[4824,4828,4832],{"type":15,"tag":113,"props":4825,"children":4826},{"style":136},[4827],{"type":21,"value":2419},{"type":15,"tag":113,"props":4829,"children":4830},{"style":2257},[4831],{"type":21,"value":2446},{"type":15,"tag":113,"props":4833,"children":4834},{"style":136},[4835],{"type":21,"value":2265},{"type":15,"tag":23,"props":4837,"children":4838},{},[4839],{"type":15,"tag":29,"props":4840,"children":4841},{},[4842],{"type":21,"value":2526},{"type":15,"tag":2528,"props":4844,"children":4845},{},[4846,4862],{"type":15,"tag":2532,"props":4847,"children":4848},{},[4849,4850,4855,4856,4861],{"type":21,"value":2536},{"type":15,"tag":80,"props":4851,"children":4853},{"className":4852},[],[4854],{"type":21,"value":2542},{"type":21,"value":2544},{"type":15,"tag":80,"props":4857,"children":4859},{"className":4858},[],[4860],{"type":21,"value":2550},{"type":21,"value":2552},{"type":15,"tag":2532,"props":4863,"children":4864},{},[4865,4866,4871],{"type":21,"value":2557},{"type":15,"tag":80,"props":4867,"children":4869},{"className":4868},[],[4870],{"type":21,"value":2563},{"type":21,"value":2565},{"type":15,"tag":56,"props":4873,"children":4874},{"id":2568},[4875],{"type":21,"value":2571},{"type":15,"tag":23,"props":4877,"children":4878},{},[4879,4880,4884],{"type":21,"value":2576},{"type":15,"tag":29,"props":4881,"children":4882},{},[4883],{"type":21,"value":2581},{"type":21,"value":2583},{"type":15,"tag":2585,"props":4886,"children":4887},{},[4888,4896,4905],{"type":15,"tag":2532,"props":4889,"children":4890},{},[4891,4895],{"type":15,"tag":29,"props":4892,"children":4893},{},[4894],{"type":21,"value":2595},{"type":21,"value":2597},{"type":15,"tag":2532,"props":4897,"children":4898},{},[4899,4900,4904],{"type":21,"value":2602},{"type":15,"tag":29,"props":4901,"children":4902},{},[4903],{"type":21,"value":2607},{"type":21,"value":2609},{"type":15,"tag":2532,"props":4906,"children":4907},{},[4908,4909,4914,4915,4920],{"type":21,"value":2614},{"type":15,"tag":80,"props":4910,"children":4912},{"className":4911},[],[4913],{"type":21,"value":1603},{"type":21,"value":2621},{"type":15,"tag":80,"props":4916,"children":4918},{"className":4917},[],[4919],{"type":21,"value":2236},{"type":21,"value":2628},{"type":15,"tag":23,"props":4922,"children":4923},{},[4924,4925,4930],{"type":21,"value":2633},{"type":15,"tag":2635,"props":4926,"children":4928},{"href":2637,"rel":4927},[2639],[4929],{"type":21,"value":2642},{"type":21,"value":2644},{"type":15,"tag":23,"props":4932,"children":4933},{},[4934],{"type":21,"value":2649},{"type":15,"tag":2343,"props":4936,"children":4937},{},[4938],{"type":21,"value":2654},{"title":7,"searchDepth":126,"depth":126,"links":4940},[4941,4945,4949],{"id":58,"depth":126,"text":61,"children":4942},[4943,4944],{"id":70,"depth":153,"text":73},{"id":995,"depth":153,"text":998},{"id":1571,"depth":126,"text":1574,"children":4946},[4947,4948],{"id":1582,"depth":153,"text":1585},{"id":2222,"depth":153,"text":2225},{"id":2568,"depth":126,"text":2571},{"_path":4951,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":4952,"description":4953,"date":4954,"code":4955,"body":4956,"_type":2666,"_id":7401,"_source":2668,"_file":7402,"_stem":7403,"_extension":2671},"\u002Fblog\u002F2-post","FastAPI + Vue3：轻量级全栈项目实战","前后端目录规范与依赖管理","2026-05-08","D4E5F6",{"type":12,"children":4957,"toc":7394},[4958,4963,4978,4984,4992,5000,5181,5187,5432,5789,5795,6191,6513,6519,6534,6726,6741,6907,6913,7204,7344,7352,7390],{"type":15,"tag":16,"props":4959,"children":4961},{"id":4960},"fastapi-vue3轻量级全栈项目实战",[4962],{"type":21,"value":4952},{"type":15,"tag":4964,"props":4965,"children":4966},"blockquote",{},[4967],{"type":15,"tag":23,"props":4968,"children":4969},{},[4970,4972,4976],{"type":21,"value":4971},"适用场景：快速原型 \u002F 内部工具 \u002F 个人项目",{"type":15,"tag":4973,"props":4974,"children":4975},"br",{},[],{"type":21,"value":4977},"\n技术栈：FastAPI + Vue3 + Pinia + Axios + Docker",{"type":15,"tag":56,"props":4979,"children":4981},{"id":4980},"_1-目录规范与依赖管理",[4982],{"type":21,"value":4983},"1. 目录规范与依赖管理",{"type":15,"tag":103,"props":4985,"children":4987},{"code":4986},"project\u002F\n├── backend\u002F          # Python 后端\n│   ├── app\u002F\n│   │   ├── main.py\n│   │   ├── routers\u002F\n│   │   ├── models\u002F   # SQLAlchemy \u002F Pydantic\n│   │   └── core\u002F     # Config, Security\n│   └── requirements.txt\n└── frontend\u002F         # Vue3 前端\n    ├── src\u002F\n    │   ├── api\u002F\n    │   ├── stores\u002F   # Pinia\n    │   └── composables\u002F\n    └── package.json\n",[4988],{"type":15,"tag":80,"props":4989,"children":4990},{"__ignoreMap":7},[4991],{"type":21,"value":4986},{"type":15,"tag":23,"props":4993,"children":4994},{},[4995],{"type":15,"tag":29,"props":4996,"children":4997},{},[4998],{"type":21,"value":4999},"初始化",{"type":15,"tag":103,"props":5001,"children":5005},{"code":5002,"language":5003,"meta":7,"className":5004,"style":7},"# Backend\npython -m venv .venv && source .venv\u002Fbin\u002Factivate\npip install \"fastapi[standard]\" pydantic passlib[bcrypt] python-jose[cryptography]\n\n# Frontend\nnpm create vite@latest frontend -- --template vue-ts\ncd frontend && npm i axios pinia vue-router\n","bash","language-bash shiki shiki-themes github-light github-dark",[5006],{"type":15,"tag":80,"props":5007,"children":5008},{"__ignoreMap":7},[5009,5017,5055,5088,5095,5103,5141],{"type":15,"tag":113,"props":5010,"children":5011},{"class":115,"line":116},[5012],{"type":15,"tag":113,"props":5013,"children":5014},{"style":120},[5015],{"type":21,"value":5016},"# Backend\n",{"type":15,"tag":113,"props":5018,"children":5019},{"class":115,"line":126},[5020,5025,5030,5035,5040,5045,5050],{"type":15,"tag":113,"props":5021,"children":5022},{"style":172},[5023],{"type":21,"value":5024},"python",{"type":15,"tag":113,"props":5026,"children":5027},{"style":198},[5028],{"type":21,"value":5029}," -m",{"type":15,"tag":113,"props":5031,"children":5032},{"style":147},[5033],{"type":21,"value":5034}," venv",{"type":15,"tag":113,"props":5036,"children":5037},{"style":147},[5038],{"type":21,"value":5039}," .venv",{"type":15,"tag":113,"props":5041,"children":5042},{"style":136},[5043],{"type":21,"value":5044}," && ",{"type":15,"tag":113,"props":5046,"children":5047},{"style":198},[5048],{"type":21,"value":5049},"source",{"type":15,"tag":113,"props":5051,"children":5052},{"style":147},[5053],{"type":21,"value":5054}," .venv\u002Fbin\u002Factivate\n",{"type":15,"tag":113,"props":5056,"children":5057},{"class":115,"line":153},[5058,5063,5068,5073,5078,5083],{"type":15,"tag":113,"props":5059,"children":5060},{"style":172},[5061],{"type":21,"value":5062},"pip",{"type":15,"tag":113,"props":5064,"children":5065},{"style":147},[5066],{"type":21,"value":5067}," install",{"type":15,"tag":113,"props":5069,"children":5070},{"style":147},[5071],{"type":21,"value":5072}," \"fastapi[standard]\"",{"type":15,"tag":113,"props":5074,"children":5075},{"style":147},[5076],{"type":21,"value":5077}," pydantic",{"type":15,"tag":113,"props":5079,"children":5080},{"style":147},[5081],{"type":21,"value":5082}," passlib[bcrypt]",{"type":15,"tag":113,"props":5084,"children":5085},{"style":147},[5086],{"type":21,"value":5087}," python-jose[cryptography]\n",{"type":15,"tag":113,"props":5089,"children":5090},{"class":115,"line":163},[5091],{"type":15,"tag":113,"props":5092,"children":5093},{"emptyLinePlaceholder":157},[5094],{"type":21,"value":160},{"type":15,"tag":113,"props":5096,"children":5097},{"class":115,"line":183},[5098],{"type":15,"tag":113,"props":5099,"children":5100},{"style":120},[5101],{"type":21,"value":5102},"# Frontend\n",{"type":15,"tag":113,"props":5104,"children":5105},{"class":115,"line":204},[5106,5111,5116,5121,5126,5131,5136],{"type":15,"tag":113,"props":5107,"children":5108},{"style":172},[5109],{"type":21,"value":5110},"npm",{"type":15,"tag":113,"props":5112,"children":5113},{"style":147},[5114],{"type":21,"value":5115}," create",{"type":15,"tag":113,"props":5117,"children":5118},{"style":147},[5119],{"type":21,"value":5120}," vite@latest",{"type":15,"tag":113,"props":5122,"children":5123},{"style":147},[5124],{"type":21,"value":5125}," frontend",{"type":15,"tag":113,"props":5127,"children":5128},{"style":198},[5129],{"type":21,"value":5130}," --",{"type":15,"tag":113,"props":5132,"children":5133},{"style":198},[5134],{"type":21,"value":5135}," --template",{"type":15,"tag":113,"props":5137,"children":5138},{"style":147},[5139],{"type":21,"value":5140}," vue-ts\n",{"type":15,"tag":113,"props":5142,"children":5143},{"class":115,"line":221},[5144,5149,5153,5157,5161,5166,5171,5176],{"type":15,"tag":113,"props":5145,"children":5146},{"style":198},[5147],{"type":21,"value":5148},"cd",{"type":15,"tag":113,"props":5150,"children":5151},{"style":147},[5152],{"type":21,"value":5125},{"type":15,"tag":113,"props":5154,"children":5155},{"style":136},[5156],{"type":21,"value":5044},{"type":15,"tag":113,"props":5158,"children":5159},{"style":172},[5160],{"type":21,"value":5110},{"type":15,"tag":113,"props":5162,"children":5163},{"style":147},[5164],{"type":21,"value":5165}," i",{"type":15,"tag":113,"props":5167,"children":5168},{"style":147},[5169],{"type":21,"value":5170}," axios",{"type":15,"tag":113,"props":5172,"children":5173},{"style":147},[5174],{"type":21,"value":5175}," pinia",{"type":15,"tag":113,"props":5177,"children":5178},{"style":147},[5179],{"type":21,"value":5180}," vue-router\n",{"type":15,"tag":56,"props":5182,"children":5184},{"id":5183},"_2-fastapi-路由pydantic-校验与-jwt",[5185],{"type":21,"value":5186},"2. FastAPI 路由、Pydantic 校验与 JWT",{"type":15,"tag":103,"props":5188,"children":5191},{"code":5189,"language":5024,"meta":7,"className":5190,"style":7},"# backend\u002Fapp\u002Fcore\u002Fsecurity.py\nfrom datetime import datetime, timedelta\nfrom jose import jwt\n\nSECRET_KEY = \"your-secret\"\nALGORITHM = \"HS256\"\n\ndef create_token(data: dict, expires_delta: timedelta = timedelta(hours=24)):\n    to_encode = data.copy()\n    to_encode.update({\"exp\": datetime.utcnow() + expires_delta})\n    return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)\n","language-python shiki shiki-themes github-light github-dark",[5192],{"type":15,"tag":80,"props":5193,"children":5194},{"__ignoreMap":7},[5195,5203,5224,5245,5252,5269,5286,5293,5349,5366,5394],{"type":15,"tag":113,"props":5196,"children":5197},{"class":115,"line":116},[5198],{"type":15,"tag":113,"props":5199,"children":5200},{"style":120},[5201],{"type":21,"value":5202},"# backend\u002Fapp\u002Fcore\u002Fsecurity.py\n",{"type":15,"tag":113,"props":5204,"children":5205},{"class":115,"line":126},[5206,5210,5215,5219],{"type":15,"tag":113,"props":5207,"children":5208},{"style":130},[5209],{"type":21,"value":144},{"type":15,"tag":113,"props":5211,"children":5212},{"style":136},[5213],{"type":21,"value":5214}," datetime ",{"type":15,"tag":113,"props":5216,"children":5217},{"style":130},[5218],{"type":21,"value":133},{"type":15,"tag":113,"props":5220,"children":5221},{"style":136},[5222],{"type":21,"value":5223}," datetime, timedelta\n",{"type":15,"tag":113,"props":5225,"children":5226},{"class":115,"line":153},[5227,5231,5236,5240],{"type":15,"tag":113,"props":5228,"children":5229},{"style":130},[5230],{"type":21,"value":144},{"type":15,"tag":113,"props":5232,"children":5233},{"style":136},[5234],{"type":21,"value":5235}," jose ",{"type":15,"tag":113,"props":5237,"children":5238},{"style":130},[5239],{"type":21,"value":133},{"type":15,"tag":113,"props":5241,"children":5242},{"style":136},[5243],{"type":21,"value":5244}," jwt\n",{"type":15,"tag":113,"props":5246,"children":5247},{"class":115,"line":163},[5248],{"type":15,"tag":113,"props":5249,"children":5250},{"emptyLinePlaceholder":157},[5251],{"type":21,"value":160},{"type":15,"tag":113,"props":5253,"children":5254},{"class":115,"line":183},[5255,5260,5264],{"type":15,"tag":113,"props":5256,"children":5257},{"style":198},[5258],{"type":21,"value":5259},"SECRET_KEY",{"type":15,"tag":113,"props":5261,"children":5262},{"style":130},[5263],{"type":21,"value":287},{"type":15,"tag":113,"props":5265,"children":5266},{"style":147},[5267],{"type":21,"value":5268}," \"your-secret\"\n",{"type":15,"tag":113,"props":5270,"children":5271},{"class":115,"line":204},[5272,5277,5281],{"type":15,"tag":113,"props":5273,"children":5274},{"style":198},[5275],{"type":21,"value":5276},"ALGORITHM",{"type":15,"tag":113,"props":5278,"children":5279},{"style":130},[5280],{"type":21,"value":287},{"type":15,"tag":113,"props":5282,"children":5283},{"style":147},[5284],{"type":21,"value":5285}," \"HS256\"\n",{"type":15,"tag":113,"props":5287,"children":5288},{"class":115,"line":221},[5289],{"type":15,"tag":113,"props":5290,"children":5291},{"emptyLinePlaceholder":157},[5292],{"type":21,"value":160},{"type":15,"tag":113,"props":5294,"children":5295},{"class":115,"line":239},[5296,5301,5306,5311,5316,5321,5325,5330,5335,5339,5344],{"type":15,"tag":113,"props":5297,"children":5298},{"style":130},[5299],{"type":21,"value":5300},"def",{"type":15,"tag":113,"props":5302,"children":5303},{"style":172},[5304],{"type":21,"value":5305}," create_token",{"type":15,"tag":113,"props":5307,"children":5308},{"style":136},[5309],{"type":21,"value":5310},"(data: ",{"type":15,"tag":113,"props":5312,"children":5313},{"style":198},[5314],{"type":21,"value":5315},"dict",{"type":15,"tag":113,"props":5317,"children":5318},{"style":136},[5319],{"type":21,"value":5320},", expires_delta: timedelta ",{"type":15,"tag":113,"props":5322,"children":5323},{"style":130},[5324],{"type":21,"value":628},{"type":15,"tag":113,"props":5326,"children":5327},{"style":136},[5328],{"type":21,"value":5329}," timedelta(",{"type":15,"tag":113,"props":5331,"children":5332},{"style":187},[5333],{"type":21,"value":5334},"hours",{"type":15,"tag":113,"props":5336,"children":5337},{"style":130},[5338],{"type":21,"value":628},{"type":15,"tag":113,"props":5340,"children":5341},{"style":198},[5342],{"type":21,"value":5343},"24",{"type":15,"tag":113,"props":5345,"children":5346},{"style":136},[5347],{"type":21,"value":5348},")):\n",{"type":15,"tag":113,"props":5350,"children":5351},{"class":115,"line":248},[5352,5357,5361],{"type":15,"tag":113,"props":5353,"children":5354},{"style":136},[5355],{"type":21,"value":5356},"    to_encode ",{"type":15,"tag":113,"props":5358,"children":5359},{"style":130},[5360],{"type":21,"value":628},{"type":15,"tag":113,"props":5362,"children":5363},{"style":136},[5364],{"type":21,"value":5365}," data.copy()\n",{"type":15,"tag":113,"props":5367,"children":5368},{"class":115,"line":256},[5369,5374,5379,5384,5389],{"type":15,"tag":113,"props":5370,"children":5371},{"style":136},[5372],{"type":21,"value":5373},"    to_encode.update({",{"type":15,"tag":113,"props":5375,"children":5376},{"style":147},[5377],{"type":21,"value":5378},"\"exp\"",{"type":15,"tag":113,"props":5380,"children":5381},{"style":136},[5382],{"type":21,"value":5383},": datetime.utcnow() ",{"type":15,"tag":113,"props":5385,"children":5386},{"style":130},[5387],{"type":21,"value":5388},"+",{"type":15,"tag":113,"props":5390,"children":5391},{"style":136},[5392],{"type":21,"value":5393}," expires_delta})\n",{"type":15,"tag":113,"props":5395,"children":5396},{"class":115,"line":300},[5397,5402,5407,5411,5415,5420,5424,5428],{"type":15,"tag":113,"props":5398,"children":5399},{"style":130},[5400],{"type":21,"value":5401},"    return",{"type":15,"tag":113,"props":5403,"children":5404},{"style":136},[5405],{"type":21,"value":5406}," jwt.encode(to_encode, ",{"type":15,"tag":113,"props":5408,"children":5409},{"style":198},[5410],{"type":21,"value":5259},{"type":15,"tag":113,"props":5412,"children":5413},{"style":136},[5414],{"type":21,"value":747},{"type":15,"tag":113,"props":5416,"children":5417},{"style":187},[5418],{"type":21,"value":5419},"algorithm",{"type":15,"tag":113,"props":5421,"children":5422},{"style":130},[5423],{"type":21,"value":628},{"type":15,"tag":113,"props":5425,"children":5426},{"style":198},[5427],{"type":21,"value":5276},{"type":15,"tag":113,"props":5429,"children":5430},{"style":136},[5431],{"type":21,"value":370},{"type":15,"tag":103,"props":5433,"children":5435},{"code":5434,"language":5024,"meta":7,"className":5190,"style":7},"# backend\u002Fapp\u002Frouters\u002Fauth.py\nfrom fastapi import APIRouter, Depends, HTTPException\nfrom pydantic import BaseModel\nfrom app.core.security import create_token\n\nrouter = APIRouter(prefix=\"\u002Fauth\", tags=[\"auth\"])\n\nclass LoginReq(BaseModel):\n    username: str\n    password: str\n\n@router.post(\"\u002Flogin\")\ndef login(payload: LoginReq):\n    if payload.username != \"admin\" or payload.password != \"123\":\n        raise HTTPException(401, \"Invalid credentials\")\n    return {\"access_token\": create_token({\"sub\": payload.username})}\n",[5436],{"type":15,"tag":80,"props":5437,"children":5438},{"__ignoreMap":7},[5439,5447,5468,5489,5510,5517,5576,5583,5610,5623,5635,5642,5663,5680,5726,5757],{"type":15,"tag":113,"props":5440,"children":5441},{"class":115,"line":116},[5442],{"type":15,"tag":113,"props":5443,"children":5444},{"style":120},[5445],{"type":21,"value":5446},"# backend\u002Fapp\u002Frouters\u002Fauth.py\n",{"type":15,"tag":113,"props":5448,"children":5449},{"class":115,"line":126},[5450,5454,5459,5463],{"type":15,"tag":113,"props":5451,"children":5452},{"style":130},[5453],{"type":21,"value":144},{"type":15,"tag":113,"props":5455,"children":5456},{"style":136},[5457],{"type":21,"value":5458}," fastapi ",{"type":15,"tag":113,"props":5460,"children":5461},{"style":130},[5462],{"type":21,"value":133},{"type":15,"tag":113,"props":5464,"children":5465},{"style":136},[5466],{"type":21,"value":5467}," APIRouter, Depends, HTTPException\n",{"type":15,"tag":113,"props":5469,"children":5470},{"class":115,"line":153},[5471,5475,5480,5484],{"type":15,"tag":113,"props":5472,"children":5473},{"style":130},[5474],{"type":21,"value":144},{"type":15,"tag":113,"props":5476,"children":5477},{"style":136},[5478],{"type":21,"value":5479}," pydantic ",{"type":15,"tag":113,"props":5481,"children":5482},{"style":130},[5483],{"type":21,"value":133},{"type":15,"tag":113,"props":5485,"children":5486},{"style":136},[5487],{"type":21,"value":5488}," BaseModel\n",{"type":15,"tag":113,"props":5490,"children":5491},{"class":115,"line":163},[5492,5496,5501,5505],{"type":15,"tag":113,"props":5493,"children":5494},{"style":130},[5495],{"type":21,"value":144},{"type":15,"tag":113,"props":5497,"children":5498},{"style":136},[5499],{"type":21,"value":5500}," app.core.security ",{"type":15,"tag":113,"props":5502,"children":5503},{"style":130},[5504],{"type":21,"value":133},{"type":15,"tag":113,"props":5506,"children":5507},{"style":136},[5508],{"type":21,"value":5509}," create_token\n",{"type":15,"tag":113,"props":5511,"children":5512},{"class":115,"line":183},[5513],{"type":15,"tag":113,"props":5514,"children":5515},{"emptyLinePlaceholder":157},[5516],{"type":21,"value":160},{"type":15,"tag":113,"props":5518,"children":5519},{"class":115,"line":204},[5520,5525,5529,5534,5539,5543,5548,5552,5557,5561,5566,5571],{"type":15,"tag":113,"props":5521,"children":5522},{"style":136},[5523],{"type":21,"value":5524},"router ",{"type":15,"tag":113,"props":5526,"children":5527},{"style":130},[5528],{"type":21,"value":628},{"type":15,"tag":113,"props":5530,"children":5531},{"style":136},[5532],{"type":21,"value":5533}," APIRouter(",{"type":15,"tag":113,"props":5535,"children":5536},{"style":187},[5537],{"type":21,"value":5538},"prefix",{"type":15,"tag":113,"props":5540,"children":5541},{"style":130},[5542],{"type":21,"value":628},{"type":15,"tag":113,"props":5544,"children":5545},{"style":147},[5546],{"type":21,"value":5547},"\"\u002Fauth\"",{"type":15,"tag":113,"props":5549,"children":5550},{"style":136},[5551],{"type":21,"value":747},{"type":15,"tag":113,"props":5553,"children":5554},{"style":187},[5555],{"type":21,"value":5556},"tags",{"type":15,"tag":113,"props":5558,"children":5559},{"style":130},[5560],{"type":21,"value":628},{"type":15,"tag":113,"props":5562,"children":5563},{"style":136},[5564],{"type":21,"value":5565},"[",{"type":15,"tag":113,"props":5567,"children":5568},{"style":147},[5569],{"type":21,"value":5570},"\"auth\"",{"type":15,"tag":113,"props":5572,"children":5573},{"style":136},[5574],{"type":21,"value":5575},"])\n",{"type":15,"tag":113,"props":5577,"children":5578},{"class":115,"line":221},[5579],{"type":15,"tag":113,"props":5580,"children":5581},{"emptyLinePlaceholder":157},[5582],{"type":21,"value":160},{"type":15,"tag":113,"props":5584,"children":5585},{"class":115,"line":239},[5586,5591,5596,5600,5605],{"type":15,"tag":113,"props":5587,"children":5588},{"style":130},[5589],{"type":21,"value":5590},"class",{"type":15,"tag":113,"props":5592,"children":5593},{"style":172},[5594],{"type":21,"value":5595}," LoginReq",{"type":15,"tag":113,"props":5597,"children":5598},{"style":136},[5599],{"type":21,"value":277},{"type":15,"tag":113,"props":5601,"children":5602},{"style":172},[5603],{"type":21,"value":5604},"BaseModel",{"type":15,"tag":113,"props":5606,"children":5607},{"style":136},[5608],{"type":21,"value":5609},"):\n",{"type":15,"tag":113,"props":5611,"children":5612},{"class":115,"line":248},[5613,5618],{"type":15,"tag":113,"props":5614,"children":5615},{"style":136},[5616],{"type":21,"value":5617},"    username: ",{"type":15,"tag":113,"props":5619,"children":5620},{"style":198},[5621],{"type":21,"value":5622},"str\n",{"type":15,"tag":113,"props":5624,"children":5625},{"class":115,"line":256},[5626,5631],{"type":15,"tag":113,"props":5627,"children":5628},{"style":136},[5629],{"type":21,"value":5630},"    password: ",{"type":15,"tag":113,"props":5632,"children":5633},{"style":198},[5634],{"type":21,"value":5622},{"type":15,"tag":113,"props":5636,"children":5637},{"class":115,"line":300},[5638],{"type":15,"tag":113,"props":5639,"children":5640},{"emptyLinePlaceholder":157},[5641],{"type":21,"value":160},{"type":15,"tag":113,"props":5643,"children":5644},{"class":115,"line":338},[5645,5650,5654,5659],{"type":15,"tag":113,"props":5646,"children":5647},{"style":172},[5648],{"type":21,"value":5649},"@router.post",{"type":15,"tag":113,"props":5651,"children":5652},{"style":136},[5653],{"type":21,"value":277},{"type":15,"tag":113,"props":5655,"children":5656},{"style":147},[5657],{"type":21,"value":5658},"\"\u002Flogin\"",{"type":15,"tag":113,"props":5660,"children":5661},{"style":136},[5662],{"type":21,"value":370},{"type":15,"tag":113,"props":5664,"children":5665},{"class":115,"line":373},[5666,5670,5675],{"type":15,"tag":113,"props":5667,"children":5668},{"style":130},[5669],{"type":21,"value":5300},{"type":15,"tag":113,"props":5671,"children":5672},{"style":172},[5673],{"type":21,"value":5674}," login",{"type":15,"tag":113,"props":5676,"children":5677},{"style":136},[5678],{"type":21,"value":5679},"(payload: LoginReq):\n",{"type":15,"tag":113,"props":5681,"children":5682},{"class":115,"line":415},[5683,5687,5692,5697,5702,5707,5712,5716,5721],{"type":15,"tag":113,"props":5684,"children":5685},{"style":130},[5686],{"type":21,"value":469},{"type":15,"tag":113,"props":5688,"children":5689},{"style":136},[5690],{"type":21,"value":5691}," payload.username ",{"type":15,"tag":113,"props":5693,"children":5694},{"style":130},[5695],{"type":21,"value":5696},"!=",{"type":15,"tag":113,"props":5698,"children":5699},{"style":147},[5700],{"type":21,"value":5701}," \"admin\"",{"type":15,"tag":113,"props":5703,"children":5704},{"style":130},[5705],{"type":21,"value":5706}," or",{"type":15,"tag":113,"props":5708,"children":5709},{"style":136},[5710],{"type":21,"value":5711}," payload.password ",{"type":15,"tag":113,"props":5713,"children":5714},{"style":130},[5715],{"type":21,"value":5696},{"type":15,"tag":113,"props":5717,"children":5718},{"style":147},[5719],{"type":21,"value":5720}," \"123\"",{"type":15,"tag":113,"props":5722,"children":5723},{"style":136},[5724],{"type":21,"value":5725},":\n",{"type":15,"tag":113,"props":5727,"children":5728},{"class":115,"line":423},[5729,5734,5739,5744,5748,5753],{"type":15,"tag":113,"props":5730,"children":5731},{"style":130},[5732],{"type":21,"value":5733},"        raise",{"type":15,"tag":113,"props":5735,"children":5736},{"style":136},[5737],{"type":21,"value":5738}," HTTPException(",{"type":15,"tag":113,"props":5740,"children":5741},{"style":198},[5742],{"type":21,"value":5743},"401",{"type":15,"tag":113,"props":5745,"children":5746},{"style":136},[5747],{"type":21,"value":747},{"type":15,"tag":113,"props":5749,"children":5750},{"style":147},[5751],{"type":21,"value":5752},"\"Invalid credentials\"",{"type":15,"tag":113,"props":5754,"children":5755},{"style":136},[5756],{"type":21,"value":370},{"type":15,"tag":113,"props":5758,"children":5759},{"class":115,"line":454},[5760,5764,5769,5774,5779,5784],{"type":15,"tag":113,"props":5761,"children":5762},{"style":130},[5763],{"type":21,"value":5401},{"type":15,"tag":113,"props":5765,"children":5766},{"style":136},[5767],{"type":21,"value":5768}," {",{"type":15,"tag":113,"props":5770,"children":5771},{"style":147},[5772],{"type":21,"value":5773},"\"access_token\"",{"type":15,"tag":113,"props":5775,"children":5776},{"style":136},[5777],{"type":21,"value":5778},": create_token({",{"type":15,"tag":113,"props":5780,"children":5781},{"style":147},[5782],{"type":21,"value":5783},"\"sub\"",{"type":15,"tag":113,"props":5785,"children":5786},{"style":136},[5787],{"type":21,"value":5788},": payload.username})}\n",{"type":15,"tag":56,"props":5790,"children":5792},{"id":5791},"_3-vue3-请求封装与拦截器",[5793],{"type":21,"value":5794},"3. Vue3 请求封装与拦截器",{"type":15,"tag":103,"props":5796,"children":5800},{"code":5797,"language":5798,"meta":7,"className":5799,"style":7},"\u002F\u002F frontend\u002Fsrc\u002Fapi\u002Fclient.ts\nimport axios from \"axios\"\nimport { useAuthStore } from \"@\u002Fstores\u002Fauth\"\n\nconst api = axios.create({ baseURL: \"\u002Fapi\", timeout: 5000 })\n\napi.interceptors.request.use(cfg => {\n  const token = useAuthStore().token\n  if (token) cfg.headers.Authorization = `Bearer ${token}`\n  return cfg\n})\n\napi.interceptors.response.use(\n  res => res.data,\n  err => {\n    if (err.response?.status === 401) useAuthStore().logout()\n    return Promise.reject(err)\n  }\n)\n\nexport default api\n","ts","language-ts shiki shiki-themes github-light github-dark",[5801],{"type":15,"tag":80,"props":5802,"children":5803},{"__ignoreMap":7},[5804,5812,5833,5854,5861,5911,5918,5949,5975,6007,6019,6027,6034,6050,6067,6083,6127,6153,6160,6167,6174],{"type":15,"tag":113,"props":5805,"children":5806},{"class":115,"line":116},[5807],{"type":15,"tag":113,"props":5808,"children":5809},{"style":120},[5810],{"type":21,"value":5811},"\u002F\u002F frontend\u002Fsrc\u002Fapi\u002Fclient.ts\n",{"type":15,"tag":113,"props":5813,"children":5814},{"class":115,"line":126},[5815,5819,5824,5828],{"type":15,"tag":113,"props":5816,"children":5817},{"style":130},[5818],{"type":21,"value":133},{"type":15,"tag":113,"props":5820,"children":5821},{"style":136},[5822],{"type":21,"value":5823}," axios ",{"type":15,"tag":113,"props":5825,"children":5826},{"style":130},[5827],{"type":21,"value":144},{"type":15,"tag":113,"props":5829,"children":5830},{"style":147},[5831],{"type":21,"value":5832}," \"axios\"\n",{"type":15,"tag":113,"props":5834,"children":5835},{"class":115,"line":153},[5836,5840,5845,5849],{"type":15,"tag":113,"props":5837,"children":5838},{"style":130},[5839],{"type":21,"value":133},{"type":15,"tag":113,"props":5841,"children":5842},{"style":136},[5843],{"type":21,"value":5844}," { useAuthStore } ",{"type":15,"tag":113,"props":5846,"children":5847},{"style":130},[5848],{"type":21,"value":144},{"type":15,"tag":113,"props":5850,"children":5851},{"style":147},[5852],{"type":21,"value":5853}," \"@\u002Fstores\u002Fauth\"\n",{"type":15,"tag":113,"props":5855,"children":5856},{"class":115,"line":163},[5857],{"type":15,"tag":113,"props":5858,"children":5859},{"emptyLinePlaceholder":157},[5860],{"type":21,"value":160},{"type":15,"tag":113,"props":5862,"children":5863},{"class":115,"line":183},[5864,5868,5873,5877,5882,5887,5892,5897,5902,5907],{"type":15,"tag":113,"props":5865,"children":5866},{"style":130},[5867],{"type":21,"value":2477},{"type":15,"tag":113,"props":5869,"children":5870},{"style":198},[5871],{"type":21,"value":5872}," api",{"type":15,"tag":113,"props":5874,"children":5875},{"style":130},[5876],{"type":21,"value":287},{"type":15,"tag":113,"props":5878,"children":5879},{"style":136},[5880],{"type":21,"value":5881}," axios.",{"type":15,"tag":113,"props":5883,"children":5884},{"style":172},[5885],{"type":21,"value":5886},"create",{"type":15,"tag":113,"props":5888,"children":5889},{"style":136},[5890],{"type":21,"value":5891},"({ baseURL: ",{"type":15,"tag":113,"props":5893,"children":5894},{"style":147},[5895],{"type":21,"value":5896},"\"\u002Fapi\"",{"type":15,"tag":113,"props":5898,"children":5899},{"style":136},[5900],{"type":21,"value":5901},", timeout: ",{"type":15,"tag":113,"props":5903,"children":5904},{"style":198},[5905],{"type":21,"value":5906},"5000",{"type":15,"tag":113,"props":5908,"children":5909},{"style":136},[5910],{"type":21,"value":2110},{"type":15,"tag":113,"props":5912,"children":5913},{"class":115,"line":204},[5914],{"type":15,"tag":113,"props":5915,"children":5916},{"emptyLinePlaceholder":157},[5917],{"type":21,"value":160},{"type":15,"tag":113,"props":5919,"children":5920},{"class":115,"line":221},[5921,5926,5931,5935,5940,5945],{"type":15,"tag":113,"props":5922,"children":5923},{"style":136},[5924],{"type":21,"value":5925},"api.interceptors.request.",{"type":15,"tag":113,"props":5927,"children":5928},{"style":172},[5929],{"type":21,"value":5930},"use",{"type":15,"tag":113,"props":5932,"children":5933},{"style":136},[5934],{"type":21,"value":277},{"type":15,"tag":113,"props":5936,"children":5937},{"style":187},[5938],{"type":21,"value":5939},"cfg",{"type":15,"tag":113,"props":5941,"children":5942},{"style":130},[5943],{"type":21,"value":5944}," =>",{"type":15,"tag":113,"props":5946,"children":5947},{"style":136},[5948],{"type":21,"value":180},{"type":15,"tag":113,"props":5950,"children":5951},{"class":115,"line":239},[5952,5956,5961,5965,5970],{"type":15,"tag":113,"props":5953,"children":5954},{"style":130},[5955],{"type":21,"value":306},{"type":15,"tag":113,"props":5957,"children":5958},{"style":198},[5959],{"type":21,"value":5960}," token",{"type":15,"tag":113,"props":5962,"children":5963},{"style":130},[5964],{"type":21,"value":287},{"type":15,"tag":113,"props":5966,"children":5967},{"style":172},[5968],{"type":21,"value":5969}," useAuthStore",{"type":15,"tag":113,"props":5971,"children":5972},{"style":136},[5973],{"type":21,"value":5974},"().token\n",{"type":15,"tag":113,"props":5976,"children":5977},{"class":115,"line":248},[5978,5983,5988,5992,5997,6002],{"type":15,"tag":113,"props":5979,"children":5980},{"style":130},[5981],{"type":21,"value":5982},"  if",{"type":15,"tag":113,"props":5984,"children":5985},{"style":136},[5986],{"type":21,"value":5987}," (token) cfg.headers.Authorization ",{"type":15,"tag":113,"props":5989,"children":5990},{"style":130},[5991],{"type":21,"value":628},{"type":15,"tag":113,"props":5993,"children":5994},{"style":147},[5995],{"type":21,"value":5996}," `Bearer ${",{"type":15,"tag":113,"props":5998,"children":5999},{"style":136},[6000],{"type":21,"value":6001},"token",{"type":15,"tag":113,"props":6003,"children":6004},{"style":147},[6005],{"type":21,"value":6006},"}`\n",{"type":15,"tag":113,"props":6008,"children":6009},{"class":115,"line":256},[6010,6014],{"type":15,"tag":113,"props":6011,"children":6012},{"style":130},[6013],{"type":21,"value":1514},{"type":15,"tag":113,"props":6015,"children":6016},{"style":136},[6017],{"type":21,"value":6018}," cfg\n",{"type":15,"tag":113,"props":6020,"children":6021},{"class":115,"line":300},[6022],{"type":15,"tag":113,"props":6023,"children":6024},{"style":136},[6025],{"type":21,"value":6026},"})\n",{"type":15,"tag":113,"props":6028,"children":6029},{"class":115,"line":338},[6030],{"type":15,"tag":113,"props":6031,"children":6032},{"emptyLinePlaceholder":157},[6033],{"type":21,"value":160},{"type":15,"tag":113,"props":6035,"children":6036},{"class":115,"line":373},[6037,6042,6046],{"type":15,"tag":113,"props":6038,"children":6039},{"style":136},[6040],{"type":21,"value":6041},"api.interceptors.response.",{"type":15,"tag":113,"props":6043,"children":6044},{"style":172},[6045],{"type":21,"value":5930},{"type":15,"tag":113,"props":6047,"children":6048},{"style":136},[6049],{"type":21,"value":1107},{"type":15,"tag":113,"props":6051,"children":6052},{"class":115,"line":415},[6053,6058,6062],{"type":15,"tag":113,"props":6054,"children":6055},{"style":187},[6056],{"type":21,"value":6057},"  res",{"type":15,"tag":113,"props":6059,"children":6060},{"style":130},[6061],{"type":21,"value":5944},{"type":15,"tag":113,"props":6063,"children":6064},{"style":136},[6065],{"type":21,"value":6066}," res.data,\n",{"type":15,"tag":113,"props":6068,"children":6069},{"class":115,"line":423},[6070,6075,6079],{"type":15,"tag":113,"props":6071,"children":6072},{"style":187},[6073],{"type":21,"value":6074},"  err",{"type":15,"tag":113,"props":6076,"children":6077},{"style":130},[6078],{"type":21,"value":5944},{"type":15,"tag":113,"props":6080,"children":6081},{"style":136},[6082],{"type":21,"value":180},{"type":15,"tag":113,"props":6084,"children":6085},{"class":115,"line":454},[6086,6090,6095,6100,6105,6109,6114,6118,6123],{"type":15,"tag":113,"props":6087,"children":6088},{"style":130},[6089],{"type":21,"value":469},{"type":15,"tag":113,"props":6091,"children":6092},{"style":136},[6093],{"type":21,"value":6094}," (err.response?.status ",{"type":15,"tag":113,"props":6096,"children":6097},{"style":130},[6098],{"type":21,"value":6099},"===",{"type":15,"tag":113,"props":6101,"children":6102},{"style":198},[6103],{"type":21,"value":6104}," 401",{"type":15,"tag":113,"props":6106,"children":6107},{"style":136},[6108],{"type":21,"value":662},{"type":15,"tag":113,"props":6110,"children":6111},{"style":172},[6112],{"type":21,"value":6113},"useAuthStore",{"type":15,"tag":113,"props":6115,"children":6116},{"style":136},[6117],{"type":21,"value":709},{"type":15,"tag":113,"props":6119,"children":6120},{"style":172},[6121],{"type":21,"value":6122},"logout",{"type":15,"tag":113,"props":6124,"children":6125},{"style":136},[6126],{"type":21,"value":958},{"type":15,"tag":113,"props":6128,"children":6129},{"class":115,"line":463},[6130,6134,6139,6143,6148],{"type":15,"tag":113,"props":6131,"children":6132},{"style":130},[6133],{"type":21,"value":5401},{"type":15,"tag":113,"props":6135,"children":6136},{"style":198},[6137],{"type":21,"value":6138}," Promise",{"type":15,"tag":113,"props":6140,"children":6141},{"style":136},[6142],{"type":21,"value":483},{"type":15,"tag":113,"props":6144,"children":6145},{"style":172},[6146],{"type":21,"value":6147},"reject",{"type":15,"tag":113,"props":6149,"children":6150},{"style":136},[6151],{"type":21,"value":6152},"(err)\n",{"type":15,"tag":113,"props":6154,"children":6155},{"class":115,"line":501},[6156],{"type":15,"tag":113,"props":6157,"children":6158},{"style":136},[6159],{"type":21,"value":967},{"type":15,"tag":113,"props":6161,"children":6162},{"class":115,"line":510},[6163],{"type":15,"tag":113,"props":6164,"children":6165},{"style":136},[6166],{"type":21,"value":370},{"type":15,"tag":113,"props":6168,"children":6169},{"class":115,"line":543},[6170],{"type":15,"tag":113,"props":6171,"children":6172},{"emptyLinePlaceholder":157},[6173],{"type":21,"value":160},{"type":15,"tag":113,"props":6175,"children":6176},{"class":115,"line":569},[6177,6181,6186],{"type":15,"tag":113,"props":6178,"children":6179},{"style":130},[6180],{"type":21,"value":262},{"type":15,"tag":113,"props":6182,"children":6183},{"style":130},[6184],{"type":21,"value":6185}," default",{"type":15,"tag":113,"props":6187,"children":6188},{"style":136},[6189],{"type":21,"value":6190}," api\n",{"type":15,"tag":103,"props":6192,"children":6194},{"code":6193,"language":5798,"meta":7,"className":5799,"style":7},"\u002F\u002F frontend\u002Fsrc\u002Fstores\u002Fauth.ts\nimport { defineStore } from \"pinia\"\nimport { ref } from \"vue\"\n\nexport const useAuthStore = defineStore(\"auth\", () => {\n  const token = ref\u003Cstring | null>(localStorage.getItem(\"token\"))\n  const setToken = (t: string) => { token.value = t; localStorage.setItem(\"token\", t) }\n  const logout = () => { token.value = null; localStorage.removeItem(\"token\") }\n  return { token, setToken, logout }\n})\n",[6195],{"type":15,"tag":80,"props":6196,"children":6197},{"__ignoreMap":7},[6198,6206,6227,6248,6255,6301,6361,6435,6494,6506],{"type":15,"tag":113,"props":6199,"children":6200},{"class":115,"line":116},[6201],{"type":15,"tag":113,"props":6202,"children":6203},{"style":120},[6204],{"type":21,"value":6205},"\u002F\u002F frontend\u002Fsrc\u002Fstores\u002Fauth.ts\n",{"type":15,"tag":113,"props":6207,"children":6208},{"class":115,"line":126},[6209,6213,6218,6222],{"type":15,"tag":113,"props":6210,"children":6211},{"style":130},[6212],{"type":21,"value":133},{"type":15,"tag":113,"props":6214,"children":6215},{"style":136},[6216],{"type":21,"value":6217}," { defineStore } ",{"type":15,"tag":113,"props":6219,"children":6220},{"style":130},[6221],{"type":21,"value":144},{"type":15,"tag":113,"props":6223,"children":6224},{"style":147},[6225],{"type":21,"value":6226}," \"pinia\"\n",{"type":15,"tag":113,"props":6228,"children":6229},{"class":115,"line":153},[6230,6234,6239,6243],{"type":15,"tag":113,"props":6231,"children":6232},{"style":130},[6233],{"type":21,"value":133},{"type":15,"tag":113,"props":6235,"children":6236},{"style":136},[6237],{"type":21,"value":6238}," { ref } ",{"type":15,"tag":113,"props":6240,"children":6241},{"style":130},[6242],{"type":21,"value":144},{"type":15,"tag":113,"props":6244,"children":6245},{"style":147},[6246],{"type":21,"value":6247}," \"vue\"\n",{"type":15,"tag":113,"props":6249,"children":6250},{"class":115,"line":163},[6251],{"type":15,"tag":113,"props":6252,"children":6253},{"emptyLinePlaceholder":157},[6254],{"type":21,"value":160},{"type":15,"tag":113,"props":6256,"children":6257},{"class":115,"line":183},[6258,6262,6267,6271,6275,6280,6284,6288,6293,6297],{"type":15,"tag":113,"props":6259,"children":6260},{"style":130},[6261],{"type":21,"value":262},{"type":15,"tag":113,"props":6263,"children":6264},{"style":130},[6265],{"type":21,"value":6266}," const",{"type":15,"tag":113,"props":6268,"children":6269},{"style":198},[6270],{"type":21,"value":5969},{"type":15,"tag":113,"props":6272,"children":6273},{"style":130},[6274],{"type":21,"value":287},{"type":15,"tag":113,"props":6276,"children":6277},{"style":172},[6278],{"type":21,"value":6279}," defineStore",{"type":15,"tag":113,"props":6281,"children":6282},{"style":136},[6283],{"type":21,"value":277},{"type":15,"tag":113,"props":6285,"children":6286},{"style":147},[6287],{"type":21,"value":5570},{"type":15,"tag":113,"props":6289,"children":6290},{"style":136},[6291],{"type":21,"value":6292},", () ",{"type":15,"tag":113,"props":6294,"children":6295},{"style":130},[6296],{"type":21,"value":447},{"type":15,"tag":113,"props":6298,"children":6299},{"style":136},[6300],{"type":21,"value":180},{"type":15,"tag":113,"props":6302,"children":6303},{"class":115,"line":204},[6304,6308,6312,6316,6320,6324,6329,6333,6337,6342,6347,6351,6356],{"type":15,"tag":113,"props":6305,"children":6306},{"style":130},[6307],{"type":21,"value":306},{"type":15,"tag":113,"props":6309,"children":6310},{"style":198},[6311],{"type":21,"value":5960},{"type":15,"tag":113,"props":6313,"children":6314},{"style":130},[6315],{"type":21,"value":287},{"type":15,"tag":113,"props":6317,"children":6318},{"style":172},[6319],{"type":21,"value":320},{"type":15,"tag":113,"props":6321,"children":6322},{"style":136},[6323],{"type":21,"value":325},{"type":15,"tag":113,"props":6325,"children":6326},{"style":198},[6327],{"type":21,"value":6328},"string",{"type":15,"tag":113,"props":6330,"children":6331},{"style":130},[6332],{"type":21,"value":398},{"type":15,"tag":113,"props":6334,"children":6335},{"style":198},[6336],{"type":21,"value":403},{"type":15,"tag":113,"props":6338,"children":6339},{"style":136},[6340],{"type":21,"value":6341},">(localStorage.",{"type":15,"tag":113,"props":6343,"children":6344},{"style":172},[6345],{"type":21,"value":6346},"getItem",{"type":15,"tag":113,"props":6348,"children":6349},{"style":136},[6350],{"type":21,"value":277},{"type":15,"tag":113,"props":6352,"children":6353},{"style":147},[6354],{"type":21,"value":6355},"\"token\"",{"type":15,"tag":113,"props":6357,"children":6358},{"style":136},[6359],{"type":21,"value":6360},"))\n",{"type":15,"tag":113,"props":6362,"children":6363},{"class":115,"line":221},[6364,6368,6373,6377,6381,6386,6390,6395,6399,6403,6408,6412,6417,6422,6426,6430],{"type":15,"tag":113,"props":6365,"children":6366},{"style":130},[6367],{"type":21,"value":306},{"type":15,"tag":113,"props":6369,"children":6370},{"style":172},[6371],{"type":21,"value":6372}," setToken",{"type":15,"tag":113,"props":6374,"children":6375},{"style":130},[6376],{"type":21,"value":287},{"type":15,"tag":113,"props":6378,"children":6379},{"style":136},[6380],{"type":21,"value":474},{"type":15,"tag":113,"props":6382,"children":6383},{"style":187},[6384],{"type":21,"value":6385},"t",{"type":15,"tag":113,"props":6387,"children":6388},{"style":130},[6389],{"type":21,"value":195},{"type":15,"tag":113,"props":6391,"children":6392},{"style":198},[6393],{"type":21,"value":6394}," string",{"type":15,"tag":113,"props":6396,"children":6397},{"style":136},[6398],{"type":21,"value":662},{"type":15,"tag":113,"props":6400,"children":6401},{"style":130},[6402],{"type":21,"value":447},{"type":15,"tag":113,"props":6404,"children":6405},{"style":136},[6406],{"type":21,"value":6407}," { token.value ",{"type":15,"tag":113,"props":6409,"children":6410},{"style":130},[6411],{"type":21,"value":628},{"type":15,"tag":113,"props":6413,"children":6414},{"style":136},[6415],{"type":21,"value":6416}," t; localStorage.",{"type":15,"tag":113,"props":6418,"children":6419},{"style":172},[6420],{"type":21,"value":6421},"setItem",{"type":15,"tag":113,"props":6423,"children":6424},{"style":136},[6425],{"type":21,"value":277},{"type":15,"tag":113,"props":6427,"children":6428},{"style":147},[6429],{"type":21,"value":6355},{"type":15,"tag":113,"props":6431,"children":6432},{"style":136},[6433],{"type":21,"value":6434},", t) }\n",{"type":15,"tag":113,"props":6436,"children":6437},{"class":115,"line":239},[6438,6442,6447,6451,6455,6459,6463,6467,6471,6476,6481,6485,6489],{"type":15,"tag":113,"props":6439,"children":6440},{"style":130},[6441],{"type":21,"value":306},{"type":15,"tag":113,"props":6443,"children":6444},{"style":172},[6445],{"type":21,"value":6446}," logout",{"type":15,"tag":113,"props":6448,"children":6449},{"style":130},[6450],{"type":21,"value":287},{"type":15,"tag":113,"props":6452,"children":6453},{"style":136},[6454],{"type":21,"value":442},{"type":15,"tag":113,"props":6456,"children":6457},{"style":130},[6458],{"type":21,"value":447},{"type":15,"tag":113,"props":6460,"children":6461},{"style":136},[6462],{"type":21,"value":6407},{"type":15,"tag":113,"props":6464,"children":6465},{"style":130},[6466],{"type":21,"value":628},{"type":15,"tag":113,"props":6468,"children":6469},{"style":198},[6470],{"type":21,"value":403},{"type":15,"tag":113,"props":6472,"children":6473},{"style":136},[6474],{"type":21,"value":6475},"; localStorage.",{"type":15,"tag":113,"props":6477,"children":6478},{"style":172},[6479],{"type":21,"value":6480},"removeItem",{"type":15,"tag":113,"props":6482,"children":6483},{"style":136},[6484],{"type":21,"value":277},{"type":15,"tag":113,"props":6486,"children":6487},{"style":147},[6488],{"type":21,"value":6355},{"type":15,"tag":113,"props":6490,"children":6491},{"style":136},[6492],{"type":21,"value":6493},") }\n",{"type":15,"tag":113,"props":6495,"children":6496},{"class":115,"line":248},[6497,6501],{"type":15,"tag":113,"props":6498,"children":6499},{"style":130},[6500],{"type":21,"value":1514},{"type":15,"tag":113,"props":6502,"children":6503},{"style":136},[6504],{"type":21,"value":6505}," { token, setToken, logout }\n",{"type":15,"tag":113,"props":6507,"children":6508},{"class":115,"line":256},[6509],{"type":15,"tag":113,"props":6510,"children":6511},{"style":136},[6512],{"type":21,"value":6026},{"type":15,"tag":56,"props":6514,"children":6516},{"id":6515},"_4-本地开发与跨域配置",[6517],{"type":21,"value":6518},"4. 本地开发与跨域配置",{"type":15,"tag":23,"props":6520,"children":6521},{},[6522],{"type":15,"tag":29,"props":6523,"children":6524},{},[6525,6527,6533],{"type":21,"value":6526},"Vite 代理 (",{"type":15,"tag":80,"props":6528,"children":6530},{"className":6529},[],[6531],{"type":21,"value":6532},"frontend\u002Fvite.config.ts",{"type":21,"value":757},{"type":15,"tag":103,"props":6535,"children":6537},{"code":6536,"language":5798,"meta":7,"className":5799,"style":7},"export default defineConfig({\n  server: {\n    proxy: {\n      \"\u002Fapi\": {\n        target: \"http:\u002F\u002F127.0.0.1:8000\",\n        changeOrigin: true,\n        rewrite: path => path.replace(\u002F^\\\u002Fapi\u002F, \"\")\n      }\n    }\n  }\n})\n",[6538],{"type":15,"tag":80,"props":6539,"children":6540},{"__ignoreMap":7},[6541,6562,6570,6578,6591,6608,6624,6698,6705,6712,6719],{"type":15,"tag":113,"props":6542,"children":6543},{"class":115,"line":116},[6544,6548,6552,6557],{"type":15,"tag":113,"props":6545,"children":6546},{"style":130},[6547],{"type":21,"value":262},{"type":15,"tag":113,"props":6549,"children":6550},{"style":130},[6551],{"type":21,"value":6185},{"type":15,"tag":113,"props":6553,"children":6554},{"style":172},[6555],{"type":21,"value":6556}," defineConfig",{"type":15,"tag":113,"props":6558,"children":6559},{"style":136},[6560],{"type":21,"value":6561},"({\n",{"type":15,"tag":113,"props":6563,"children":6564},{"class":115,"line":126},[6565],{"type":15,"tag":113,"props":6566,"children":6567},{"style":136},[6568],{"type":21,"value":6569},"  server: {\n",{"type":15,"tag":113,"props":6571,"children":6572},{"class":115,"line":153},[6573],{"type":15,"tag":113,"props":6574,"children":6575},{"style":136},[6576],{"type":21,"value":6577},"    proxy: {\n",{"type":15,"tag":113,"props":6579,"children":6580},{"class":115,"line":163},[6581,6586],{"type":15,"tag":113,"props":6582,"children":6583},{"style":147},[6584],{"type":21,"value":6585},"      \"\u002Fapi\"",{"type":15,"tag":113,"props":6587,"children":6588},{"style":136},[6589],{"type":21,"value":6590},": {\n",{"type":15,"tag":113,"props":6592,"children":6593},{"class":115,"line":183},[6594,6599,6604],{"type":15,"tag":113,"props":6595,"children":6596},{"style":136},[6597],{"type":21,"value":6598},"        target: ",{"type":15,"tag":113,"props":6600,"children":6601},{"style":147},[6602],{"type":21,"value":6603},"\"http:\u002F\u002F127.0.0.1:8000\"",{"type":15,"tag":113,"props":6605,"children":6606},{"style":136},[6607],{"type":21,"value":767},{"type":15,"tag":113,"props":6609,"children":6610},{"class":115,"line":204},[6611,6616,6620],{"type":15,"tag":113,"props":6612,"children":6613},{"style":136},[6614],{"type":21,"value":6615},"        changeOrigin: ",{"type":15,"tag":113,"props":6617,"children":6618},{"style":198},[6619],{"type":21,"value":2105},{"type":15,"tag":113,"props":6621,"children":6622},{"style":136},[6623],{"type":21,"value":767},{"type":15,"tag":113,"props":6625,"children":6626},{"class":115,"line":221},[6627,6632,6637,6642,6646,6651,6656,6660,6664,6669,6675,6681,6685,6689,6694],{"type":15,"tag":113,"props":6628,"children":6629},{"style":172},[6630],{"type":21,"value":6631},"        rewrite",{"type":15,"tag":113,"props":6633,"children":6634},{"style":136},[6635],{"type":21,"value":6636},": ",{"type":15,"tag":113,"props":6638,"children":6639},{"style":187},[6640],{"type":21,"value":6641},"path",{"type":15,"tag":113,"props":6643,"children":6644},{"style":130},[6645],{"type":21,"value":5944},{"type":15,"tag":113,"props":6647,"children":6648},{"style":136},[6649],{"type":21,"value":6650}," path.",{"type":15,"tag":113,"props":6652,"children":6653},{"style":172},[6654],{"type":21,"value":6655},"replace",{"type":15,"tag":113,"props":6657,"children":6658},{"style":136},[6659],{"type":21,"value":277},{"type":15,"tag":113,"props":6661,"children":6662},{"style":147},[6663],{"type":21,"value":1892},{"type":15,"tag":113,"props":6665,"children":6666},{"style":130},[6667],{"type":21,"value":6668},"^",{"type":15,"tag":113,"props":6670,"children":6672},{"style":6671},"--shiki-default:#22863A;--shiki-default-font-weight:bold;--shiki-dark:#85E89D;--shiki-dark-font-weight:bold",[6673],{"type":21,"value":6674},"\\\u002F",{"type":15,"tag":113,"props":6676,"children":6678},{"style":6677},"--shiki-default:#032F62;--shiki-dark:#DBEDFF",[6679],{"type":21,"value":6680},"api",{"type":15,"tag":113,"props":6682,"children":6683},{"style":147},[6684],{"type":21,"value":1892},{"type":15,"tag":113,"props":6686,"children":6687},{"style":136},[6688],{"type":21,"value":747},{"type":15,"tag":113,"props":6690,"children":6691},{"style":147},[6692],{"type":21,"value":6693},"\"\"",{"type":15,"tag":113,"props":6695,"children":6696},{"style":136},[6697],{"type":21,"value":370},{"type":15,"tag":113,"props":6699,"children":6700},{"class":115,"line":239},[6701],{"type":15,"tag":113,"props":6702,"children":6703},{"style":136},[6704],{"type":21,"value":1286},{"type":15,"tag":113,"props":6706,"children":6707},{"class":115,"line":248},[6708],{"type":15,"tag":113,"props":6709,"children":6710},{"style":136},[6711],{"type":21,"value":2040},{"type":15,"tag":113,"props":6713,"children":6714},{"class":115,"line":256},[6715],{"type":15,"tag":113,"props":6716,"children":6717},{"style":136},[6718],{"type":21,"value":967},{"type":15,"tag":113,"props":6720,"children":6721},{"class":115,"line":300},[6722],{"type":15,"tag":113,"props":6723,"children":6724},{"style":136},[6725],{"type":21,"value":6026},{"type":15,"tag":23,"props":6727,"children":6728},{},[6729],{"type":15,"tag":29,"props":6730,"children":6731},{},[6732,6734,6740],{"type":21,"value":6733},"FastAPI CORS (",{"type":15,"tag":80,"props":6735,"children":6737},{"className":6736},[],[6738],{"type":21,"value":6739},"backend\u002Fapp\u002Fmain.py",{"type":21,"value":757},{"type":15,"tag":103,"props":6742,"children":6744},{"code":6743,"language":5024,"meta":7,"className":5190,"style":7},"from fastapi import FastAPI\nfrom fastapi.middleware.cors import CORSMiddleware\n\napp = FastAPI()\napp.add_middleware(CORSMiddleware, allow_origins=[\"*\"], allow_credentials=True,\n                   allow_methods=[\"*\"], allow_headers=[\"*\"])\n",[6745],{"type":15,"tag":80,"props":6746,"children":6747},{"__ignoreMap":7},[6748,6768,6789,6796,6813,6862],{"type":15,"tag":113,"props":6749,"children":6750},{"class":115,"line":116},[6751,6755,6759,6763],{"type":15,"tag":113,"props":6752,"children":6753},{"style":130},[6754],{"type":21,"value":144},{"type":15,"tag":113,"props":6756,"children":6757},{"style":136},[6758],{"type":21,"value":5458},{"type":15,"tag":113,"props":6760,"children":6761},{"style":130},[6762],{"type":21,"value":133},{"type":15,"tag":113,"props":6764,"children":6765},{"style":136},[6766],{"type":21,"value":6767}," FastAPI\n",{"type":15,"tag":113,"props":6769,"children":6770},{"class":115,"line":126},[6771,6775,6780,6784],{"type":15,"tag":113,"props":6772,"children":6773},{"style":130},[6774],{"type":21,"value":144},{"type":15,"tag":113,"props":6776,"children":6777},{"style":136},[6778],{"type":21,"value":6779}," fastapi.middleware.cors ",{"type":15,"tag":113,"props":6781,"children":6782},{"style":130},[6783],{"type":21,"value":133},{"type":15,"tag":113,"props":6785,"children":6786},{"style":136},[6787],{"type":21,"value":6788}," CORSMiddleware\n",{"type":15,"tag":113,"props":6790,"children":6791},{"class":115,"line":153},[6792],{"type":15,"tag":113,"props":6793,"children":6794},{"emptyLinePlaceholder":157},[6795],{"type":21,"value":160},{"type":15,"tag":113,"props":6797,"children":6798},{"class":115,"line":163},[6799,6804,6808],{"type":15,"tag":113,"props":6800,"children":6801},{"style":136},[6802],{"type":21,"value":6803},"app ",{"type":15,"tag":113,"props":6805,"children":6806},{"style":130},[6807],{"type":21,"value":628},{"type":15,"tag":113,"props":6809,"children":6810},{"style":136},[6811],{"type":21,"value":6812}," FastAPI()\n",{"type":15,"tag":113,"props":6814,"children":6815},{"class":115,"line":183},[6816,6821,6826,6830,6834,6839,6844,6849,6853,6858],{"type":15,"tag":113,"props":6817,"children":6818},{"style":136},[6819],{"type":21,"value":6820},"app.add_middleware(CORSMiddleware, ",{"type":15,"tag":113,"props":6822,"children":6823},{"style":187},[6824],{"type":21,"value":6825},"allow_origins",{"type":15,"tag":113,"props":6827,"children":6828},{"style":130},[6829],{"type":21,"value":628},{"type":15,"tag":113,"props":6831,"children":6832},{"style":136},[6833],{"type":21,"value":5565},{"type":15,"tag":113,"props":6835,"children":6836},{"style":147},[6837],{"type":21,"value":6838},"\"*\"",{"type":15,"tag":113,"props":6840,"children":6841},{"style":136},[6842],{"type":21,"value":6843},"], ",{"type":15,"tag":113,"props":6845,"children":6846},{"style":187},[6847],{"type":21,"value":6848},"allow_credentials",{"type":15,"tag":113,"props":6850,"children":6851},{"style":130},[6852],{"type":21,"value":628},{"type":15,"tag":113,"props":6854,"children":6855},{"style":198},[6856],{"type":21,"value":6857},"True",{"type":15,"tag":113,"props":6859,"children":6860},{"style":136},[6861],{"type":21,"value":767},{"type":15,"tag":113,"props":6863,"children":6864},{"class":115,"line":204},[6865,6870,6874,6878,6882,6886,6891,6895,6899,6903],{"type":15,"tag":113,"props":6866,"children":6867},{"style":187},[6868],{"type":21,"value":6869},"                   allow_methods",{"type":15,"tag":113,"props":6871,"children":6872},{"style":130},[6873],{"type":21,"value":628},{"type":15,"tag":113,"props":6875,"children":6876},{"style":136},[6877],{"type":21,"value":5565},{"type":15,"tag":113,"props":6879,"children":6880},{"style":147},[6881],{"type":21,"value":6838},{"type":15,"tag":113,"props":6883,"children":6884},{"style":136},[6885],{"type":21,"value":6843},{"type":15,"tag":113,"props":6887,"children":6888},{"style":187},[6889],{"type":21,"value":6890},"allow_headers",{"type":15,"tag":113,"props":6892,"children":6893},{"style":130},[6894],{"type":21,"value":628},{"type":15,"tag":113,"props":6896,"children":6897},{"style":136},[6898],{"type":21,"value":5565},{"type":15,"tag":113,"props":6900,"children":6901},{"style":147},[6902],{"type":21,"value":6838},{"type":15,"tag":113,"props":6904,"children":6905},{"style":136},[6906],{"type":21,"value":5575},{"type":15,"tag":56,"props":6908,"children":6910},{"id":6909},"_5-docker-compose-编排与-nginx",[6911],{"type":21,"value":6912},"5. Docker Compose 编排与 Nginx",{"type":15,"tag":103,"props":6914,"children":6918},{"code":6915,"language":6916,"meta":7,"className":6917,"style":7},"# docker-compose.yml\nservices:\n  backend:\n    build: .\u002Fbackend\n    command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload\n    volumes: [.\u002Fbackend:\u002Fapp]\n  frontend:\n    build: .\u002Ffrontend\n    command: npm run dev -- --host\n    volumes: [.\u002Ffrontend:\u002Fapp, \u002Fapp\u002Fnode_modules]\n    ports: [\"5173:5173\"]\n  nginx:\n    image: nginx:alpine\n    ports: [\"80:80\"]\n    volumes: [\".\u002Fnginx.conf:\u002Fetc\u002Fnginx\u002Fconf.d\u002Fdefault.conf:ro\"]\n    depends_on: [backend, frontend]\n","yaml","language-yaml shiki shiki-themes github-light github-dark",[6919],{"type":15,"tag":80,"props":6920,"children":6921},{"__ignoreMap":7},[6922,6930,6942,6954,6971,6988,7011,7023,7039,7055,7084,7105,7117,7134,7154,7174],{"type":15,"tag":113,"props":6923,"children":6924},{"class":115,"line":116},[6925],{"type":15,"tag":113,"props":6926,"children":6927},{"style":120},[6928],{"type":21,"value":6929},"# docker-compose.yml\n",{"type":15,"tag":113,"props":6931,"children":6932},{"class":115,"line":126},[6933,6938],{"type":15,"tag":113,"props":6934,"children":6935},{"style":2257},[6936],{"type":21,"value":6937},"services",{"type":15,"tag":113,"props":6939,"children":6940},{"style":136},[6941],{"type":21,"value":5725},{"type":15,"tag":113,"props":6943,"children":6944},{"class":115,"line":153},[6945,6950],{"type":15,"tag":113,"props":6946,"children":6947},{"style":2257},[6948],{"type":21,"value":6949},"  backend",{"type":15,"tag":113,"props":6951,"children":6952},{"style":136},[6953],{"type":21,"value":5725},{"type":15,"tag":113,"props":6955,"children":6956},{"class":115,"line":163},[6957,6962,6966],{"type":15,"tag":113,"props":6958,"children":6959},{"style":2257},[6960],{"type":21,"value":6961},"    build",{"type":15,"tag":113,"props":6963,"children":6964},{"style":136},[6965],{"type":21,"value":6636},{"type":15,"tag":113,"props":6967,"children":6968},{"style":147},[6969],{"type":21,"value":6970},".\u002Fbackend\n",{"type":15,"tag":113,"props":6972,"children":6973},{"class":115,"line":183},[6974,6979,6983],{"type":15,"tag":113,"props":6975,"children":6976},{"style":2257},[6977],{"type":21,"value":6978},"    command",{"type":15,"tag":113,"props":6980,"children":6981},{"style":136},[6982],{"type":21,"value":6636},{"type":15,"tag":113,"props":6984,"children":6985},{"style":147},[6986],{"type":21,"value":6987},"uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload\n",{"type":15,"tag":113,"props":6989,"children":6990},{"class":115,"line":204},[6991,6996,7001,7006],{"type":15,"tag":113,"props":6992,"children":6993},{"style":2257},[6994],{"type":21,"value":6995},"    volumes",{"type":15,"tag":113,"props":6997,"children":6998},{"style":136},[6999],{"type":21,"value":7000},": [",{"type":15,"tag":113,"props":7002,"children":7003},{"style":147},[7004],{"type":21,"value":7005},".\u002Fbackend:\u002Fapp",{"type":15,"tag":113,"props":7007,"children":7008},{"style":136},[7009],{"type":21,"value":7010},"]\n",{"type":15,"tag":113,"props":7012,"children":7013},{"class":115,"line":221},[7014,7019],{"type":15,"tag":113,"props":7015,"children":7016},{"style":2257},[7017],{"type":21,"value":7018},"  frontend",{"type":15,"tag":113,"props":7020,"children":7021},{"style":136},[7022],{"type":21,"value":5725},{"type":15,"tag":113,"props":7024,"children":7025},{"class":115,"line":239},[7026,7030,7034],{"type":15,"tag":113,"props":7027,"children":7028},{"style":2257},[7029],{"type":21,"value":6961},{"type":15,"tag":113,"props":7031,"children":7032},{"style":136},[7033],{"type":21,"value":6636},{"type":15,"tag":113,"props":7035,"children":7036},{"style":147},[7037],{"type":21,"value":7038},".\u002Ffrontend\n",{"type":15,"tag":113,"props":7040,"children":7041},{"class":115,"line":248},[7042,7046,7050],{"type":15,"tag":113,"props":7043,"children":7044},{"style":2257},[7045],{"type":21,"value":6978},{"type":15,"tag":113,"props":7047,"children":7048},{"style":136},[7049],{"type":21,"value":6636},{"type":15,"tag":113,"props":7051,"children":7052},{"style":147},[7053],{"type":21,"value":7054},"npm run dev -- --host\n",{"type":15,"tag":113,"props":7056,"children":7057},{"class":115,"line":256},[7058,7062,7066,7071,7075,7080],{"type":15,"tag":113,"props":7059,"children":7060},{"style":2257},[7061],{"type":21,"value":6995},{"type":15,"tag":113,"props":7063,"children":7064},{"style":136},[7065],{"type":21,"value":7000},{"type":15,"tag":113,"props":7067,"children":7068},{"style":147},[7069],{"type":21,"value":7070},".\u002Ffrontend:\u002Fapp",{"type":15,"tag":113,"props":7072,"children":7073},{"style":136},[7074],{"type":21,"value":747},{"type":15,"tag":113,"props":7076,"children":7077},{"style":147},[7078],{"type":21,"value":7079},"\u002Fapp\u002Fnode_modules",{"type":15,"tag":113,"props":7081,"children":7082},{"style":136},[7083],{"type":21,"value":7010},{"type":15,"tag":113,"props":7085,"children":7086},{"class":115,"line":300},[7087,7092,7096,7101],{"type":15,"tag":113,"props":7088,"children":7089},{"style":2257},[7090],{"type":21,"value":7091},"    ports",{"type":15,"tag":113,"props":7093,"children":7094},{"style":136},[7095],{"type":21,"value":7000},{"type":15,"tag":113,"props":7097,"children":7098},{"style":147},[7099],{"type":21,"value":7100},"\"5173:5173\"",{"type":15,"tag":113,"props":7102,"children":7103},{"style":136},[7104],{"type":21,"value":7010},{"type":15,"tag":113,"props":7106,"children":7107},{"class":115,"line":338},[7108,7113],{"type":15,"tag":113,"props":7109,"children":7110},{"style":2257},[7111],{"type":21,"value":7112},"  nginx",{"type":15,"tag":113,"props":7114,"children":7115},{"style":136},[7116],{"type":21,"value":5725},{"type":15,"tag":113,"props":7118,"children":7119},{"class":115,"line":373},[7120,7125,7129],{"type":15,"tag":113,"props":7121,"children":7122},{"style":2257},[7123],{"type":21,"value":7124},"    image",{"type":15,"tag":113,"props":7126,"children":7127},{"style":136},[7128],{"type":21,"value":6636},{"type":15,"tag":113,"props":7130,"children":7131},{"style":147},[7132],{"type":21,"value":7133},"nginx:alpine\n",{"type":15,"tag":113,"props":7135,"children":7136},{"class":115,"line":415},[7137,7141,7145,7150],{"type":15,"tag":113,"props":7138,"children":7139},{"style":2257},[7140],{"type":21,"value":7091},{"type":15,"tag":113,"props":7142,"children":7143},{"style":136},[7144],{"type":21,"value":7000},{"type":15,"tag":113,"props":7146,"children":7147},{"style":147},[7148],{"type":21,"value":7149},"\"80:80\"",{"type":15,"tag":113,"props":7151,"children":7152},{"style":136},[7153],{"type":21,"value":7010},{"type":15,"tag":113,"props":7155,"children":7156},{"class":115,"line":423},[7157,7161,7165,7170],{"type":15,"tag":113,"props":7158,"children":7159},{"style":2257},[7160],{"type":21,"value":6995},{"type":15,"tag":113,"props":7162,"children":7163},{"style":136},[7164],{"type":21,"value":7000},{"type":15,"tag":113,"props":7166,"children":7167},{"style":147},[7168],{"type":21,"value":7169},"\".\u002Fnginx.conf:\u002Fetc\u002Fnginx\u002Fconf.d\u002Fdefault.conf:ro\"",{"type":15,"tag":113,"props":7171,"children":7172},{"style":136},[7173],{"type":21,"value":7010},{"type":15,"tag":113,"props":7175,"children":7176},{"class":115,"line":454},[7177,7182,7186,7191,7195,7200],{"type":15,"tag":113,"props":7178,"children":7179},{"style":2257},[7180],{"type":21,"value":7181},"    depends_on",{"type":15,"tag":113,"props":7183,"children":7184},{"style":136},[7185],{"type":21,"value":7000},{"type":15,"tag":113,"props":7187,"children":7188},{"style":147},[7189],{"type":21,"value":7190},"backend",{"type":15,"tag":113,"props":7192,"children":7193},{"style":136},[7194],{"type":21,"value":747},{"type":15,"tag":113,"props":7196,"children":7197},{"style":147},[7198],{"type":21,"value":7199},"frontend",{"type":15,"tag":113,"props":7201,"children":7202},{"style":136},[7203],{"type":21,"value":7010},{"type":15,"tag":103,"props":7205,"children":7209},{"code":7206,"language":7207,"meta":7,"className":7208,"style":7},"# nginx.conf\nserver {\n  listen 80;\n  location \u002F {\n    proxy_pass http:\u002F\u002Ffrontend:5173;\n  }\n  location \u002Fapi\u002F {\n    proxy_pass http:\u002F\u002Fbackend:8000\u002Fapi\u002F;\n    proxy_set_header Host $host;\n  }\n}\n","nginx","language-nginx shiki shiki-themes github-light github-dark",[7210],{"type":15,"tag":80,"props":7211,"children":7212},{"__ignoreMap":7},[7213,7221,7233,7251,7269,7282,7289,7305,7317,7330,7337],{"type":15,"tag":113,"props":7214,"children":7215},{"class":115,"line":116},[7216],{"type":15,"tag":113,"props":7217,"children":7218},{"style":120},[7219],{"type":21,"value":7220},"# nginx.conf\n",{"type":15,"tag":113,"props":7222,"children":7223},{"class":115,"line":126},[7224,7229],{"type":15,"tag":113,"props":7225,"children":7226},{"style":130},[7227],{"type":21,"value":7228},"server",{"type":15,"tag":113,"props":7230,"children":7231},{"style":136},[7232],{"type":21,"value":180},{"type":15,"tag":113,"props":7234,"children":7235},{"class":115,"line":153},[7236,7241,7246],{"type":15,"tag":113,"props":7237,"children":7238},{"style":130},[7239],{"type":21,"value":7240},"  listen ",{"type":15,"tag":113,"props":7242,"children":7243},{"style":198},[7244],{"type":21,"value":7245},"80",{"type":15,"tag":113,"props":7247,"children":7248},{"style":136},[7249],{"type":21,"value":7250},";\n",{"type":15,"tag":113,"props":7252,"children":7253},{"class":115,"line":163},[7254,7259,7264],{"type":15,"tag":113,"props":7255,"children":7256},{"style":130},[7257],{"type":21,"value":7258},"  location",{"type":15,"tag":113,"props":7260,"children":7261},{"style":172},[7262],{"type":21,"value":7263}," \u002F ",{"type":15,"tag":113,"props":7265,"children":7266},{"style":136},[7267],{"type":21,"value":7268},"{\n",{"type":15,"tag":113,"props":7270,"children":7271},{"class":115,"line":183},[7272,7277],{"type":15,"tag":113,"props":7273,"children":7274},{"style":130},[7275],{"type":21,"value":7276},"    proxy_pass ",{"type":15,"tag":113,"props":7278,"children":7279},{"style":136},[7280],{"type":21,"value":7281},"http:\u002F\u002Ffrontend:5173;\n",{"type":15,"tag":113,"props":7283,"children":7284},{"class":115,"line":204},[7285],{"type":15,"tag":113,"props":7286,"children":7287},{"style":136},[7288],{"type":21,"value":967},{"type":15,"tag":113,"props":7290,"children":7291},{"class":115,"line":221},[7292,7296,7301],{"type":15,"tag":113,"props":7293,"children":7294},{"style":130},[7295],{"type":21,"value":7258},{"type":15,"tag":113,"props":7297,"children":7298},{"style":172},[7299],{"type":21,"value":7300}," \u002Fapi\u002F ",{"type":15,"tag":113,"props":7302,"children":7303},{"style":136},[7304],{"type":21,"value":7268},{"type":15,"tag":113,"props":7306,"children":7307},{"class":115,"line":239},[7308,7312],{"type":15,"tag":113,"props":7309,"children":7310},{"style":130},[7311],{"type":21,"value":7276},{"type":15,"tag":113,"props":7313,"children":7314},{"style":136},[7315],{"type":21,"value":7316},"http:\u002F\u002Fbackend:8000\u002Fapi\u002F;\n",{"type":15,"tag":113,"props":7318,"children":7319},{"class":115,"line":248},[7320,7325],{"type":15,"tag":113,"props":7321,"children":7322},{"style":130},[7323],{"type":21,"value":7324},"    proxy_set_header ",{"type":15,"tag":113,"props":7326,"children":7327},{"style":136},[7328],{"type":21,"value":7329},"Host $host;\n",{"type":15,"tag":113,"props":7331,"children":7332},{"class":115,"line":256},[7333],{"type":15,"tag":113,"props":7334,"children":7335},{"style":136},[7336],{"type":21,"value":967},{"type":15,"tag":113,"props":7338,"children":7339},{"class":115,"line":300},[7340],{"type":15,"tag":113,"props":7341,"children":7342},{"style":136},[7343],{"type":21,"value":245},{"type":15,"tag":23,"props":7345,"children":7346},{},[7347],{"type":15,"tag":29,"props":7348,"children":7349},{},[7350],{"type":21,"value":7351},"启动",{"type":15,"tag":103,"props":7353,"children":7355},{"code":7354,"language":5003,"meta":7,"className":5004,"style":7},"docker compose up -d\n# 访问 http:\u002F\u002Flocalhost\n",[7356],{"type":15,"tag":80,"props":7357,"children":7358},{"__ignoreMap":7},[7359,7382],{"type":15,"tag":113,"props":7360,"children":7361},{"class":115,"line":116},[7362,7367,7372,7377],{"type":15,"tag":113,"props":7363,"children":7364},{"style":172},[7365],{"type":21,"value":7366},"docker",{"type":15,"tag":113,"props":7368,"children":7369},{"style":147},[7370],{"type":21,"value":7371}," compose",{"type":15,"tag":113,"props":7373,"children":7374},{"style":147},[7375],{"type":21,"value":7376}," up",{"type":15,"tag":113,"props":7378,"children":7379},{"style":198},[7380],{"type":21,"value":7381}," -d\n",{"type":15,"tag":113,"props":7383,"children":7384},{"class":115,"line":126},[7385],{"type":15,"tag":113,"props":7386,"children":7387},{"style":120},[7388],{"type":21,"value":7389},"# 访问 http:\u002F\u002Flocalhost\n",{"type":15,"tag":2343,"props":7391,"children":7392},{},[7393],{"type":21,"value":2654},{"title":7,"searchDepth":126,"depth":126,"links":7395},[7396,7397,7398,7399,7400],{"id":4980,"depth":126,"text":4983},{"id":5183,"depth":126,"text":5186},{"id":5791,"depth":126,"text":5794},{"id":6515,"depth":126,"text":6518},{"id":6909,"depth":126,"text":6912},"content:blog:2-post.md","blog\u002F2-post.md","blog\u002F2-post",{"_path":7405,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":7406,"description":7407,"date":7408,"code":7409,"body":7410,"_type":2666,"_id":7455,"_source":2668,"_file":7456,"_stem":7457,"_extension":2671},"\u002Fblog\u002Ffirst-post","开始使用 Nuxt 4 重构博客","记录从旧项目迁移到 Nuxt 4 的过程与心得。","2026-05-06","D4E5F7",{"type":12,"children":7411,"toc":7452},[7412,7418,7423,7428],{"type":15,"tag":16,"props":7413,"children":7415},{"id":7414},"你好nuxt-4",[7416],{"type":21,"value":7417},"你好，Nuxt 4",{"type":15,"tag":23,"props":7419,"children":7420},{},[7421],{"type":21,"value":7422},"这是第一篇测试文章。Nuxt 4 带来了更清晰的目录结构和更好的性能。",{"type":15,"tag":56,"props":7424,"children":7426},{"id":7425},"主要变化",[7427],{"type":21,"value":7425},{"type":15,"tag":2585,"props":7429,"children":7430},{},[7431,7442,7447],{"type":15,"tag":2532,"props":7432,"children":7433},{},[7434,7440],{"type":15,"tag":80,"props":7435,"children":7437},{"className":7436},[],[7438],{"type":21,"value":7439},"app\u002F",{"type":21,"value":7441}," 目录成为默认应用代码存放处",{"type":15,"tag":2532,"props":7443,"children":7444},{},[7445],{"type":21,"value":7446},"更高效的构建工具链",{"type":15,"tag":2532,"props":7448,"children":7449},{},[7450],{"type":21,"value":7451},"...",{"title":7,"searchDepth":126,"depth":126,"links":7453},[7454],{"id":7425,"depth":126,"text":7425},"content:blog:first-post.md","blog\u002Ffirst-post.md","blog\u002Ffirst-post",1784099949734]