[{"data":1,"prerenderedAt":4588},["ShallowReactive",2],{"page-\u002Fvue\u002Fnuxt\u002Fnuxt和vuetify":3},{"id":4,"title":5,"body":6,"description":4581,"extension":4582,"meta":4583,"navigation":131,"path":4584,"seo":4585,"stem":4586,"__hash__":4587},"content\u002FVue\u002FNuxt\u002Fnuxt和vuetify.md","Nuxt和vuetify",{"type":7,"value":8,"toc":4516},"minimark",[9,21,29,41,49,192,201,242,249,255,414,425,431,437,445,451,456,463,609,615,621,693,699,702,709,818,824,827,833,1071,1080,1206,1213,1309,1321,1324,1333,1336,1416,1419,1571,1578,1583,1586,1589,1592,1595,1598,1601,1607,1610,1636,1639,1717,1720,1723,1726,1729,1735,1738,1758,1761,1880,1883,1886,2086,2092,2096,2099,2106,2188,2191,2195,2202,2219,2227,2233,2238,2356,2374,2377,2380,2448,2451,2475,2478,2481,2487,2490,2493,2496,2499,2502,2562,2566,2577,2603,2607,2627,2630,2738,2741,2747,2750,2754,2757,2763,2766,2769,2772,2775,2781,2784,2790,2793,2800,3003,3013,3019,3022,3031,3038,3060,3067,3093,3100,3121,3128,3142,3149,3174,3178,3204,3210,3213,3220,3231,3238,3415,3422,3444,3451,3491,3497,3500,3507,3510,3587,3593,3644,3650,3668,3671,3741,3747,3786,3789,3793,3798,3802,3931,3935,3970,3973,3988,3994,4000,4006,4026,4034,4040,4046,4059,4062,4065,4078,4084,4093,4134,4143,4216,4220,4229,4277,4280,4283,4286,4292,4310,4316,4319,4322,4332,4335,4513],[10,11,12,16,17,20],"p",{},[13,14,15],"strong",{},"Nuxt 项目","和传统的",[13,18,19],{},"约定优于配置","的理念，大大简化了项目结构",[22,23,25,26],"h3",{"id":24},"nuxt-项目的入口文件差异","🚀 ",[13,27,28],{},"Nuxt 项目的入口文件差异：",[10,30,31,32,36,37,40],{},"在 Vue 3 项目中，我们习惯有一个明确的 ",[33,34,35],"code",{},"main.ts","（",[33,38,39],{},"main.js","），通常这样写：",[10,42,43],{},[13,44,45,46,48],{},"Vue 3 项目 ",[33,47,35],{},"：",[50,51,56],"pre",{"className":52,"code":53,"language":54,"meta":55,"style":55},"language-ts shiki shiki-themes github-light github-dark","import { createApp } from 'vue';\nimport App from '.\u002FApp.vue';\nimport router from '.\u002Frouter';\nimport store from '.\u002Fstore';\n\nconst app = createApp(App);\napp.use(router);\napp.use(store);\napp.mount('#app');\n\n","ts","",[33,57,58,81,96,111,126,133,153,165,175],{"__ignoreMap":55},[59,60,63,67,71,74,78],"span",{"class":61,"line":62},"line",1,[59,64,66],{"class":65},"szBVR","import",[59,68,70],{"class":69},"sVt8B"," { createApp } ",[59,72,73],{"class":65},"from",[59,75,77],{"class":76},"sZZnC"," 'vue'",[59,79,80],{"class":69},";\n",[59,82,84,86,89,91,94],{"class":61,"line":83},2,[59,85,66],{"class":65},[59,87,88],{"class":69}," App ",[59,90,73],{"class":65},[59,92,93],{"class":76}," '.\u002FApp.vue'",[59,95,80],{"class":69},[59,97,99,101,104,106,109],{"class":61,"line":98},3,[59,100,66],{"class":65},[59,102,103],{"class":69}," router ",[59,105,73],{"class":65},[59,107,108],{"class":76}," '.\u002Frouter'",[59,110,80],{"class":69},[59,112,114,116,119,121,124],{"class":61,"line":113},4,[59,115,66],{"class":65},[59,117,118],{"class":69}," store ",[59,120,73],{"class":65},[59,122,123],{"class":76}," '.\u002Fstore'",[59,125,80],{"class":69},[59,127,129],{"class":61,"line":128},5,[59,130,132],{"emptyLinePlaceholder":131},true,"\n",[59,134,136,139,143,146,150],{"class":61,"line":135},6,[59,137,138],{"class":65},"const",[59,140,142],{"class":141},"sj4cs"," app",[59,144,145],{"class":65}," =",[59,147,149],{"class":148},"sScJk"," createApp",[59,151,152],{"class":69},"(App);\n",[59,154,156,159,162],{"class":61,"line":155},7,[59,157,158],{"class":69},"app.",[59,160,161],{"class":148},"use",[59,163,164],{"class":69},"(router);\n",[59,166,168,170,172],{"class":61,"line":167},8,[59,169,158],{"class":69},[59,171,161],{"class":148},[59,173,174],{"class":69},"(store);\n",[59,176,178,180,183,186,189],{"class":61,"line":177},9,[59,179,158],{"class":69},[59,181,182],{"class":148},"mount",[59,184,185],{"class":69},"(",[59,187,188],{"class":76},"'#app'",[59,190,191],{"class":69},");\n",[10,193,194,197,198,200],{},[13,195,196],{},"而在 Nuxt 项目"," 中，没有",[33,199,35],{},"，因为 Nuxt 已经帮你处理了大部分",[202,203,204,211,221,230,236],"ul",{},[205,206,207,210],"li",{},[13,208,209],{},"应用创建","：N",[205,212,213,216,217,220],{},[13,214,215],{},"路由初始化","：基于 ",[33,218,219],{},"pages\u002F"," 目录生成路由。",[205,222,223,48,226,229],{},[13,224,225],{},"插件注册",[33,227,228],{},"plugins\u002F"," 目录来扩展功能。",[205,231,232,235],{},[13,233,234],{},"状态管理","：集成 Pinia（Nuxt 3）",[205,237,238,241],{},[13,239,240],{},"中间件、布局、SEO 等功能","，全部由 Nuxt 自动处理",[22,243,245,246],{"id":244},"nuxt-的等效入口机制","🌟 *",[13,247,248],{},"Nuxt 的等效入口机制",[10,250,251,252,254],{},"虽然没有 ",[33,253,35],{},"，但你可以通过以下",[256,257,258,268,342,400],"ol",{},[205,259,260,263,264,267],{},[13,261,262],{},"app.vue","\n这个是 Nuxt 应用的根组件，相当于 Vue 项目的 ",[33,265,266],{},"App.vue","。你可以在这里进行全局布局、页面切换动画等逻辑。",[205,269,270,273,274,277,283,335,337,338,341],{},[13,271,272],{},"plugins 目录","\n如果你想在项目启动",[275,276],"br",{},[13,278,279,280],{},"示例：",[33,281,282],{},"plugins\u002Fmy-plugin.ts",[50,284,286],{"className":52,"code":285,"language":54,"meta":55,"style":55},"export default defineNuxtPlugin((nuxtApp) => {\n  console.log('Nuxt app is ready!');\n});\n",[33,287,288,315,330],{"__ignoreMap":55},[59,289,290,293,296,299,302,306,309,312],{"class":61,"line":62},[59,291,292],{"class":65},"export",[59,294,295],{"class":65}," default",[59,297,298],{"class":148}," defineNuxtPlugin",[59,300,301],{"class":69},"((",[59,303,305],{"class":304},"s4XuR","nuxtApp",[59,307,308],{"class":69},") ",[59,310,311],{"class":65},"=>",[59,313,314],{"class":69}," {\n",[59,316,317,320,323,325,328],{"class":61,"line":83},[59,318,319],{"class":69},"  console.",[59,321,322],{"class":148},"log",[59,324,185],{"class":69},[59,326,327],{"class":76},"'Nuxt app is ready!'",[59,329,191],{"class":69},[59,331,332],{"class":61,"line":98},[59,333,334],{"class":69},"});\n",[275,336],{},"Nuxt 会自动在启动时加载 ",[33,339,340],{},"plugins"," 目录",[205,343,344,347,348,351,352],{},[13,345,346],{},"nuxt.config.ts","\n类似",[33,349,350],{},"vue.config.js","，这里是 Nuxt 的全局配置文件。你",[50,353,355],{"className":52,"code":354,"language":54,"meta":55,"style":55},"\u002F\u002F nuxt.config.ts\nexport default defineNuxtConfig({\n  modules: ['@pinia\u002Fnuxt'],\n  plugins: ['~\u002Fplugins\u002Fmy-plugin.ts'],\n});\n",[33,356,357,363,375,386,396],{"__ignoreMap":55},[59,358,359],{"class":61,"line":62},[59,360,362],{"class":361},"sJ8bj","\u002F\u002F nuxt.config.ts\n",[59,364,365,367,369,372],{"class":61,"line":83},[59,366,292],{"class":65},[59,368,295],{"class":65},[59,370,371],{"class":148}," defineNuxtConfig",[59,373,374],{"class":69},"({\n",[59,376,377,380,383],{"class":61,"line":98},[59,378,379],{"class":69},"  modules: [",[59,381,382],{"class":76},"'@pinia\u002Fnuxt'",[59,384,385],{"class":69},"],\n",[59,387,388,391,394],{"class":61,"line":113},[59,389,390],{"class":69},"  plugins: [",[59,392,393],{"class":76},"'~\u002Fplugins\u002Fmy-plugin.ts'",[59,395,385],{"class":69},[59,397,398],{"class":61,"line":128},[59,399,334],{"class":69},[205,401,402,405,406,409,410,413],{},[13,403,404],{},"中间件和生命周期钩子","\n你还可以在页面级别使用 ",[33,407,408],{},"onMounted"," 等 Vue 生命周期钩子，或者 Nuxt 的专有钩子如 ",[33,411,412],{},"onNuxtReady"," 来控制项目的初始化逻辑。",[10,415,416,417,420,421,424],{},"在 ",[13,418,419],{},"Nuxt 3"," 项目中集成 ",[13,422,423],{},"Vuetify"," 非常直接，我们一步步来搞定！💪",[22,426,25,428],{"id":427},"nuxt-3-安装-vuetify",[13,429,430],{},"Nuxt 3 安装 Vuetify",[10,432,433,434],{},"1️⃣ ",[13,435,436],{},"安装 Vuetify 和相关依赖：",[50,438,443],{"className":439,"code":441,"language":442},[440],"language-text","bash复制编辑# 安装 Vuetify 及其 peer 依赖\nnpm install vuetify @mdi\u002Ffont sass\n","text",[33,444,441],{"__ignoreMap":55},[10,446,447,448],{},"2️⃣ ",[13,449,450],{},"配置 Vuetify 插件：",[10,452,416,453,455],{},[33,454,228],{}," 目录下新建一个插件文件：",[10,457,458],{},[13,459,460],{},[33,461,462],{},"plugins\u002Fvuetify.ts",[50,464,466],{"className":52,"code":465,"language":54,"meta":55,"style":55},"\u002F\u002F plugins\u002Fvuetify.ts\nimport { createVuetify } from 'vuetify';\nimport * as components from 'vuetify\u002Fcomponents';\nimport * as directives from 'vuetify\u002Fdirectives';\nimport 'vuetify\u002Fstyles';\n\nexport default defineNuxtPlugin((nuxtApp) => {\n  const vuetify = createVuetify({\n    components,\n    directives,\n  });\n\n  nuxtApp.vueApp.use(vuetify);\n});\n",[33,467,468,473,487,507,525,534,538,556,571,576,582,588,593,604],{"__ignoreMap":55},[59,469,470],{"class":61,"line":62},[59,471,472],{"class":361},"\u002F\u002F plugins\u002Fvuetify.ts\n",[59,474,475,477,480,482,485],{"class":61,"line":83},[59,476,66],{"class":65},[59,478,479],{"class":69}," { createVuetify } ",[59,481,73],{"class":65},[59,483,484],{"class":76}," 'vuetify'",[59,486,80],{"class":69},[59,488,489,491,494,497,500,502,505],{"class":61,"line":98},[59,490,66],{"class":65},[59,492,493],{"class":141}," *",[59,495,496],{"class":65}," as",[59,498,499],{"class":69}," components ",[59,501,73],{"class":65},[59,503,504],{"class":76}," 'vuetify\u002Fcomponents'",[59,506,80],{"class":69},[59,508,509,511,513,515,518,520,523],{"class":61,"line":113},[59,510,66],{"class":65},[59,512,493],{"class":141},[59,514,496],{"class":65},[59,516,517],{"class":69}," directives ",[59,519,73],{"class":65},[59,521,522],{"class":76}," 'vuetify\u002Fdirectives'",[59,524,80],{"class":69},[59,526,527,529,532],{"class":61,"line":128},[59,528,66],{"class":65},[59,530,531],{"class":76}," 'vuetify\u002Fstyles'",[59,533,80],{"class":69},[59,535,536],{"class":61,"line":135},[59,537,132],{"emptyLinePlaceholder":131},[59,539,540,542,544,546,548,550,552,554],{"class":61,"line":155},[59,541,292],{"class":65},[59,543,295],{"class":65},[59,545,298],{"class":148},[59,547,301],{"class":69},[59,549,305],{"class":304},[59,551,308],{"class":69},[59,553,311],{"class":65},[59,555,314],{"class":69},[59,557,558,561,564,566,569],{"class":61,"line":167},[59,559,560],{"class":65},"  const",[59,562,563],{"class":141}," vuetify",[59,565,145],{"class":65},[59,567,568],{"class":148}," createVuetify",[59,570,374],{"class":69},[59,572,573],{"class":61,"line":177},[59,574,575],{"class":69},"    components,\n",[59,577,579],{"class":61,"line":578},10,[59,580,581],{"class":69},"    directives,\n",[59,583,585],{"class":61,"line":584},11,[59,586,587],{"class":69},"  });\n",[59,589,591],{"class":61,"line":590},12,[59,592,132],{"emptyLinePlaceholder":131},[59,594,596,599,601],{"class":61,"line":595},13,[59,597,598],{"class":69},"  nuxtApp.vueApp.",[59,600,161],{"class":148},[59,602,603],{"class":69},"(vuetify);\n",[59,605,607],{"class":61,"line":606},14,[59,608,334],{"class":69},[10,610,611,612],{},"3️⃣ ",[13,613,614],{},"注册插件：",[10,616,617,618,620],{},"打开 ",[33,619,346],{}," 并添加：",[50,622,624],{"className":52,"code":623,"language":54,"meta":55,"style":55},"\u002F\u002F nuxt.config.ts\nexport default defineNuxtConfig({\n  css: ['vuetify\u002Fstyles'], \u002F\u002F 引入全局样式\n  build: {\n    transpile: ['vuetify'], \u002F\u002F 确保编译 Vuetify\n  },\n  plugins: ['~\u002Fplugins\u002Fvuetify.ts'], \u002F\u002F 注册插件\n});\n",[33,625,626,630,640,654,659,672,677,689],{"__ignoreMap":55},[59,627,628],{"class":61,"line":62},[59,629,362],{"class":361},[59,631,632,634,636,638],{"class":61,"line":83},[59,633,292],{"class":65},[59,635,295],{"class":65},[59,637,371],{"class":148},[59,639,374],{"class":69},[59,641,642,645,648,651],{"class":61,"line":98},[59,643,644],{"class":69},"  css: [",[59,646,647],{"class":76},"'vuetify\u002Fstyles'",[59,649,650],{"class":69},"], ",[59,652,653],{"class":361},"\u002F\u002F 引入全局样式\n",[59,655,656],{"class":61,"line":113},[59,657,658],{"class":69},"  build: {\n",[59,660,661,664,667,669],{"class":61,"line":128},[59,662,663],{"class":69},"    transpile: [",[59,665,666],{"class":76},"'vuetify'",[59,668,650],{"class":69},[59,670,671],{"class":361},"\u002F\u002F 确保编译 Vuetify\n",[59,673,674],{"class":61,"line":135},[59,675,676],{"class":69},"  },\n",[59,678,679,681,684,686],{"class":61,"line":155},[59,680,390],{"class":69},[59,682,683],{"class":76},"'~\u002Fplugins\u002Fvuetify.ts'",[59,685,650],{"class":69},[59,687,688],{"class":361},"\u002F\u002F 注册插件\n",[59,690,691],{"class":61,"line":167},[59,692,334],{"class":69},[10,694,695,696],{},"4️⃣ ",[13,697,698],{},"使用组件：",[10,700,701],{},"现在你就可以在组件中直接使用 Vuetify 的组件啦！🌟",[10,703,704],{},[13,705,279,706],{},[33,707,708],{},"pages\u002Findex.vue",[50,710,714],{"className":711,"code":712,"language":713,"meta":55,"style":55},"language-vue shiki shiki-themes github-light github-dark","\u003Ctemplate>\n  \u003Cv-container>\n    \u003Cv-row>\n      \u003Cv-col>\n        \u003Cv-btn color=\"primary\">Hello Vuetify\u003C\u002Fv-btn>\n      \u003C\u002Fv-col>\n    \u003C\u002Fv-row>\n  \u003C\u002Fv-container>\n\u003C\u002Ftemplate>\n","vue",[33,715,716,728,738,748,758,782,791,800,809],{"__ignoreMap":55},[59,717,718,721,725],{"class":61,"line":62},[59,719,720],{"class":69},"\u003C",[59,722,724],{"class":723},"s9eBZ","template",[59,726,727],{"class":69},">\n",[59,729,730,733,736],{"class":61,"line":83},[59,731,732],{"class":69},"  \u003C",[59,734,735],{"class":723},"v-container",[59,737,727],{"class":69},[59,739,740,743,746],{"class":61,"line":98},[59,741,742],{"class":69},"    \u003C",[59,744,745],{"class":723},"v-row",[59,747,727],{"class":69},[59,749,750,753,756],{"class":61,"line":113},[59,751,752],{"class":69},"      \u003C",[59,754,755],{"class":723},"v-col",[59,757,727],{"class":69},[59,759,760,763,766,769,772,775,778,780],{"class":61,"line":128},[59,761,762],{"class":69},"        \u003C",[59,764,765],{"class":723},"v-btn",[59,767,768],{"class":148}," color",[59,770,771],{"class":69},"=",[59,773,774],{"class":76},"\"primary\"",[59,776,777],{"class":69},">Hello Vuetify\u003C\u002F",[59,779,765],{"class":723},[59,781,727],{"class":69},[59,783,784,787,789],{"class":61,"line":135},[59,785,786],{"class":69},"      \u003C\u002F",[59,788,755],{"class":723},[59,790,727],{"class":69},[59,792,793,796,798],{"class":61,"line":155},[59,794,795],{"class":69},"    \u003C\u002F",[59,797,745],{"class":723},[59,799,727],{"class":69},[59,801,802,805,807],{"class":61,"line":167},[59,803,804],{"class":69},"  \u003C\u002F",[59,806,735],{"class":723},[59,808,727],{"class":69},[59,810,811,814,816],{"class":61,"line":177},[59,812,813],{"class":69},"\u003C\u002F",[59,815,724],{"class":723},[59,817,727],{"class":69},[10,819,820,821],{},"5️⃣ ",[13,822,823],{},"可选：定制主题",[10,825,826],{},"如果你想定制主题，比如改颜色或者其他设置，可以在创建 Vuetify 实例时添加配置：",[10,828,829],{},[13,830,831],{},[33,832,462],{},[50,834,836],{"className":52,"code":835,"language":54,"meta":55,"style":55},"import { createVuetify } from 'vuetify';\nimport * as components from 'vuetify\u002Fcomponents';\nimport * as directives from 'vuetify\u002Fdirectives';\nimport 'vuetify\u002Fstyles';\n\nconst customTheme = {\n  dark: false,\n  colors: {\n    primary: '#4caf50',\n    secondary: '#ff9800',\n    accent: '#9c27b0',\n  },\n};\n\nexport default defineNuxtPlugin((nuxtApp) => {\n  const vuetify = createVuetify({\n    components,\n    directives,\n    theme: {\n      defaultTheme: 'customTheme',\n      themes: {\n        customTheme,\n      },\n    },\n  });\n\n  nuxtApp.vueApp.use(vuetify);\n});\n",[33,837,838,850,866,882,890,894,905,916,921,931,941,951,955,960,964,983,996,1001,1006,1012,1023,1029,1035,1041,1047,1052,1057,1066],{"__ignoreMap":55},[59,839,840,842,844,846,848],{"class":61,"line":62},[59,841,66],{"class":65},[59,843,479],{"class":69},[59,845,73],{"class":65},[59,847,484],{"class":76},[59,849,80],{"class":69},[59,851,852,854,856,858,860,862,864],{"class":61,"line":83},[59,853,66],{"class":65},[59,855,493],{"class":141},[59,857,496],{"class":65},[59,859,499],{"class":69},[59,861,73],{"class":65},[59,863,504],{"class":76},[59,865,80],{"class":69},[59,867,868,870,872,874,876,878,880],{"class":61,"line":98},[59,869,66],{"class":65},[59,871,493],{"class":141},[59,873,496],{"class":65},[59,875,517],{"class":69},[59,877,73],{"class":65},[59,879,522],{"class":76},[59,881,80],{"class":69},[59,883,884,886,888],{"class":61,"line":113},[59,885,66],{"class":65},[59,887,531],{"class":76},[59,889,80],{"class":69},[59,891,892],{"class":61,"line":128},[59,893,132],{"emptyLinePlaceholder":131},[59,895,896,898,901,903],{"class":61,"line":135},[59,897,138],{"class":65},[59,899,900],{"class":141}," customTheme",[59,902,145],{"class":65},[59,904,314],{"class":69},[59,906,907,910,913],{"class":61,"line":155},[59,908,909],{"class":69},"  dark: ",[59,911,912],{"class":141},"false",[59,914,915],{"class":69},",\n",[59,917,918],{"class":61,"line":167},[59,919,920],{"class":69},"  colors: {\n",[59,922,923,926,929],{"class":61,"line":177},[59,924,925],{"class":69},"    primary: ",[59,927,928],{"class":76},"'#4caf50'",[59,930,915],{"class":69},[59,932,933,936,939],{"class":61,"line":578},[59,934,935],{"class":69},"    secondary: ",[59,937,938],{"class":76},"'#ff9800'",[59,940,915],{"class":69},[59,942,943,946,949],{"class":61,"line":584},[59,944,945],{"class":69},"    accent: ",[59,947,948],{"class":76},"'#9c27b0'",[59,950,915],{"class":69},[59,952,953],{"class":61,"line":590},[59,954,676],{"class":69},[59,956,957],{"class":61,"line":595},[59,958,959],{"class":69},"};\n",[59,961,962],{"class":61,"line":606},[59,963,132],{"emptyLinePlaceholder":131},[59,965,967,969,971,973,975,977,979,981],{"class":61,"line":966},15,[59,968,292],{"class":65},[59,970,295],{"class":65},[59,972,298],{"class":148},[59,974,301],{"class":69},[59,976,305],{"class":304},[59,978,308],{"class":69},[59,980,311],{"class":65},[59,982,314],{"class":69},[59,984,986,988,990,992,994],{"class":61,"line":985},16,[59,987,560],{"class":65},[59,989,563],{"class":141},[59,991,145],{"class":65},[59,993,568],{"class":148},[59,995,374],{"class":69},[59,997,999],{"class":61,"line":998},17,[59,1000,575],{"class":69},[59,1002,1004],{"class":61,"line":1003},18,[59,1005,581],{"class":69},[59,1007,1009],{"class":61,"line":1008},19,[59,1010,1011],{"class":69},"    theme: {\n",[59,1013,1015,1018,1021],{"class":61,"line":1014},20,[59,1016,1017],{"class":69},"      defaultTheme: ",[59,1019,1020],{"class":76},"'customTheme'",[59,1022,915],{"class":69},[59,1024,1026],{"class":61,"line":1025},21,[59,1027,1028],{"class":69},"      themes: {\n",[59,1030,1032],{"class":61,"line":1031},22,[59,1033,1034],{"class":69},"        customTheme,\n",[59,1036,1038],{"class":61,"line":1037},23,[59,1039,1040],{"class":69},"      },\n",[59,1042,1044],{"class":61,"line":1043},24,[59,1045,1046],{"class":69},"    },\n",[59,1048,1050],{"class":61,"line":1049},25,[59,1051,587],{"class":69},[59,1053,1055],{"class":61,"line":1054},26,[59,1056,132],{"emptyLinePlaceholder":131},[59,1058,1060,1062,1064],{"class":61,"line":1059},27,[59,1061,598],{"class":69},[59,1063,161],{"class":148},[59,1065,603],{"class":69},[59,1067,1069],{"class":61,"line":1068},28,[59,1070,334],{"class":69},[22,1072,1074,1075],{"id":1073},"nuxtconfigts-配置项总结","🧑‍💻 ",[13,1076,1077,1079],{},[33,1078,346],{}," 配置项总结",[1081,1082,1083,1096],"table",{},[1084,1085,1086],"thead",{},[1087,1088,1089,1093],"tr",{},[1090,1091,1092],"th",{},"配置项",[1090,1094,1095],{},"描述",[1097,1098,1099,1114,1124,1133,1143,1153,1163,1173,1186,1196],"tbody",{},[1087,1100,1101,1107],{},[1102,1103,1104],"td",{},[33,1105,1106],{},"app",[1102,1108,1109,1110,1113],{},"配置应用的根级设置，如 ",[33,1111,1112],{},"\u003Chead>"," 信息等。",[1087,1115,1116,1121],{},[1102,1117,1118],{},[33,1119,1120],{},"css",[1102,1122,1123],{},"用于引入全局 CSS 和样式文件。",[1087,1125,1126,1130],{},[1102,1127,1128],{},[33,1129,340],{},[1102,1131,1132],{},"用于注册插件，可以在应用中全局使用的库或工具。",[1087,1134,1135,1140],{},[1102,1136,1137],{},[33,1138,1139],{},"modules",[1102,1141,1142],{},"配置 Nuxt 模块，扩展应用功能。",[1087,1144,1145,1150],{},[1102,1146,1147],{},[33,1148,1149],{},"router",[1102,1151,1152],{},"配置路由相关选项，如自定义路由路径。",[1087,1154,1155,1160],{},[1102,1156,1157],{},[33,1158,1159],{},"build",[1102,1161,1162],{},"配置构建相关选项，如 Webpack、Babel 配置等。",[1087,1164,1165,1170],{},[1102,1166,1167],{},[33,1168,1169],{},"env",[1102,1171,1172],{},"配置环境变量，用于不同环境下的变量设置。",[1087,1174,1175,1180],{},[1102,1176,1177],{},[33,1178,1179],{},"head",[1102,1181,1182,1183,1185],{},"配置 ",[33,1184,1112],{}," 标签，主要用于标题、meta 标签、favicon 等。",[1087,1187,1188,1193],{},[1102,1189,1190],{},[33,1191,1192],{},"middleware",[1102,1194,1195],{},"配置路由中间件，用于执行路由切换前后的逻辑。",[1087,1197,1198,1203],{},[1102,1199,1200],{},[33,1201,1202],{},"i18n",[1102,1204,1205],{},"配置多语言支持。",[22,1207,1074,1209],{"id":1208},"nuxtconfigts-配置项总结-1",[13,1210,1211,1079],{},[33,1212,346],{},[1081,1214,1215,1223],{},[1084,1216,1217],{},[1087,1218,1219,1221],{},[1090,1220,1092],{},[1090,1222,1095],{},[1097,1224,1225,1235,1243,1251,1259,1267,1275,1283,1293,1301],{},[1087,1226,1227,1231],{},[1102,1228,1229],{},[33,1230,1106],{},[1102,1232,1109,1233,1113],{},[33,1234,1112],{},[1087,1236,1237,1241],{},[1102,1238,1239],{},[33,1240,1120],{},[1102,1242,1123],{},[1087,1244,1245,1249],{},[1102,1246,1247],{},[33,1248,340],{},[1102,1250,1132],{},[1087,1252,1253,1257],{},[1102,1254,1255],{},[33,1256,1139],{},[1102,1258,1142],{},[1087,1260,1261,1265],{},[1102,1262,1263],{},[33,1264,1149],{},[1102,1266,1152],{},[1087,1268,1269,1273],{},[1102,1270,1271],{},[33,1272,1159],{},[1102,1274,1162],{},[1087,1276,1277,1281],{},[1102,1278,1279],{},[33,1280,1169],{},[1102,1282,1172],{},[1087,1284,1285,1289],{},[1102,1286,1287],{},[33,1288,1179],{},[1102,1290,1182,1291,1185],{},[33,1292,1112],{},[1087,1294,1295,1299],{},[1102,1296,1297],{},[33,1298,1192],{},[1102,1300,1195],{},[1087,1302,1303,1307],{},[1102,1304,1305],{},[33,1306,1202],{},[1102,1308,1205],{},[10,1310,1311,1313,1314,1317,1318],{},[33,1312,346],{}," 是 ",[13,1315,1316],{},"Nuxt.js"," 应用的核心配置文件，",[13,1319,1320],{},"控制了应用的整体行为和功能。",[10,1322,1323],{},"​\t它提供了丰富的配置选项，允许你调整页面头部、引入插件、配置路由、构建选项、状态管理、环境变量等。",[10,1325,1326,1327,1329,1330],{},"​\t通过 ",[33,1328,346],{},"，你可以根据项目需求",[13,1331,1332],{},"自定义应用的各个方面",[10,1334,1335],{},"runtimeConfig里面可以写运行时的一些全局变量。",[50,1337,1339],{"className":52,"code":1338,"language":54,"meta":55,"style":55},"\u002F\u002F https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fapi\u002Fconfiguration\u002Fnuxt-config\nexport default defineNuxtConfig({\n  compatibilityDate: '2024-11-01',\n  devtools: { enabled: true },\n  runtimeConfig:{\n    count:1,\n    public:{baseURL:'localhsot:8080'} \u002F\u002Fpublic表示这个配置会暴露给客户端，可以在前端中访问\n  }\n})\n\n",[33,1340,1341,1346,1356,1366,1377,1382,1392,1406,1411],{"__ignoreMap":55},[59,1342,1343],{"class":61,"line":62},[59,1344,1345],{"class":361},"\u002F\u002F https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fapi\u002Fconfiguration\u002Fnuxt-config\n",[59,1347,1348,1350,1352,1354],{"class":61,"line":83},[59,1349,292],{"class":65},[59,1351,295],{"class":65},[59,1353,371],{"class":148},[59,1355,374],{"class":69},[59,1357,1358,1361,1364],{"class":61,"line":98},[59,1359,1360],{"class":69},"  compatibilityDate: ",[59,1362,1363],{"class":76},"'2024-11-01'",[59,1365,915],{"class":69},[59,1367,1368,1371,1374],{"class":61,"line":113},[59,1369,1370],{"class":69},"  devtools: { enabled: ",[59,1372,1373],{"class":141},"true",[59,1375,1376],{"class":69}," },\n",[59,1378,1379],{"class":61,"line":128},[59,1380,1381],{"class":69},"  runtimeConfig:{\n",[59,1383,1384,1387,1390],{"class":61,"line":135},[59,1385,1386],{"class":69},"    count:",[59,1388,1389],{"class":141},"1",[59,1391,915],{"class":69},[59,1393,1394,1397,1400,1403],{"class":61,"line":155},[59,1395,1396],{"class":69},"    public:{baseURL:",[59,1398,1399],{"class":76},"'localhsot:8080'",[59,1401,1402],{"class":69},"} ",[59,1404,1405],{"class":361},"\u002F\u002Fpublic表示这个配置会暴露给客户端，可以在前端中访问\n",[59,1407,1408],{"class":61,"line":167},[59,1409,1410],{"class":69},"  }\n",[59,1412,1413],{"class":61,"line":177},[59,1414,1415],{"class":69},"})\n",[10,1417,1418],{},"组件中写：",[50,1420,1422],{"className":711,"code":1421,"language":713,"meta":55,"style":55},"\u003Ctemplate>\n  \u003Cdiv>\n\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\u003Cscript setup name=\"app\">\nconst config = useRuntimeConfig()\nconsole.log(\"1\"+config)\nconsole.log(\"2\"+config.count) \u002F\u002Fcount不是public的特性，因此浏览器里控制台得到的是\n\u002F\u002Fundefined,意思是count只能在服务端期间获取到\n\u002F\u002F而public的既可以在服务端也可以在客户端\nconsole.log(\"3\"+config.public.baseURL)\n\n\u003C\u002Fscript>\n\n",[33,1423,1424,1432,1441,1445,1453,1461,1481,1496,1514,1533,1538,1543,1559,1563],{"__ignoreMap":55},[59,1425,1426,1428,1430],{"class":61,"line":62},[59,1427,720],{"class":69},[59,1429,724],{"class":723},[59,1431,727],{"class":69},[59,1433,1434,1436,1439],{"class":61,"line":83},[59,1435,732],{"class":69},[59,1437,1438],{"class":723},"div",[59,1440,727],{"class":69},[59,1442,1443],{"class":61,"line":98},[59,1444,132],{"emptyLinePlaceholder":131},[59,1446,1447,1449,1451],{"class":61,"line":113},[59,1448,804],{"class":69},[59,1450,1438],{"class":723},[59,1452,727],{"class":69},[59,1454,1455,1457,1459],{"class":61,"line":128},[59,1456,813],{"class":69},[59,1458,724],{"class":723},[59,1460,727],{"class":69},[59,1462,1463,1465,1468,1471,1474,1476,1479],{"class":61,"line":135},[59,1464,720],{"class":69},[59,1466,1467],{"class":723},"script",[59,1469,1470],{"class":148}," setup",[59,1472,1473],{"class":148}," name",[59,1475,771],{"class":69},[59,1477,1478],{"class":76},"\"app\"",[59,1480,727],{"class":69},[59,1482,1483,1485,1488,1490,1493],{"class":61,"line":155},[59,1484,138],{"class":65},[59,1486,1487],{"class":141}," config",[59,1489,145],{"class":65},[59,1491,1492],{"class":148}," useRuntimeConfig",[59,1494,1495],{"class":69},"()\n",[59,1497,1498,1501,1503,1505,1508,1511],{"class":61,"line":167},[59,1499,1500],{"class":69},"console.",[59,1502,322],{"class":148},[59,1504,185],{"class":69},[59,1506,1507],{"class":76},"\"1\"",[59,1509,1510],{"class":65},"+",[59,1512,1513],{"class":69},"config)\n",[59,1515,1516,1518,1520,1522,1525,1527,1530],{"class":61,"line":177},[59,1517,1500],{"class":69},[59,1519,322],{"class":148},[59,1521,185],{"class":69},[59,1523,1524],{"class":76},"\"2\"",[59,1526,1510],{"class":65},[59,1528,1529],{"class":69},"config.count) ",[59,1531,1532],{"class":361},"\u002F\u002Fcount不是public的特性，因此浏览器里控制台得到的是\n",[59,1534,1535],{"class":61,"line":578},[59,1536,1537],{"class":361},"\u002F\u002Fundefined,意思是count只能在服务端期间获取到\n",[59,1539,1540],{"class":61,"line":584},[59,1541,1542],{"class":361},"\u002F\u002F而public的既可以在服务端也可以在客户端\n",[59,1544,1545,1547,1549,1551,1554,1556],{"class":61,"line":590},[59,1546,1500],{"class":69},[59,1548,322],{"class":148},[59,1550,185],{"class":69},[59,1552,1553],{"class":76},"\"3\"",[59,1555,1510],{"class":65},[59,1557,1558],{"class":69},"config.public.baseURL)\n",[59,1560,1561],{"class":61,"line":595},[59,1562,132],{"emptyLinePlaceholder":131},[59,1564,1565,1567,1569],{"class":61,"line":606},[59,1566,813],{"class":69},[59,1568,1467],{"class":723},[59,1570,727],{"class":69},[10,1572,1573],{},[1574,1575],"img",{"alt":1576,"src":1577},"image-20250223054448331","image-20250223054448331.png",[1579,1580,1582],"h2",{"id":1581},"ssr","SSR",[10,1584,1585],{},"​\t在控制台里可以看得到数据是由客户端还是由服务端渲染出来的，具体就看它有没有ssr这个前缀",[10,1587,1588],{},"​\tnuxt里有一个nitro的引擎，当我们通过链接发起请求，那么nitro就回去渲染页面，并返回给页面。",[10,1590,1591],{},"​\t客户端渲染则是浏览器的引擎负责渲染。当服务器内部遇到渲染错误的时候，会爆500这个错误（比如alert的渲染）。",[1579,1593,1594],{"id":1594},"静态资源",[10,1596,1597],{},"按照一般的约定，我们要把静态资源放在文件夹\u002Fassets里",[10,1599,1600],{},"我们可以在assets里添加新的文件夹比如css，之后在里面添加样式，如base.scss",[10,1602,1603],{},[1574,1604],{"alt":1605,"src":1606},"image-20250223054801893","image-20250223054801893.png",[10,1608,1609],{},"​\t使用scss来定义样式，我们需要使用sass这个工具， 使用pnpm i -D sass来添加到工作环境。",[10,1611,1612,1613,1616,1617,1620,1621,1624,1625,1628,1629,1632,1633],{},"​\t在 ",[33,1614,1615],{},"pnpm"," 中，",[33,1618,1619],{},"-D"," 参数是 ",[33,1622,1623],{},"--save-dev"," 的简写，表示将依赖项安装为 ",[13,1626,1627],{},"开发依赖","。开发依赖是指",[13,1630,1631],{},"只在开发过程中需要的依赖","，而",[13,1634,1635],{},"不是在生产环境中运行时需要的依赖。",[10,1637,1638],{},"然后回到nuxt.config.ts中去引用样式。",[50,1640,1642],{"className":52,"code":1641,"language":54,"meta":55,"style":55},"\u002F\u002F https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fapi\u002Fconfiguration\u002Fnuxt-config\nexport default defineNuxtConfig({\n  compatibilityDate: '2024-11-01',\n  devtools: { enabled: true },\n  css:['@\u002Fassets\u002Fcss\u002Fbase.scss'],\n  runtimeConfig:{\n    count:1,\n    public:{baseURL:'localhsot:8080'}\n\n  }\n})\n\n",[33,1643,1644,1648,1658,1666,1674,1684,1688,1696,1705,1709,1713],{"__ignoreMap":55},[59,1645,1646],{"class":61,"line":62},[59,1647,1345],{"class":361},[59,1649,1650,1652,1654,1656],{"class":61,"line":83},[59,1651,292],{"class":65},[59,1653,295],{"class":65},[59,1655,371],{"class":148},[59,1657,374],{"class":69},[59,1659,1660,1662,1664],{"class":61,"line":98},[59,1661,1360],{"class":69},[59,1663,1363],{"class":76},[59,1665,915],{"class":69},[59,1667,1668,1670,1672],{"class":61,"line":113},[59,1669,1370],{"class":69},[59,1671,1373],{"class":141},[59,1673,1376],{"class":69},[59,1675,1676,1679,1682],{"class":61,"line":128},[59,1677,1678],{"class":69},"  css:[",[59,1680,1681],{"class":76},"'@\u002Fassets\u002Fcss\u002Fbase.scss'",[59,1683,385],{"class":69},[59,1685,1686],{"class":61,"line":135},[59,1687,1381],{"class":69},[59,1689,1690,1692,1694],{"class":61,"line":155},[59,1691,1386],{"class":69},[59,1693,1389],{"class":141},[59,1695,915],{"class":69},[59,1697,1698,1700,1702],{"class":61,"line":167},[59,1699,1396],{"class":69},[59,1701,1399],{"class":76},[59,1703,1704],{"class":69},"}\n",[59,1706,1707],{"class":61,"line":177},[59,1708,132],{"emptyLinePlaceholder":131},[59,1710,1711],{"class":61,"line":578},[59,1712,1410],{"class":69},[59,1714,1715],{"class":61,"line":584},[59,1716,1415],{"class":69},[10,1718,1719],{},"base.scss可以写入用选择器自定义控件的样式。比如下面这个。",[10,1721,1722],{},"h1{",[10,1724,1725],{},"color: red;",[10,1727,1728],{},"}",[10,1730,1731],{},[1574,1732],{"alt":1733,"src":1734},"image-20250223055317380","image-20250223055317380.png",[10,1736,1737],{},"我们一般会在预处理器里定义一个变量 比如：",[50,1739,1743],{"className":1740,"code":1741,"language":1742,"meta":55,"style":55},"language-scss shiki shiki-themes github-light github-dark","$mycolor: green;\n","scss",[33,1744,1745],{"__ignoreMap":55},[59,1746,1747,1750,1753,1756],{"class":61,"line":62},[59,1748,1749],{"class":304},"$mycolor",[59,1751,1752],{"class":69},": ",[59,1754,1755],{"class":141},"green",[59,1757,80],{"class":69},[10,1759,1760],{},"如果要使用这种变量，就需要回到nuxt.config.ts去配置vite的配置项：",[50,1762,1764],{"className":52,"code":1763,"language":54,"meta":55,"style":55},"\u002F\u002F https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fapi\u002Fconfiguration\u002Fnuxt-config\nexport default defineNuxtConfig({\n  compatibilityDate: '2024-11-01',\n  devtools: { enabled: true },\n  vite:{\n    css:{\n      preprocessorOptions:{\n        scss:{\n          additionalData:`@use \"~\u002Fassets\u002Fcss\u002Fbase.scss\" as *;`\n            \u002F\u002F在 SCSS 中，@use 语句用于引入另一个 SCSS 文件，并通过模块化的方式将其中的内容作为一个命名空间导入。as * 的作用是将被引入文件中的所有内容（如变量、混合器、函数等）直接注入到当前作用域，而不是通过命名空间来访问它们。\n        }\n      }\n    }\n  },\n  runtimeConfig:{\n    count:1,\n    public:{baseURL:'localhsot:8080'}\n\n  }\n})\n\n",[33,1765,1766,1770,1780,1788,1796,1801,1806,1811,1816,1824,1829,1834,1839,1844,1848,1852,1860,1868,1872,1876],{"__ignoreMap":55},[59,1767,1768],{"class":61,"line":62},[59,1769,1345],{"class":361},[59,1771,1772,1774,1776,1778],{"class":61,"line":83},[59,1773,292],{"class":65},[59,1775,295],{"class":65},[59,1777,371],{"class":148},[59,1779,374],{"class":69},[59,1781,1782,1784,1786],{"class":61,"line":98},[59,1783,1360],{"class":69},[59,1785,1363],{"class":76},[59,1787,915],{"class":69},[59,1789,1790,1792,1794],{"class":61,"line":113},[59,1791,1370],{"class":69},[59,1793,1373],{"class":141},[59,1795,1376],{"class":69},[59,1797,1798],{"class":61,"line":128},[59,1799,1800],{"class":69},"  vite:{\n",[59,1802,1803],{"class":61,"line":135},[59,1804,1805],{"class":69},"    css:{\n",[59,1807,1808],{"class":61,"line":155},[59,1809,1810],{"class":69},"      preprocessorOptions:{\n",[59,1812,1813],{"class":61,"line":167},[59,1814,1815],{"class":69},"        scss:{\n",[59,1817,1818,1821],{"class":61,"line":177},[59,1819,1820],{"class":69},"          additionalData:",[59,1822,1823],{"class":76},"`@use \"~\u002Fassets\u002Fcss\u002Fbase.scss\" as *;`\n",[59,1825,1826],{"class":61,"line":578},[59,1827,1828],{"class":361},"            \u002F\u002F在 SCSS 中，@use 语句用于引入另一个 SCSS 文件，并通过模块化的方式将其中的内容作为一个命名空间导入。as * 的作用是将被引入文件中的所有内容（如变量、混合器、函数等）直接注入到当前作用域，而不是通过命名空间来访问它们。\n",[59,1830,1831],{"class":61,"line":584},[59,1832,1833],{"class":69},"        }\n",[59,1835,1836],{"class":61,"line":590},[59,1837,1838],{"class":69},"      }\n",[59,1840,1841],{"class":61,"line":595},[59,1842,1843],{"class":69},"    }\n",[59,1845,1846],{"class":61,"line":606},[59,1847,676],{"class":69},[59,1849,1850],{"class":61,"line":966},[59,1851,1381],{"class":69},[59,1853,1854,1856,1858],{"class":61,"line":985},[59,1855,1386],{"class":69},[59,1857,1389],{"class":141},[59,1859,915],{"class":69},[59,1861,1862,1864,1866],{"class":61,"line":998},[59,1863,1396],{"class":69},[59,1865,1399],{"class":76},[59,1867,1704],{"class":69},[59,1869,1870],{"class":61,"line":1003},[59,1871,132],{"emptyLinePlaceholder":131},[59,1873,1874],{"class":61,"line":1008},[59,1875,1410],{"class":69},[59,1877,1878],{"class":61,"line":1014},[59,1879,1415],{"class":69},[10,1881,1882],{},"​\t注意原先的css没了，原先的是直接引用，会和下面这个冲突，因此建议直接用刚才说的这个方式。",[10,1884,1885],{},"最后在vue里可以灵活的使用$去引用预处理的变量。",[50,1887,1889],{"className":711,"code":1888,"language":713,"meta":55,"style":55},"\u003Ctemplate>\n  \u003Cdiv>\n  \u003Ch1>这里是样式测试\u003C\u002Fh1>\n  \u003Cp>11111\u003C\u002Fp>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\u003Cscript setup name=\"app\">\nconst config = useRuntimeConfig()\nconsole.log(\"1\"+config)\nconsole.log(\"2\"+config.count) \u002F\u002Fcount不是public的特性，因此浏览器里控制台得到的是\n\u002F\u002Fundefined\nconsole.log(\"3\"+config.public.baseURL)\n\n\u003C\u002Fscript>\n\n\u003Cstyle scoped lang=\"scss\">\n p{\n  color: $mycolor;\n }\n\u003C\u002Fstyle>\n\n",[33,1890,1891,1899,1907,1921,1934,1942,1950,1966,1978,1992,2008,2013,2027,2031,2039,2043,2063,2068,2073,2078],{"__ignoreMap":55},[59,1892,1893,1895,1897],{"class":61,"line":62},[59,1894,720],{"class":69},[59,1896,724],{"class":723},[59,1898,727],{"class":69},[59,1900,1901,1903,1905],{"class":61,"line":83},[59,1902,732],{"class":69},[59,1904,1438],{"class":723},[59,1906,727],{"class":69},[59,1908,1909,1911,1914,1917,1919],{"class":61,"line":98},[59,1910,732],{"class":69},[59,1912,1913],{"class":723},"h1",[59,1915,1916],{"class":69},">这里是样式测试\u003C\u002F",[59,1918,1913],{"class":723},[59,1920,727],{"class":69},[59,1922,1923,1925,1927,1930,1932],{"class":61,"line":113},[59,1924,732],{"class":69},[59,1926,10],{"class":723},[59,1928,1929],{"class":69},">11111\u003C\u002F",[59,1931,10],{"class":723},[59,1933,727],{"class":69},[59,1935,1936,1938,1940],{"class":61,"line":128},[59,1937,804],{"class":69},[59,1939,1438],{"class":723},[59,1941,727],{"class":69},[59,1943,1944,1946,1948],{"class":61,"line":135},[59,1945,813],{"class":69},[59,1947,724],{"class":723},[59,1949,727],{"class":69},[59,1951,1952,1954,1956,1958,1960,1962,1964],{"class":61,"line":155},[59,1953,720],{"class":69},[59,1955,1467],{"class":723},[59,1957,1470],{"class":148},[59,1959,1473],{"class":148},[59,1961,771],{"class":69},[59,1963,1478],{"class":76},[59,1965,727],{"class":69},[59,1967,1968,1970,1972,1974,1976],{"class":61,"line":167},[59,1969,138],{"class":65},[59,1971,1487],{"class":141},[59,1973,145],{"class":65},[59,1975,1492],{"class":148},[59,1977,1495],{"class":69},[59,1979,1980,1982,1984,1986,1988,1990],{"class":61,"line":177},[59,1981,1500],{"class":69},[59,1983,322],{"class":148},[59,1985,185],{"class":69},[59,1987,1507],{"class":76},[59,1989,1510],{"class":65},[59,1991,1513],{"class":69},[59,1993,1994,1996,1998,2000,2002,2004,2006],{"class":61,"line":578},[59,1995,1500],{"class":69},[59,1997,322],{"class":148},[59,1999,185],{"class":69},[59,2001,1524],{"class":76},[59,2003,1510],{"class":65},[59,2005,1529],{"class":69},[59,2007,1532],{"class":361},[59,2009,2010],{"class":61,"line":584},[59,2011,2012],{"class":361},"\u002F\u002Fundefined\n",[59,2014,2015,2017,2019,2021,2023,2025],{"class":61,"line":590},[59,2016,1500],{"class":69},[59,2018,322],{"class":148},[59,2020,185],{"class":69},[59,2022,1553],{"class":76},[59,2024,1510],{"class":65},[59,2026,1558],{"class":69},[59,2028,2029],{"class":61,"line":595},[59,2030,132],{"emptyLinePlaceholder":131},[59,2032,2033,2035,2037],{"class":61,"line":606},[59,2034,813],{"class":69},[59,2036,1467],{"class":723},[59,2038,727],{"class":69},[59,2040,2041],{"class":61,"line":966},[59,2042,132],{"emptyLinePlaceholder":131},[59,2044,2045,2047,2050,2053,2056,2058,2061],{"class":61,"line":985},[59,2046,720],{"class":69},[59,2048,2049],{"class":723},"style",[59,2051,2052],{"class":148}," scoped",[59,2054,2055],{"class":148}," lang",[59,2057,771],{"class":69},[59,2059,2060],{"class":76},"\"scss\"",[59,2062,727],{"class":69},[59,2064,2065],{"class":61,"line":998},[59,2066,2067],{"class":69}," p{\n",[59,2069,2070],{"class":61,"line":1003},[59,2071,2072],{"class":69},"  color: $mycolor;\n",[59,2074,2075],{"class":61,"line":1008},[59,2076,2077],{"class":69}," }\n",[59,2079,2080,2082,2084],{"class":61,"line":1014},[59,2081,813],{"class":69},[59,2083,2049],{"class":723},[59,2085,727],{"class":69},[10,2087,2088,2089],{},"这个引用体现在",[2049,2090,2091],{},"标签里。",[1579,2093,2095],{"id":2094},"使用elementui","使用elementUI",[10,2097,2098],{},"使用方式依然是在nuxt.config.ts里配置相关的模板。",[10,2100,2101,2102,2105],{},"​\t当引入了moudles之后就会自动配置，",[13,2103,2104],{},"之后我们需要去配置全局样式","，如果在引入moudles之后依然没有什么作用。",[50,2107,2109],{"className":711,"code":2108,"language":713,"meta":55,"style":55},"\u003Ctemplate>\n  \u003Cdiv>\n  \u003Ch1>这里是样式测试\u003C\u002Fh1>\n  \u003Cp>11111\u003C\u002Fp>\n  \u003Cel-button type=\"primary\">1111\u003C\u002Fel-button>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n",[33,2110,2111,2119,2127,2139,2151,2172,2180],{"__ignoreMap":55},[59,2112,2113,2115,2117],{"class":61,"line":62},[59,2114,720],{"class":69},[59,2116,724],{"class":723},[59,2118,727],{"class":69},[59,2120,2121,2123,2125],{"class":61,"line":83},[59,2122,732],{"class":69},[59,2124,1438],{"class":723},[59,2126,727],{"class":69},[59,2128,2129,2131,2133,2135,2137],{"class":61,"line":98},[59,2130,732],{"class":69},[59,2132,1913],{"class":723},[59,2134,1916],{"class":69},[59,2136,1913],{"class":723},[59,2138,727],{"class":69},[59,2140,2141,2143,2145,2147,2149],{"class":61,"line":113},[59,2142,732],{"class":69},[59,2144,10],{"class":723},[59,2146,1929],{"class":69},[59,2148,10],{"class":723},[59,2150,727],{"class":69},[59,2152,2153,2155,2158,2161,2163,2165,2168,2170],{"class":61,"line":128},[59,2154,732],{"class":69},[59,2156,2157],{"class":723},"el-button",[59,2159,2160],{"class":148}," type",[59,2162,771],{"class":69},[59,2164,774],{"class":76},[59,2166,2167],{"class":69},">1111\u003C\u002F",[59,2169,2157],{"class":723},[59,2171,727],{"class":69},[59,2173,2174,2176,2178],{"class":61,"line":135},[59,2175,804],{"class":69},[59,2177,1438],{"class":723},[59,2179,727],{"class":69},[59,2181,2182,2184,2186],{"class":61,"line":155},[59,2183,813],{"class":69},[59,2185,724],{"class":723},[59,2187,727],{"class":69},[10,2189,2190],{},"然后使用标签引入就可以直接使用了。",[1579,2192,2194],{"id":2193},"useruntimeconfig","useRuntimeConfig",[10,2196,2197],{},[13,2198,2199,2201],{},[33,2200,2194],{}," 的工作原理：",[10,2203,2204,2205,2207,2208,2210,2211,2214,2215,2218],{},"​\t",[33,2206,2194],{}," 允许你访问在 ",[33,2209,346],{}," 或 ",[33,2212,2213],{},"nuxt.config.js"," 中定义的 ",[33,2216,2217],{},"runtimeConfig"," 对象。",[22,2220,2222],{"id":2221},"如何使用-useruntimeconfig",[13,2223,2224,2225,48],{},"如何使用 ",[33,2226,2194],{},[10,2228,2229,2230,2232],{},"在组件、页面或插件中，可以通过 ",[33,2231,2194],{}," 来访问这些配置。",[2234,2235,2237],"h4",{"id":2236},"在组件中使用","在组件中使用：",[50,2239,2241],{"className":711,"code":2240,"language":713,"meta":55,"style":55},"\u003Cscript setup>\nconst config = useRuntimeConfig()\n\n\u002F\u002F 访问公共配置\nconsole.log(config.public.baseURL) \u002F\u002F 输出: http:\u002F\u002Flocalhost:8080\n\n\u002F\u002F 访问私有配置，只能在服务端访问\nif (process.server) {   \u002F\u002F这也是判断是否在服务端\n    \n  console.log(config.private.apiKey) \u002F\u002F 输出: your-private-api-key\n}\n\n\u002F\u002F 访问共享的 count 配置\nconsole.log(config.count) \u002F\u002F 输出: 1\n\u003C\u002Fscript>\n",[33,2242,2243,2253,2265,2269,2274,2286,2290,2295,2306,2311,2323,2327,2331,2336,2348],{"__ignoreMap":55},[59,2244,2245,2247,2249,2251],{"class":61,"line":62},[59,2246,720],{"class":69},[59,2248,1467],{"class":723},[59,2250,1470],{"class":148},[59,2252,727],{"class":69},[59,2254,2255,2257,2259,2261,2263],{"class":61,"line":83},[59,2256,138],{"class":65},[59,2258,1487],{"class":141},[59,2260,145],{"class":65},[59,2262,1492],{"class":148},[59,2264,1495],{"class":69},[59,2266,2267],{"class":61,"line":98},[59,2268,132],{"emptyLinePlaceholder":131},[59,2270,2271],{"class":61,"line":113},[59,2272,2273],{"class":361},"\u002F\u002F 访问公共配置\n",[59,2275,2276,2278,2280,2283],{"class":61,"line":128},[59,2277,1500],{"class":69},[59,2279,322],{"class":148},[59,2281,2282],{"class":69},"(config.public.baseURL) ",[59,2284,2285],{"class":361},"\u002F\u002F 输出: http:\u002F\u002Flocalhost:8080\n",[59,2287,2288],{"class":61,"line":135},[59,2289,132],{"emptyLinePlaceholder":131},[59,2291,2292],{"class":61,"line":155},[59,2293,2294],{"class":361},"\u002F\u002F 访问私有配置，只能在服务端访问\n",[59,2296,2297,2300,2303],{"class":61,"line":167},[59,2298,2299],{"class":65},"if",[59,2301,2302],{"class":69}," (process.server) {   ",[59,2304,2305],{"class":361},"\u002F\u002F这也是判断是否在服务端\n",[59,2307,2308],{"class":61,"line":177},[59,2309,2310],{"class":69},"    \n",[59,2312,2313,2315,2317,2320],{"class":61,"line":578},[59,2314,319],{"class":69},[59,2316,322],{"class":148},[59,2318,2319],{"class":69},"(config.private.apiKey) ",[59,2321,2322],{"class":361},"\u002F\u002F 输出: your-private-api-key\n",[59,2324,2325],{"class":61,"line":584},[59,2326,1704],{"class":69},[59,2328,2329],{"class":61,"line":590},[59,2330,132],{"emptyLinePlaceholder":131},[59,2332,2333],{"class":61,"line":595},[59,2334,2335],{"class":361},"\u002F\u002F 访问共享的 count 配置\n",[59,2337,2338,2340,2342,2345],{"class":61,"line":606},[59,2339,1500],{"class":69},[59,2341,322],{"class":148},[59,2343,2344],{"class":69},"(config.count) ",[59,2346,2347],{"class":361},"\u002F\u002F 输出: 1\n",[59,2349,2350,2352,2354],{"class":61,"line":966},[59,2351,813],{"class":69},[59,2353,1467],{"class":723},[59,2355,727],{"class":69},[10,2357,2358,2359,2362,2363,2366,2367,2369,2370,2373],{},"​\t判断当前是否在客户端，你可以使用 ",[33,2360,2361],{},"process.client","，它是 Nuxt 3 内置的全局变量。与 ",[33,2364,2365],{},"process.server"," 类似，",[33,2368,2361],{}," 可以帮助你区分代码是否在 ",[13,2371,2372],{},"客户端"," 环境中执行。",[1579,2375,2376],{"id":2376},"路由",[10,2378,2379],{},"​\t和vue不一样，nuxt已经对路由vue.router进行了封装，可以直接使用和完成导航。",[50,2381,2385],{"className":2382,"code":2383,"language":2384,"meta":55,"style":55},"language-bash shiki shiki-themes github-light github-dark"," WARN  [nuxt] Your project has pages but the \u003CNuxtPage \u002F> component has not been used. You might be using the \u003CRouterView \u002F> component instead, which will not work correctly in Nuxt. You can set pages: false in nuxt.config if you do not wish to use the Nuxt vue-router integration.\n","bash",[33,2386,2387],{"__ignoreMap":55},[59,2388,2389,2392,2395,2397,2400,2403,2406,2408,2411,2413,2416,2418,2421,2424,2427,2430,2433,2436,2439,2442,2445],{"class":61,"line":62},[59,2390,2391],{"class":148}," WARN",[59,2393,2394],{"class":69},"  [nuxt] Your project has pages but the ",[59,2396,720],{"class":65},[59,2398,2399],{"class":69},"NuxtPage \u002F",[59,2401,2402],{"class":65},">",[59,2404,2405],{"class":69}," component has not been used. You might be using the ",[59,2407,720],{"class":65},[59,2409,2410],{"class":69},"RouterView \u002F",[59,2412,2402],{"class":65},[59,2414,2415],{"class":69}," component instead, which will not work correctly in Nuxt. You can set pages: false in nuxt.config ",[59,2417,2299],{"class":65},[59,2419,2420],{"class":148}," you",[59,2422,2423],{"class":76}," do",[59,2425,2426],{"class":76}," not",[59,2428,2429],{"class":76}," wish",[59,2431,2432],{"class":76}," to",[59,2434,2435],{"class":76}," use",[59,2437,2438],{"class":76}," the",[59,2440,2441],{"class":76}," Nuxt",[59,2443,2444],{"class":76}," vue-router",[59,2446,2447],{"class":76}," integration.\n",[10,2449,2450],{},"注意一下如果在写完了pages后直接进行跳转页面就会有这个报错。",[10,2452,2453,2454,36,2457,2460,2461,2464,2465,2468,2469,2471,2472,2474],{},"​\t这个警告意味着你正在使用 Nuxt 项目时，系统发现你的",[13,2455,2456],{},"项目中定义了页面",[33,2458,2459],{},"pages"," 目录下有 Vue 文件），但是你没有在模板中使用 ",[33,2462,2463],{},"\u003CNuxtPage \u002F>"," 组件，而是使用了 ",[33,2466,2467],{},"\u003CRouterView \u002F>"," 组件。Nuxt 依赖于 ",[33,2470,2463],{}," 来正确渲染路由页面，而 ",[33,2473,2467],{}," 是 Vue Router 的组件，并不能与 Nuxt 的自动化路由系统兼容。",[10,2476,2477],{},"​\t也就是没有写路由的入口，如果在\u002Fpages里 创建一个index.vue的组件，那么它就会称为 \u002F 的入口 ，当你进入localhsot:3000的时候，就会显示这个页面。",[10,2479,2480],{},"查看这个图片",[10,2482,2483],{},[1574,2484],{"alt":2485,"src":2486},"image-20250223181646375","image-20250223181646375.png",[10,2488,2489],{},"这里的router-view就是路由的入口，当路由发生变化的时候，这个地方就会变化",[10,2491,2492],{},"只是我们一般用的是NuxtPage标签。它可以支持命名路由和可选路由。",[22,2494,2495],{"id":2495},"导航守卫和中间件",[10,2497,2498],{},"中间件必须定义为middleware的文件夹里",[10,2500,2501],{},"假设在文件夹里定义一个文件叫做test.js",[50,2503,2507],{"className":2504,"code":2505,"language":2506,"meta":55,"style":55},"language-js shiki shiki-themes github-light github-dark","export default defineNuxtRouteMiddleware((to, from) => {\n    console.log(to.path, from)\n    console.log(\"拦截到了，上面是输出\")\n})\n","js",[33,2508,2509,2534,2544,2558],{"__ignoreMap":55},[59,2510,2511,2513,2515,2518,2520,2523,2526,2528,2530,2532],{"class":61,"line":62},[59,2512,292],{"class":65},[59,2514,295],{"class":65},[59,2516,2517],{"class":148}," defineNuxtRouteMiddleware",[59,2519,301],{"class":69},[59,2521,2522],{"class":304},"to",[59,2524,2525],{"class":69},", ",[59,2527,73],{"class":304},[59,2529,308],{"class":69},[59,2531,311],{"class":65},[59,2533,314],{"class":69},[59,2535,2536,2539,2541],{"class":61,"line":83},[59,2537,2538],{"class":69},"    console.",[59,2540,322],{"class":148},[59,2542,2543],{"class":69},"(to.path, from)\n",[59,2545,2546,2548,2550,2552,2555],{"class":61,"line":98},[59,2547,2538],{"class":69},[59,2549,322],{"class":148},[59,2551,185],{"class":69},[59,2553,2554],{"class":76},"\"拦截到了，上面是输出\"",[59,2556,2557],{"class":69},")\n",[59,2559,2560],{"class":61,"line":113},[59,2561,1415],{"class":69},[22,2563,2565],{"id":2564},"输出示例","输出示例：",[10,2567,2568,2569,2572,2573,2576],{},"假设用户从 ",[33,2570,2571],{},"\u002Fhome"," 页面跳转到 ",[33,2574,2575],{},"\u002Fprofile"," 页面，则控制台的输出会是：",[50,2578,2580],{"className":2382,"code":2579,"language":2384,"meta":55,"style":55},"Target path: \u002Fprofile\nCurrent path: \u002Fhome\n",[33,2581,2582,2593],{"__ignoreMap":55},[59,2583,2584,2587,2590],{"class":61,"line":62},[59,2585,2586],{"class":148},"Target",[59,2588,2589],{"class":76}," path:",[59,2591,2592],{"class":76}," \u002Fprofile\n",[59,2594,2595,2598,2600],{"class":61,"line":83},[59,2596,2597],{"class":148},"Current",[59,2599,2589],{"class":76},[59,2601,2602],{"class":76}," \u002Fhome\n",[22,2604,2606],{"id":2605},"使用场景","使用场景：",[202,2608,2609,2615],{},[205,2610,2611,2614],{},[13,2612,2613],{},"调试路由跳转","：你可以用它来调试路由跳转，查看哪些路径在跳转过程中被访问。",[205,2616,2617,2620,2621,2623,2624,2626],{},[13,2618,2619],{},"路由跳转条件","：你也可以根据 ",[33,2622,2522],{}," 和 ",[33,2625,73],{}," 判断是否允许某次跳转。例如，如果用户未登录且试图访问某些页面，可以取消跳转。",[10,2628,2629],{},"定义好test.js后在页面里引用",[50,2631,2633],{"className":711,"code":2632,"language":713,"meta":55,"style":55},"\u003Ctemplate>\n    \u003Cdiv>\n        \u003Ch2>首页\u003C\u002Fh2>\n    \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup name=\"index\" lang=\"ts\">\ndefinePageMeta({\n    middleware:[\"test\"]\n})\n\u003C\u002Fscript>\n",[33,2634,2635,2643,2651,2664,2672,2680,2684,2708,2715,2726,2730],{"__ignoreMap":55},[59,2636,2637,2639,2641],{"class":61,"line":62},[59,2638,720],{"class":69},[59,2640,724],{"class":723},[59,2642,727],{"class":69},[59,2644,2645,2647,2649],{"class":61,"line":83},[59,2646,742],{"class":69},[59,2648,1438],{"class":723},[59,2650,727],{"class":69},[59,2652,2653,2655,2657,2660,2662],{"class":61,"line":98},[59,2654,762],{"class":69},[59,2656,1579],{"class":723},[59,2658,2659],{"class":69},">首页\u003C\u002F",[59,2661,1579],{"class":723},[59,2663,727],{"class":69},[59,2665,2666,2668,2670],{"class":61,"line":113},[59,2667,795],{"class":69},[59,2669,1438],{"class":723},[59,2671,727],{"class":69},[59,2673,2674,2676,2678],{"class":61,"line":128},[59,2675,813],{"class":69},[59,2677,724],{"class":723},[59,2679,727],{"class":69},[59,2681,2682],{"class":61,"line":135},[59,2683,132],{"emptyLinePlaceholder":131},[59,2685,2686,2688,2690,2692,2694,2696,2699,2701,2703,2706],{"class":61,"line":155},[59,2687,720],{"class":69},[59,2689,1467],{"class":723},[59,2691,1470],{"class":148},[59,2693,1473],{"class":148},[59,2695,771],{"class":69},[59,2697,2698],{"class":76},"\"index\"",[59,2700,2055],{"class":148},[59,2702,771],{"class":69},[59,2704,2705],{"class":76},"\"ts\"",[59,2707,727],{"class":69},[59,2709,2710,2713],{"class":61,"line":167},[59,2711,2712],{"class":148},"definePageMeta",[59,2714,374],{"class":69},[59,2716,2717,2720,2723],{"class":61,"line":177},[59,2718,2719],{"class":69},"    middleware:[",[59,2721,2722],{"class":76},"\"test\"",[59,2724,2725],{"class":69},"]\n",[59,2727,2728],{"class":61,"line":578},[59,2729,1415],{"class":69},[59,2731,2732,2734,2736],{"class":61,"line":584},[59,2733,813],{"class":69},[59,2735,1467],{"class":723},[59,2737,727],{"class":69},[10,2739,2740],{},"然后试着去请求页面：",[10,2742,2743],{},[1574,2744],{"alt":2745,"src":2746},"image-20250223185626938","image-20250223185626938.png",[10,2748,2749],{},"在 Nuxt 项目中，页面加载时会经历一系列的生命周期和事件，理解这些事件的顺序对于掌握 Nuxt 的内部工作原理非常重要。以下是从请求到页面渲染过程中，前后发生的一些关键步骤。",[22,2751,2753],{"id":2752},"全局中间件的定义","全局中间件的定义:",[10,2755,2756],{},"结尾以global.js为结尾定义。",[10,2758,2759],{},[1574,2760],{"alt":2761,"src":2762},"image-20250223191415333","image-20250223191415333.png",[10,2764,2765],{},"这种写法就不需要向上面那样在vue组件中引入了。",[22,2767,2768],{"id":2768},"导航守卫",[10,2770,2771],{},"​\t导航守卫就是靠全局中间件去定义的。一些页面可能需要携带一定的token去进入，否则就是去重定向。",[10,2773,2774],{},"​\t那么token的存储是需要依靠localStore去实现的，里面还有很多的细节，千万要小心服务端侧的代码执行和客户端侧的代码执行，比如ElMessage.error()等方法无法在服务端段执行，而在test.global.js这种全局中间件都是默认是服务端侧的代码执行。",[10,2776,2777],{},[1574,2778],{"alt":2779,"src":2780},"image-20250223193805377","image-20250223193805377.png",[10,2782,2783],{},"​\t这就很麻烦。因为ElMessage.error()是一个客户端组件，无法在服务端运行，这时候可以使用query去传递参数。",[10,2785,2786],{},[1574,2787],{"alt":2788,"src":2789},"image-20250223200224833","image-20250223200224833.png",[10,2791,2792],{},"携带参数后就去返回的页面去获取参数",[10,2794,2795,2796,2799],{},"我们直接在跳转到的页面这样引入，顺便",[13,2797,2798],{},"判断在浏览器段执行的代码","。",[50,2801,2803],{"className":711,"code":2802,"language":713,"meta":55,"style":55},"\u003Ctemplate>\n    \u003Cdiv>\n        \u003Ch2>首页\u003C\u002Fh2>\n    \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup name=\"index\" lang=\"ts\">\nconst route = useRoute()\nif (import.meta.client) { \u002F\u002F 只在客户端执行\n    const { code, message } = route.query\n    if (code && message) {\n        ElMessage.error(`${code} ${message}`)\n    }\n}\ndefinePageMeta({\n    \u002F\u002F middleware:[\"test\"]\n})\n\u003C\u002Fscript>\n",[33,2804,2805,2813,2821,2833,2841,2849,2853,2875,2889,2910,2933,2947,2972,2976,2980,2986,2991,2995],{"__ignoreMap":55},[59,2806,2807,2809,2811],{"class":61,"line":62},[59,2808,720],{"class":69},[59,2810,724],{"class":723},[59,2812,727],{"class":69},[59,2814,2815,2817,2819],{"class":61,"line":83},[59,2816,742],{"class":69},[59,2818,1438],{"class":723},[59,2820,727],{"class":69},[59,2822,2823,2825,2827,2829,2831],{"class":61,"line":98},[59,2824,762],{"class":69},[59,2826,1579],{"class":723},[59,2828,2659],{"class":69},[59,2830,1579],{"class":723},[59,2832,727],{"class":69},[59,2834,2835,2837,2839],{"class":61,"line":113},[59,2836,795],{"class":69},[59,2838,1438],{"class":723},[59,2840,727],{"class":69},[59,2842,2843,2845,2847],{"class":61,"line":128},[59,2844,813],{"class":69},[59,2846,724],{"class":723},[59,2848,727],{"class":69},[59,2850,2851],{"class":61,"line":135},[59,2852,132],{"emptyLinePlaceholder":131},[59,2854,2855,2857,2859,2861,2863,2865,2867,2869,2871,2873],{"class":61,"line":155},[59,2856,720],{"class":69},[59,2858,1467],{"class":723},[59,2860,1470],{"class":148},[59,2862,1473],{"class":148},[59,2864,771],{"class":69},[59,2866,2698],{"class":76},[59,2868,2055],{"class":148},[59,2870,771],{"class":69},[59,2872,2705],{"class":76},[59,2874,727],{"class":69},[59,2876,2877,2879,2882,2884,2887],{"class":61,"line":167},[59,2878,138],{"class":65},[59,2880,2881],{"class":141}," route",[59,2883,145],{"class":65},[59,2885,2886],{"class":148}," useRoute",[59,2888,1495],{"class":69},[59,2890,2891,2893,2896,2898,2901,2904,2907],{"class":61,"line":177},[59,2892,2299],{"class":65},[59,2894,2895],{"class":69}," (",[59,2897,66],{"class":65},[59,2899,2900],{"class":69},".",[59,2902,2903],{"class":141},"meta",[59,2905,2906],{"class":69},".client) { ",[59,2908,2909],{"class":361},"\u002F\u002F 只在客户端执行\n",[59,2911,2912,2915,2918,2920,2922,2925,2928,2930],{"class":61,"line":578},[59,2913,2914],{"class":65},"    const",[59,2916,2917],{"class":69}," { ",[59,2919,33],{"class":141},[59,2921,2525],{"class":69},[59,2923,2924],{"class":141},"message",[59,2926,2927],{"class":69}," } ",[59,2929,771],{"class":65},[59,2931,2932],{"class":69}," route.query\n",[59,2934,2935,2938,2941,2944],{"class":61,"line":584},[59,2936,2937],{"class":65},"    if",[59,2939,2940],{"class":69}," (code ",[59,2942,2943],{"class":65},"&&",[59,2945,2946],{"class":69}," message) {\n",[59,2948,2949,2952,2955,2957,2960,2962,2965,2967,2970],{"class":61,"line":590},[59,2950,2951],{"class":69},"        ElMessage.",[59,2953,2954],{"class":148},"error",[59,2956,185],{"class":69},[59,2958,2959],{"class":76},"`${",[59,2961,33],{"class":69},[59,2963,2964],{"class":76},"} ${",[59,2966,2924],{"class":69},[59,2968,2969],{"class":76},"}`",[59,2971,2557],{"class":69},[59,2973,2974],{"class":61,"line":595},[59,2975,1843],{"class":69},[59,2977,2978],{"class":61,"line":606},[59,2979,1704],{"class":69},[59,2981,2982,2984],{"class":61,"line":966},[59,2983,2712],{"class":148},[59,2985,374],{"class":69},[59,2987,2988],{"class":61,"line":985},[59,2989,2990],{"class":361},"    \u002F\u002F middleware:[\"test\"]\n",[59,2992,2993],{"class":61,"line":998},[59,2994,1415],{"class":69},[59,2996,2997,2999,3001],{"class":61,"line":1003},[59,2998,813],{"class":69},[59,3000,1467],{"class":723},[59,3002,727],{"class":69},[10,3004,3005,3006,3008,3009,3012],{},"另一种是使用生命周期的钩子比如 onmounted这个HooK,",[33,3007,408],{}," 只会在",[13,3010,3011],{},"组件的 DOM 元素被挂载到页面上后执行","，而挂载是在客户端进行的，所以它也适合用于判断是否在客户端。",[10,3014,3015],{},[1574,3016],{"alt":3017,"src":3018},"image-20250223200633096","image-20250223200633096.png",[10,3020,3021],{},"​\t试问为什么要加上if(route.query.code){}。因为我们正常访问login页面的时候这段代码也会执行，用的是onMounted去判断，因此要判断有无code,也就是去前往list网页的时候通过query携带的参数code，若没有，则正常进入就是了。",[10,3023,3024,2623,3027,3030],{},[33,3025,3026],{},"localStorage",[13,3028,3029],{},"cookie"," 都是浏览器提供的客户端存储机制，但它们有一些不同之处：",[22,3032,3034,3035,48],{"id":3033},"_1-存储方式","1. ",[13,3036,3037],{},"存储方式",[202,3039,3040,3051],{},[205,3041,3042,3046,3047,3050],{},[13,3043,3044],{},[33,3045,3026],{},"：用于存储数据的",[13,3048,3049],{},"简单键值对数据。数据存储在浏览器的本地存储中，不会随着页面刷新或浏览器关闭而清除","，除非手动清除。",[205,3052,3053,3056,3057,2799],{},[13,3054,3055],{},"Cookies","：用于存储小量数据，可以在请求头中自动随每次 HTTP 请求发送到服务器，",[13,3058,3059],{},"适用于身份验证、会话管理等",[22,3061,3063,3064,48],{"id":3062},"_2-存储大小","2. ",[13,3065,3066],{},"存储大小",[202,3068,3069,3080],{},[205,3070,3071,3075,3076,3079],{},[13,3072,3073],{},[33,3074,3026],{},"：每个域名下最多可以存储约 ",[13,3077,3078],{},"5MB"," 的数据（不同浏览器可能略有不同）。",[205,3081,3082,3084,3085,3088,3089,3092],{},[13,3083,3055],{},"：每个 cookie 的大小限制通常为 ",[13,3086,3087],{},"4KB","，而且通常最多允许设置 ",[13,3090,3091],{},"20-50"," 个 cookie。",[22,3094,3096,3097,48],{"id":3095},"_3-持久性","3. ",[13,3098,3099],{},"持久性",[202,3101,3102,3109],{},[205,3103,3104,3108],{},[13,3105,3106],{},[33,3107,3026],{},"：数据不会过期，除非显式删除（例如通过 JavaScript 清除）。",[205,3110,3111,3113,3114,2210,3117,3120],{},[13,3112,3055],{},"：数据有有效期设置，可以是会话级别的（即浏览器关闭时删除）或者长期有效（通过设置 ",[33,3115,3116],{},"expires",[33,3118,3119],{},"max-age","）。",[22,3122,3124,3125,48],{"id":3123},"_4-发送机制","4. ",[13,3126,3127],{},"发送机制",[202,3129,3130,3137],{},[205,3131,3132,3136],{},[13,3133,3134],{},[33,3135,3026],{},"：数据存储在浏览器中，不会自动发送给服务器。它只适用于客户端 JavaScript 获取和存储数据。",[205,3138,3139,3141],{},[13,3140,3055],{},"：会随着每次 HTTP 请求自动发送到服务器，适合用于保存身份认证信息等。",[22,3143,3145,3146,48],{"id":3144},"_5-跨域访问","5. ",[13,3147,3148],{},"跨域访问",[202,3150,3151,3161],{},[205,3152,3153,3157,3158,2799],{},[13,3154,3155],{},[33,3156,3026],{},"：只能在",[13,3159,3160],{},"相同的源（协议、域名、端口）下访问",[205,3162,3163,3165,3166,3169,3170,3173],{},[13,3164,3055],{},"：同样",[13,3167,3168],{},"有相同的域名访问限制","，但是可以通过设置 ",[33,3171,3172],{},"Domain"," 属性来共享跨子域名的 Cookie。",[22,3175,3177],{"id":3176},"总结","总结：",[202,3179,3180,3195],{},[205,3181,3182,2623,3186,3188,3189,3191,3192,3194],{},[13,3183,3184],{},[33,3185,3026],{},[13,3187,3029],{}," 并不是同一个东西。",[33,3190,3026],{}," 是一个用于在浏览器端存储数据的 API，而 ",[13,3193,3029],{}," 主要用于在浏览器与服务器之间传递信息。",[205,3196,3197,3198,3200,3201,3203],{},"它们有不同的用途和行为，",[33,3199,3026],{}," 更适合用于存储大量数据，",[13,3202,3029],{}," 则适合用于在客户端与服务器之间交换少量信息（如会话标识）。",[22,3205,3034,3207],{"id":3206},"_1-路由请求和中间件触发的顺序",[13,3208,3209],{},"路由请求和中间件触发的顺序",[10,3211,3212],{},"​\t当用户访问某个页面时，浏览器向 Nuxt 应用发出路由请求，Nuxt 会依次执行以下步骤：",[2234,3214,3216,3217],{"id":3215},"_11-请求开始","1.1 ",[13,3218,3219],{},"请求开始：",[202,3221,3222],{},[205,3223,3224,3227,3228,3230],{},[13,3225,3226],{},"浏览器向服务器发出请求","，例如用户访问 ",[33,3229,2575],{}," 页面，浏览器会发出请求到服务器。",[2234,3232,3234,3235],{"id":3233},"_12-nuxt-中间件执行","1.2 ",[13,3236,3237],{},"Nuxt 中间件执行：",[202,3239,3240],{},[205,3241,3242,2623,3245,3248,3249,3252,3253,3256,3257,3283,3285,48,3288,3377,3379,3380],{},[13,3243,3244],{},"全局中间件",[13,3246,3247],{},"页面中间件"," 会",[13,3250,3251],{},"首先执行","（也就是上面的middleware会开始执行）。这些",[13,3254,3255],{},"中间件用于处理一些页面加载前的逻辑，例如权限检查、数据获取、重定向","等。",[202,3258,3259,3270],{},[205,3260,3261,3263,3264,3266,3267,2799],{},[13,3262,3244],{},"：在 ",[33,3265,346],{}," 中配置的全局中间件会首先被调用。它们",[13,3268,3269],{},"对所有路由生效",[205,3271,3272,3275,3276,3279,3280,3282],{},[13,3273,3274],{},"页面级中间件","：你可以在每个页面的 ",[33,3277,3278],{},"\u003Cscript setup>"," 中通过 ",[33,3281,2712],{}," 来配置中间件，它们在对应页面加载之前被调用。",[275,3284],{},[13,3286,3287],{},"例如",[50,3289,3291],{"className":2504,"code":3290,"language":2506,"meta":55,"style":55},"\u002F\u002F middleware\u002Fauth.js\nexport default defineNuxtRouteMiddleware((to, from) => {\n    console.log('Before page load', to.path)\n    \u002F\u002F 权限检查\n    if (!isAuthenticated) {\n        return navigateTo('\u002Flogin') \u002F\u002F 如果用户未认证，跳转到登录页面\n    }\n})\n",[33,3292,3293,3298,3320,3334,3339,3351,3369,3373],{"__ignoreMap":55},[59,3294,3295],{"class":61,"line":62},[59,3296,3297],{"class":361},"\u002F\u002F middleware\u002Fauth.js\n",[59,3299,3300,3302,3304,3306,3308,3310,3312,3314,3316,3318],{"class":61,"line":83},[59,3301,292],{"class":65},[59,3303,295],{"class":65},[59,3305,2517],{"class":148},[59,3307,301],{"class":69},[59,3309,2522],{"class":304},[59,3311,2525],{"class":69},[59,3313,73],{"class":304},[59,3315,308],{"class":69},[59,3317,311],{"class":65},[59,3319,314],{"class":69},[59,3321,3322,3324,3326,3328,3331],{"class":61,"line":98},[59,3323,2538],{"class":69},[59,3325,322],{"class":148},[59,3327,185],{"class":69},[59,3329,3330],{"class":76},"'Before page load'",[59,3332,3333],{"class":69},", to.path)\n",[59,3335,3336],{"class":61,"line":113},[59,3337,3338],{"class":361},"    \u002F\u002F 权限检查\n",[59,3340,3341,3343,3345,3348],{"class":61,"line":128},[59,3342,2937],{"class":65},[59,3344,2895],{"class":69},[59,3346,3347],{"class":65},"!",[59,3349,3350],{"class":69},"isAuthenticated) {\n",[59,3352,3353,3356,3359,3361,3364,3366],{"class":61,"line":135},[59,3354,3355],{"class":65},"        return",[59,3357,3358],{"class":148}," navigateTo",[59,3360,185],{"class":69},[59,3362,3363],{"class":76},"'\u002Flogin'",[59,3365,308],{"class":69},[59,3367,3368],{"class":361},"\u002F\u002F 如果用户未认证，跳转到登录页面\n",[59,3370,3371],{"class":61,"line":155},[59,3372,1843],{"class":69},[59,3374,3375],{"class":61,"line":167},[59,3376,1415],{"class":69},[275,3378],{},"这些中间件会执行如下操作：",[202,3381,3382,3392,3401],{},[205,3383,3384,3387,3388,3391],{},[13,3385,3386],{},"验证用户身份","：如果是",[13,3389,3390],{},"需要登录才能访问的页面","，检查用户是否已认证。",[205,3393,3394,3397,3398,2799],{},[13,3395,3396],{},"数据加载","：有些中间件也会",[13,3399,3400],{},"负责在页面加载前异步请求数据",[205,3402,3403,3406,3407,3410,3411,3414],{},[13,3404,3405],{},"重定向","：如果中间件决定",[13,3408,3409],{},"用户无法访问某个页面","，可以通过 ",[33,3412,3413],{},"navigateTo('\u002Flogin')"," 实现页面重定向。",[2234,3416,3418,3419],{"id":3417},"_13-服务器端渲染ssr或客户端渲染csr","1.3 ",[13,3420,3421],{},"服务器端渲染（SSR）或客户端渲染（CSR）",[202,3423,3424,3438],{},[205,3425,3426,3429,3430,3433,3434,3437],{},[13,3427,3428],{},"服务器端渲染","：在 SSR 模式下，Nuxt 会在服务器上渲染页面内容，生成 HTML 并发送给浏览器。",[33,3431,3432],{},"useFetch","、",[33,3435,3436],{},"useAsyncData"," 等函数通常在服务器端运行，用于数据加载。",[205,3439,3440,3443],{},[13,3441,3442],{},"客户端渲染","：在 CSR 模式下，Nuxt 会在浏览器中进行渲染，动态生成页面内容。通过路由跳转，页面数据会在客户端获取。",[2234,3445,3447,3448],{"id":3446},"_14-appvue-的加载和渲染","1.4 ",[13,3449,3450],{},"App.vue 的加载和渲染：",[202,3452,3453,3475,3483],{},[205,3454,3455,3456,3458,3459,3461,3462,3464,48,3469],{},"在页面中间件处理完后，Nuxt 会加载 ",[33,3457,266],{}," 文件。",[33,3460,266],{}," 是 Nuxt 的根组件，所有页面内容都会渲染在这个组件内。",[275,3463],{},[13,3465,3466,3468],{},[33,3467,266],{}," 大致结构",[50,3470,3473],{"className":3471,"code":3472,"language":442},[440],"vue复制编辑\u003Ctemplate>\n  \u003Cdiv>\n    \u003CNuxtLayout \u002F>\n    \u003CNuxtPage \u002F> \u003C!-- 页面内容 -->\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript setup>\n\u002F\u002F 可在此执行一些初始化逻辑\n\u003C\u002Fscript>\n",[33,3474,3472],{"__ignoreMap":55},[205,3476,3477,3482],{},[13,3478,3479],{},[33,3480,3481],{},"NuxtLayout","：这个组件负责渲染布局，布局通常包含页面的头部、侧边栏、底部等固定部分。",[205,3484,3485,3490],{},[13,3486,3487],{},[33,3488,3489],{},"NuxtPage","：这个组件负责渲染具体的页面内容，它会根据当前路由加载对应的页面组件。",[22,3492,3063,3494],{"id":3493},"_2-客户端加载的详细过程",[13,3495,3496],{},"客户端加载的详细过程：",[10,3498,3499],{},"在客户端渲染时，页面加载过程会略有不同。",[2234,3501,3503,3504],{"id":3502},"_21-页面路由跳转","2.1 ",[13,3505,3506],{},"页面路由跳转：",[10,3508,3509],{},"当你在浏览器中点击链接，触发路由跳转时，Nuxt 会执行如下操作：",[256,3511,3512,3526,3549,3574],{},[205,3513,3514,3517,3518],{},[13,3515,3516],{},"执行中间件","：\n",[202,3519,3520,3523],{},[205,3521,3522],{},"如果页面有配置中间件（全局或局部），中间件会在路由跳转前执行。",[205,3524,3525],{},"页面级中间件会在特定页面渲染之前执行。",[205,3527,3528,3517,3531],{},[13,3529,3530],{},"动态加载页面组件",[202,3532,3533,3543],{},[205,3534,3535,3536,3538,3539,3542],{},"Nuxt 会根据路由配置，异步加载相应的页面组件，通常是通过 ",[33,3537,2459],{}," 目录下的 ",[33,3540,3541],{},".vue"," 文件进行自动路由映射。",[205,3544,3545,3546,3548],{},"页面组件会传递给 ",[33,3547,3489],{}," 来渲染。",[205,3550,3551,3517,3554],{},[13,3552,3553],{},"数据获取",[202,3555,3556,3564],{},[205,3557,3558,3559,2210,3561,3563],{},"在页面加载前，Nuxt 会触发 ",[33,3560,3432],{},[33,3562,3436],{}," 来获取数据，确保页面渲染时能够展示最新的数据。",[205,3565,3566,3567,2210,3570,3573],{},"这些数据会在 ",[33,3568,3569],{},"beforeMount",[33,3571,3572],{},"mounted"," 生命周期钩子之前加载完成。",[205,3575,3576,3517,3579],{},[13,3577,3578],{},"渲染页面",[202,3580,3581],{},[205,3582,3583,3584,3586],{},"页面内容渲染到 ",[33,3585,3489],{}," 组件内，最终显示在浏览器中。",[22,3588,3096,3590],{"id":3589},"_3-总结页面加载生命周期",[13,3591,3592],{},"总结：页面加载生命周期",[256,3594,3595,3601,3607,3613,3622,3628,3638],{},[205,3596,3597,3600],{},[13,3598,3599],{},"浏览器发起请求","，访问特定页面。",[205,3602,3603,3606],{},[13,3604,3605],{},"执行全局中间件","，检查访问权限、数据加载等。",[205,3608,3609,3612],{},[13,3610,3611],{},"执行页面级中间件","，特定页面的逻辑（如权限验证）。",[205,3614,3615,2210,3618,3621],{},[13,3616,3617],{},"服务器端渲染（SSR）",[13,3619,3620],{},"客户端渲染（CSR）","：根据渲染模式决定如何加载页面内容。",[205,3623,3624,3627],{},[13,3625,3626],{},"App.vue 加载","：Nuxt 渲染应用的根组件，展示页面布局和内容。",[205,3629,3630,3632,3633,2210,3635,3637],{},[13,3631,3396],{},"：通过 ",[33,3634,3432],{},[33,3636,3436],{}," 获取异步数据。",[205,3639,3640,3643],{},[13,3641,3642],{},"渲染页面组件","，并在浏览器中显示。",[22,3645,3124,3647],{"id":3646},"_4-appvue-和-中间件的关系",[13,3648,3649],{},"App.vue 和 中间件的关系",[202,3651,3652,3662],{},[205,3653,3654,3656,3657,2623,3659,3661],{},[13,3655,266],{}," 是应用的根组件，负责渲染全局布局和页面内容。它的作用是作为一个容器，里面包含了 ",[33,3658,3481],{},[33,3660,3489],{},"，这些是用来呈现路由视图的。",[205,3663,3664,3667],{},[13,3665,3666],{},"中间件"," 则是在页面渲染前或者路由跳转时执行的逻辑，通常用来处理如权限验证、重定向、异步数据获取等。",[10,3669,3670],{},"比如这里，可以利用return navigateTo去进行重定向：",[50,3672,3674],{"className":2504,"code":3673,"language":2506,"meta":55,"style":55},"export default defineNuxtRouteMiddleware((to, from) => {\n    console.log(to.path, from)\n    console.log(\"拦截到了，上面是输出\")\n    return navigateTo(\"\u002Flist\")\n    \u002F\u002F重定向到list\n})\n",[33,3675,3676,3698,3706,3718,3732,3737],{"__ignoreMap":55},[59,3677,3678,3680,3682,3684,3686,3688,3690,3692,3694,3696],{"class":61,"line":62},[59,3679,292],{"class":65},[59,3681,295],{"class":65},[59,3683,2517],{"class":148},[59,3685,301],{"class":69},[59,3687,2522],{"class":304},[59,3689,2525],{"class":69},[59,3691,73],{"class":304},[59,3693,308],{"class":69},[59,3695,311],{"class":65},[59,3697,314],{"class":69},[59,3699,3700,3702,3704],{"class":61,"line":83},[59,3701,2538],{"class":69},[59,3703,322],{"class":148},[59,3705,2543],{"class":69},[59,3707,3708,3710,3712,3714,3716],{"class":61,"line":98},[59,3709,2538],{"class":69},[59,3711,322],{"class":148},[59,3713,185],{"class":69},[59,3715,2554],{"class":76},[59,3717,2557],{"class":69},[59,3719,3720,3723,3725,3727,3730],{"class":61,"line":113},[59,3721,3722],{"class":65},"    return",[59,3724,3358],{"class":148},[59,3726,185],{"class":69},[59,3728,3729],{"class":76},"\"\u002Flist\"",[59,3731,2557],{"class":69},[59,3733,3734],{"class":61,"line":128},[59,3735,3736],{"class":361},"    \u002F\u002F重定向到list\n",[59,3738,3739],{"class":61,"line":135},[59,3740,1415],{"class":69},[22,3742,3145,3744],{"id":3743},"_5-运行顺序客户端的详细流程",[13,3745,3746],{},"运行顺序（客户端的详细流程）：",[256,3748,3749,3752,3761,3766,3776,3783],{},[205,3750,3751],{},"浏览器发起路由请求，Nuxt 开始处理。",[205,3753,3754,3755,36,3757,3760],{},"执行",[13,3756,3244],{},[33,3758,3759],{},"middleware\u002F"," 下的配置）。",[205,3762,3754,3763,3765],{},[13,3764,3274],{},"（在页面组件内定义的）。",[205,3767,3768,3769,36,3771,3433,3773,3775],{},"如果是客户端渲染，执行客户端的",[13,3770,3396],{},[33,3772,3432],{},[33,3774,3436],{},"等）。",[205,3777,3778,3779,3782],{},"渲染页面的",[13,3780,3781],{},"组件","，更新页面显示。",[205,3784,3785],{},"页面渲染完成后，浏览器显示页面，用户看到最终内容。",[10,3787,3788],{},"这种结构使得 Nuxt 在处理路由跳转和页面渲染时，能够有效地管理数据和用户权限等，确保页面加载的流畅性与可控性。",[1579,3790,3792],{"id":3791},"seo优化","SEO优化",[10,3794,3795,3797],{},[13,3796,3792],{},"（Search Engine Optimization，搜索引擎优化）是指通过一系列的技术手段、内容策略以及用户体验的改进，提高网站在搜索引擎（如Google、Bing等）中的排名，从而增加网站的自然流量。SEO的目标是让你的网站更容易被搜索引擎抓取、理解和排名，从而让更多的潜在用户能够通过搜索引擎找到你的网站。",[22,3799,3801],{"id":3800},"seo优化的主要方面","SEO优化的主要方面",[256,3803,3804,3851,3876,3913],{},[205,3805,3806,3517,3809],{},[13,3807,3808],{},"站内优化（On-Page SEO）",[202,3810,3811,3817,3827,3833,3839,3845],{},[205,3812,3813,3816],{},[13,3814,3815],{},"关键词研究","：根据用户搜索习惯选择合适的关键词，确保网站内容包含这些关键词。",[205,3818,3819,3822,3823],{},[13,3820,3821],{},"标题标签和Meta描述","：为每个页面设置优化的标题标签（",[3824,3825,3826],"title",{},"）和Meta描述（meta description），使它们既有吸引力又包含目标关键词。",[205,3828,3829,3832],{},[13,3830,3831],{},"URL优化","：URL结构简洁、包含关键词且易于理解。",[205,3834,3835,3838],{},[13,3836,3837],{},"内容优化","：确保页面内容有价值、原创、富有信息性，并且合理地使用关键词。",[205,3840,3841,3844],{},[13,3842,3843],{},"图片优化","：图片需要有描述性的文件名和Alt属性，且优化图片大小以提高加载速度。",[205,3846,3847,3850],{},[13,3848,3849],{},"内部链接","：通过适当的内部链接结构，帮助搜索引擎更好地抓取和理解网站内容。",[205,3852,3853,3517,3856],{},[13,3854,3855],{},"站外优化（Off-Page SEO）",[202,3857,3858,3864,3870],{},[205,3859,3860,3863],{},[13,3861,3862],{},"外部链接（Backlinks）","：通过获得其他高质量网站的链接来增加网站的权威性和可信度。外部链接的质量和数量对排名影响较大。",[205,3865,3866,3869],{},[13,3867,3868],{},"社交媒体信号","：社交媒体的分享和互动可以间接影响搜索排名。",[205,3871,3872,3875],{},[13,3873,3874],{},"品牌建设","：提高品牌在网络上的知名度和信誉，增强网站的影响力。",[205,3877,3878,3517,3881],{},[13,3879,3880],{},"技术优化（Technical SEO）",[202,3882,3883,3889,3895,3901,3907],{},[205,3884,3885,3888],{},[13,3886,3887],{},"网站速度","：确保网站加载速度快，避免长时间等待，这对用户体验和搜索引擎排名都非常重要。",[205,3890,3891,3894],{},[13,3892,3893],{},"移动优化","：随着移动设备的普及，搜索引擎更倾向于优先考虑对移动设备友好的网站。",[205,3896,3897,3900],{},[13,3898,3899],{},"网站结构和导航","：清晰的网站结构和导航，确保搜索引擎能够高效地抓取网站内容。",[205,3902,3903,3906],{},[13,3904,3905],{},"XML站点地图","：创建并提交站点地图，帮助搜索引擎快速发现并抓取新内容。",[205,3908,3909,3912],{},[13,3910,3911],{},"Robots.txt文件","：通过设置robots.txt文件，控制哪些页面可以被搜索引擎抓取，哪些页面应当被忽略。",[205,3914,3915,3517,3917],{},[13,3916,3837],{},[202,3918,3919,3925],{},[205,3920,3921,3924],{},[13,3922,3923],{},"更新内容","：保持网站内容的新鲜度，定期更新，以符合用户和搜索引擎对新信息的需求。",[205,3926,3927,3930],{},[13,3928,3929],{},"长尾关键词","：除了热门关键词，还可以针对较长的、细分的搜索词进行优化。这些关键词的竞争通常较小，但也能带来流量。",[22,3932,3934],{"id":3933},"seo优化的重要性","SEO优化的重要性",[202,3936,3937,3946,3952,3961],{},[205,3938,3939,3942,3943,2799],{},[13,3940,3941],{},"提高可见性","：良好的SEO优化能",[13,3944,3945],{},"帮助你的网站在搜索引擎结果页面（SERP）中排名靠前，从而吸引更多的用户访问",[205,3947,3948,3951],{},[13,3949,3950],{},"增加流量","：通过搜索引擎获得自然流量，而不需要依赖广告或其他营销手段。",[205,3953,3954,3957,3958,2799],{},[13,3955,3956],{},"增强用户体验","：SEO优化",[13,3959,3960],{},"不仅能提升网站排名，还能改善用户体验，提升网站的加载速度、易用性和内容质量",[205,3962,3963,3966,3967,2799],{},[13,3964,3965],{},"提升转化率","：排名靠前的网站",[13,3968,3969],{},"更可能吸引到高质量的访客，进而提高转化率（如购买、注册等）",[1579,3971,3972],{"id":3972},"composables文件夹",[10,3974,3975,3976,3979,3980,3983,3984,3987],{},"在 Nuxt 3 中，",[33,3977,3978],{},"composables"," 文件夹是用来存放 ",[13,3981,3982],{},"Composition API"," 相关代码的地方，主要用于存放可复用的功能逻辑，通常以 ",[13,3985,3986],{},"函数"," 的形式进行定义。这样的设计使得你可以在多个组件中重用代码，从而提高代码的可维护性和可复用性。",[22,3989,3034,3991],{"id":3990},"_1-什么是-composables",[13,3992,3993],{},"什么是 Composables？",[10,3995,3996,3999],{},[13,3997,3998],{},"Composables"," 是使用 Vue 3 的 Composition API 来封装可复用的逻辑函数。这些函数可以包含 reactive 状态、生命周期钩子、计算属性、方法等，且可以在组件中被引用。",[22,4001,3063,4003],{"id":4002},"_2-composables-的用途",[13,4004,4005],{},"Composables 的用途",[202,4007,4008,4014,4020],{},[205,4009,4010,4013],{},[13,4011,4012],{},"逻辑复用","：将某些逻辑封装在一个函数中，可以在多个组件中共享和复用。",[205,4015,4016,4019],{},[13,4017,4018],{},"提高可维护性","：避免将业务逻辑混杂在组件的模板或脚本部分，使得代码更加清晰易维护。",[205,4021,4022,4025],{},[13,4023,4024],{},"按需引入","：可以按需在组件中导入使用，不会造成不必要的加载。",[22,4027,3096,4029],{"id":4028},"_3-在-composables-文件夹中如何定义函数",[13,4030,416,4031,4033],{},[33,4032,3978],{}," 文件夹中如何定义函数",[10,4035,4036,4037,4039],{},"​\t你可以在 ",[33,4038,3978],{}," 文件夹中定义很多功能函数（例如 API 请求、状态管理、逻辑处理等），然后在组件中通过导入的方式使用。",[22,4041,3124,4043],{"id":4042},"_4-举个例子",[13,4044,4045],{},"举个例子：",[10,4047,4048,4049,4052,4053,4055,4056,2799],{},"​\t假设你有一个需求，需要在多个页面中",[13,4050,4051],{},"使用相同的逻辑去获取 API 数据","，你可以在 ",[33,4054,3978],{}," 文件夹中",[13,4057,4058],{},"创建一个函数来进行封装",[10,4060,4061],{},"​\t但是nuxt只会扫面一层目录去全局导入和使用，如果有多个文件夹，就需要导入，而不会被自动注册。",[1579,4063,4064],{"id":4064},"fetch方法",[10,4066,2204,4067,4070,4071,2210,4074,4077],{},[33,4068,4069],{},"$fetch"," 是 Nuxt 3 提供的一个用来发起 HTTP 请求的函数，作为一个更简单且灵活的方式替代传统的 ",[33,4072,4073],{},"axios",[33,4075,4076],{},"fetch"," API。它内部封装了很多常见的功能，如自动处理请求拦截、错误处理和响应处理等。",[10,4079,4080,4081,4083],{},"​\t在 Nuxt 3 中，你可以通过 ",[33,4082,4069],{}," 方法来发送 API 请求。",[10,4085,4086,4089,4090,4092],{},[13,4087,4088],{},"GET 请求","：\n使用 ",[33,4091,4069],{}," 方法发起 GET 请求时，只需要传递请求的 URL。",[50,4094,4096],{"className":2504,"code":4095,"language":2506,"meta":55,"style":55},"\u002F\u002F Example of using $fetch in a composable or component\nconst data = await $fetch('https:\u002F\u002Fapi.example.com\u002Fdata')\nconsole.log(data)\n\n",[33,4097,4098,4103,4125],{"__ignoreMap":55},[59,4099,4100],{"class":61,"line":62},[59,4101,4102],{"class":361},"\u002F\u002F Example of using $fetch in a composable or component\n",[59,4104,4105,4107,4110,4112,4115,4118,4120,4123],{"class":61,"line":83},[59,4106,138],{"class":65},[59,4108,4109],{"class":141}," data",[59,4111,145],{"class":65},[59,4113,4114],{"class":65}," await",[59,4116,4117],{"class":148}," $fetch",[59,4119,185],{"class":69},[59,4121,4122],{"class":76},"'https:\u002F\u002Fapi.example.com\u002Fdata'",[59,4124,2557],{"class":69},[59,4126,4127,4129,4131],{"class":61,"line":98},[59,4128,1500],{"class":69},[59,4130,322],{"class":148},[59,4132,4133],{"class":69},"(data)\n",[10,4135,4136,4139,4140,4142],{},[13,4137,4138],{},"POST 请求","：\n通过 ",[33,4141,4069],{}," 发送 POST 请求时，你可以传递一个对象来指定请求的选项。",[50,4144,4146],{"className":2504,"code":4145,"language":2506,"meta":55,"style":55},"const data = await $fetch('https:\u002F\u002Fapi.example.com\u002Fdata', {\n  method: 'POST',\n  body: {\n    key1: 'value1',\n    key2: 'value2'\n  }\n})\nconsole.log(data)\n",[33,4147,4148,4167,4177,4182,4192,4200,4204,4208],{"__ignoreMap":55},[59,4149,4150,4152,4154,4156,4158,4160,4162,4164],{"class":61,"line":62},[59,4151,138],{"class":65},[59,4153,4109],{"class":141},[59,4155,145],{"class":65},[59,4157,4114],{"class":65},[59,4159,4117],{"class":148},[59,4161,185],{"class":69},[59,4163,4122],{"class":76},[59,4165,4166],{"class":69},", {\n",[59,4168,4169,4172,4175],{"class":61,"line":83},[59,4170,4171],{"class":69},"  method: ",[59,4173,4174],{"class":76},"'POST'",[59,4176,915],{"class":69},[59,4178,4179],{"class":61,"line":98},[59,4180,4181],{"class":69},"  body: {\n",[59,4183,4184,4187,4190],{"class":61,"line":113},[59,4185,4186],{"class":69},"    key1: ",[59,4188,4189],{"class":76},"'value1'",[59,4191,915],{"class":69},[59,4193,4194,4197],{"class":61,"line":128},[59,4195,4196],{"class":69},"    key2: ",[59,4198,4199],{"class":76},"'value2'\n",[59,4201,4202],{"class":61,"line":135},[59,4203,1410],{"class":69},[59,4205,4206],{"class":61,"line":155},[59,4207,1415],{"class":69},[59,4209,4210,4212,4214],{"class":61,"line":167},[59,4211,1500],{"class":69},[59,4213,322],{"class":148},[59,4215,4133],{"class":69},[22,4217,4219],{"id":4218},"配置选项","配置选项：",[10,4221,4222,4223,4225,4226,2799],{},"你可以通过 ",[33,4224,4069],{}," 传递配置对象来控制请求的其他方面，比如",[13,4227,4228],{},"请求头、请求体、超时等",[202,4230,4231,4250,4256,4265,4271],{},[205,4232,4233,4236,4237,2525,4240,2525,4243,2525,4246,4249],{},[33,4234,4235],{},"method",": HTTP 方法（如 ",[33,4238,4239],{},"GET",[33,4241,4242],{},"POST",[33,4244,4245],{},"PUT",[33,4247,4248],{},"DELETE"," 等）。",[205,4251,4252,4255],{},[33,4253,4254],{},"headers",": 请求头，作为对象传递。",[205,4257,4258,4261,4262,4264],{},[33,4259,4260],{},"body",": 请求体，用于 ",[33,4263,4242],{}," 或其他请求。",[205,4266,4267,4270],{},[33,4268,4269],{},"params",": URL 参数，等效于查询字符串。",[205,4272,4273,4276],{},[33,4274,4275],{},"timeout",": 请求超时时间，单位为毫秒。",[1579,4278,4279],{"id":4279},"layout布局",[10,4281,4282],{},"可以解放app.vue 把样式布局扔在这个\u002Flayouts文件夹里定义的vue文件里。",[4284,4285],"nuxt-page",{},[10,4287,4288,4289],{},"而在app.vue里则使用",[4284,4290,4291],{},"标签，意思就是default.vue里的样式。",[10,4293,4294,4295,4298,4299],{},"请注意，如果app.vue这个",[13,4296,4297],{},"父组件","里使用",[4300,4301,4302,4303,4306,4307],"nuxt-layout",{},"标签去",[13,4304,4305],{},"包裹","上面的",[4284,4308,4309],{},"标签，那么会强制使用default.vue的样式。",[10,4311,4312],{},[1574,4313],{"alt":4314,"src":4315},"image-20250223211908547","image-20250223211908547.png",[10,4317,4318],{},"这种方法可以设置一个独立的页面而不受default的影响。",[1579,4320,4321],{"id":4321},"nuxt的自定义hooks",[10,4323,4324,4325,4328,4329,4331],{},"​\t.js的hooks放在\u002Fplugins文件夹里，并且：使用 ",[33,4326,4327],{},"defineNuxtPlugin"," 包裹。在 Nuxt 3 中，推荐将插件包裹在 ",[33,4330,4327],{}," 中，这样可以让 Nuxt 更好地识别和管理插件，并为未来可能的增强功能提供支持。",[10,4333,4334],{},"比如：",[50,4336,4338],{"className":2504,"code":4337,"language":2506,"meta":55,"style":55},"\u002F\u002F plugins\u002FuseAxios.js\nimport axios from 'axios'\n\nexport default defineNuxtPlugin(nuxtApp => {\n  \u002F\u002F 你可以在这里进行插件的初始化逻辑，例如配置 axios 实例等\n  const api_get = async (url) => {\n    try {\n      const response = await axios.get(url)\n      return response.data\n    } catch (error) {\n      console.error('请求错误:', error)\n      throw error\n    }\n  }\n\n  \u002F\u002F 在 Nuxt 应用中注入 axios\n  nuxtApp.provide('api_get', api_get)\n})\n\n",[33,4339,4340,4345,4357,4361,4378,4383,4406,4413,4434,4442,4453,4468,4476,4480,4484,4488,4493,4509],{"__ignoreMap":55},[59,4341,4342],{"class":61,"line":62},[59,4343,4344],{"class":361},"\u002F\u002F plugins\u002FuseAxios.js\n",[59,4346,4347,4349,4352,4354],{"class":61,"line":83},[59,4348,66],{"class":65},[59,4350,4351],{"class":69}," axios ",[59,4353,73],{"class":65},[59,4355,4356],{"class":76}," 'axios'\n",[59,4358,4359],{"class":61,"line":98},[59,4360,132],{"emptyLinePlaceholder":131},[59,4362,4363,4365,4367,4369,4371,4373,4376],{"class":61,"line":113},[59,4364,292],{"class":65},[59,4366,295],{"class":65},[59,4368,298],{"class":148},[59,4370,185],{"class":69},[59,4372,305],{"class":304},[59,4374,4375],{"class":65}," =>",[59,4377,314],{"class":69},[59,4379,4380],{"class":61,"line":128},[59,4381,4382],{"class":361},"  \u002F\u002F 你可以在这里进行插件的初始化逻辑，例如配置 axios 实例等\n",[59,4384,4385,4387,4390,4392,4395,4397,4400,4402,4404],{"class":61,"line":135},[59,4386,560],{"class":65},[59,4388,4389],{"class":148}," api_get",[59,4391,145],{"class":65},[59,4393,4394],{"class":65}," async",[59,4396,2895],{"class":69},[59,4398,4399],{"class":304},"url",[59,4401,308],{"class":69},[59,4403,311],{"class":65},[59,4405,314],{"class":69},[59,4407,4408,4411],{"class":61,"line":155},[59,4409,4410],{"class":65},"    try",[59,4412,314],{"class":69},[59,4414,4415,4418,4421,4423,4425,4428,4431],{"class":61,"line":167},[59,4416,4417],{"class":65},"      const",[59,4419,4420],{"class":141}," response",[59,4422,145],{"class":65},[59,4424,4114],{"class":65},[59,4426,4427],{"class":69}," axios.",[59,4429,4430],{"class":148},"get",[59,4432,4433],{"class":69},"(url)\n",[59,4435,4436,4439],{"class":61,"line":177},[59,4437,4438],{"class":65},"      return",[59,4440,4441],{"class":69}," response.data\n",[59,4443,4444,4447,4450],{"class":61,"line":578},[59,4445,4446],{"class":69},"    } ",[59,4448,4449],{"class":65},"catch",[59,4451,4452],{"class":69}," (error) {\n",[59,4454,4455,4458,4460,4462,4465],{"class":61,"line":584},[59,4456,4457],{"class":69},"      console.",[59,4459,2954],{"class":148},[59,4461,185],{"class":69},[59,4463,4464],{"class":76},"'请求错误:'",[59,4466,4467],{"class":69},", error)\n",[59,4469,4470,4473],{"class":61,"line":590},[59,4471,4472],{"class":65},"      throw",[59,4474,4475],{"class":69}," error\n",[59,4477,4478],{"class":61,"line":595},[59,4479,1843],{"class":69},[59,4481,4482],{"class":61,"line":606},[59,4483,1410],{"class":69},[59,4485,4486],{"class":61,"line":966},[59,4487,132],{"emptyLinePlaceholder":131},[59,4489,4490],{"class":61,"line":985},[59,4491,4492],{"class":361},"  \u002F\u002F 在 Nuxt 应用中注入 axios\n",[59,4494,4495,4498,4501,4503,4506],{"class":61,"line":998},[59,4496,4497],{"class":69},"  nuxtApp.",[59,4499,4500],{"class":148},"provide",[59,4502,185],{"class":69},[59,4504,4505],{"class":76},"'api_get'",[59,4507,4508],{"class":69},", api_get)\n",[59,4510,4511],{"class":61,"line":1003},[59,4512,1415],{"class":69},[2049,4514,4515],{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}",{"title":55,"searchDepth":83,"depth":83,"links":4517},[4518,4520,4522,4524,4526,4527,4528,4529,4530,4534,4562,4566,4576,4579,4580],{"id":24,"depth":98,"text":4519},"🚀 Nuxt 项目的入口文件差异：",{"id":244,"depth":98,"text":4521},"🌟 *Nuxt 的等效入口机制",{"id":427,"depth":98,"text":4523},"🚀 Nuxt 3 安装 Vuetify",{"id":1073,"depth":98,"text":4525},"🧑‍💻 nuxt.config.ts 配置项总结",{"id":1208,"depth":98,"text":4525},{"id":1581,"depth":83,"text":1582},{"id":1594,"depth":83,"text":1594},{"id":2094,"depth":83,"text":2095},{"id":2193,"depth":83,"text":2194,"children":4531},[4532],{"id":2221,"depth":98,"text":4533},"如何使用 useRuntimeConfig：",{"id":2376,"depth":83,"text":2376,"children":4535},[4536,4537,4538,4539,4540,4541,4543,4545,4547,4549,4551,4552,4554,4556,4558,4560],{"id":2495,"depth":98,"text":2495},{"id":2564,"depth":98,"text":2565},{"id":2605,"depth":98,"text":2606},{"id":2752,"depth":98,"text":2753},{"id":2768,"depth":98,"text":2768},{"id":3033,"depth":98,"text":4542},"1. 存储方式：",{"id":3062,"depth":98,"text":4544},"2. 存储大小：",{"id":3095,"depth":98,"text":4546},"3. 持久性：",{"id":3123,"depth":98,"text":4548},"4. 发送机制：",{"id":3144,"depth":98,"text":4550},"5. 跨域访问：",{"id":3176,"depth":98,"text":3177},{"id":3206,"depth":98,"text":4553},"1. 路由请求和中间件触发的顺序",{"id":3493,"depth":98,"text":4555},"2. 客户端加载的详细过程：",{"id":3589,"depth":98,"text":4557},"3. 总结：页面加载生命周期",{"id":3646,"depth":98,"text":4559},"4. App.vue 和 中间件的关系",{"id":3743,"depth":98,"text":4561},"5. 运行顺序（客户端的详细流程）：",{"id":3791,"depth":83,"text":3792,"children":4563},[4564,4565],{"id":3800,"depth":98,"text":3801},{"id":3933,"depth":98,"text":3934},{"id":3972,"depth":83,"text":3972,"children":4567},[4568,4570,4572,4574],{"id":3990,"depth":98,"text":4569},"1. 什么是 Composables？",{"id":4002,"depth":98,"text":4571},"2. Composables 的用途",{"id":4028,"depth":98,"text":4573},"3. 在 composables 文件夹中如何定义函数",{"id":4042,"depth":98,"text":4575},"4. 举个例子：",{"id":4064,"depth":83,"text":4064,"children":4577},[4578],{"id":4218,"depth":98,"text":4219},{"id":4279,"depth":83,"text":4279},{"id":4321,"depth":83,"text":4321},"Nuxt 项目和传统的约定优于配置的理念，大大简化了项目结构","md",{},"\u002Fvue\u002Fnuxt\u002Fnuxt和vuetify",{"description":4581},"Vue\u002FNuxt\u002Fnuxt和vuetify","APd2ixK7CuwQL3DBg2L3BDwmE8K5Eer7L5jV9WFBnFk",1791042467720]