[{"data":1,"prerenderedAt":3506},["ShallowReactive",2],{"article-/topics/nuxt/nuxt-data-fetching-guide":3,"related-nuxt":675,"content-query-7DmfnY65qA":2976},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"topic":5,"author":11,"tags":12,"image":18,"featured":19,"readingTime":20,"body":21,"_type":669,"_id":670,"_source":671,"_file":672,"_stem":673,"_extension":674},"/topics/nuxt/nuxt-data-fetching-guide","nuxt",false,"","Nuxt 服务端数据获取完全指南 - useFetch 与 useAsyncData 深度解析","深入讲解 Nuxt 3 的数据获取机制，包括 useFetch、useAsyncData、$fetch 的使用场景、区别和最佳实践。提供完整的代码示例和性能优化技巧。","2025-12-24","HTMLPAGE 团队",[13,14,15,16,17],"Nuxt 3","useFetch","useAsyncData","SSR","数据获取","/images/topics/nuxt-data-fetching.jpg",true,12,{"type":22,"children":23,"toc":625},"root",[24,33,38,67,72,79,88,93,101,107,112,123,128,137,142,151,156,165,171,176,185,190,199,204,213,219,224,235,240,249,255,260,269,275,286,291,300,305,310,319,324,333,338,347,352,361,366,372,381,386,395,400,409,414,453,476,486,496,501,506,538,546,575,580],{"type":25,"tag":26,"props":27,"children":29},"element","h2",{"id":28},"nuxt-服务端数据获取完全指南",[30],{"type":31,"value":32},"text","Nuxt 服务端数据获取完全指南",{"type":25,"tag":26,"props":34,"children":36},{"id":35},"概述",[37],{"type":31,"value":35},{"type":25,"tag":39,"props":40,"children":41},"p",{},[42,44,50,52,57,59,65],{"type":31,"value":43},"数据获取是 Nuxt 应用的核心功能。Nuxt 3 提供了 ",{"type":25,"tag":45,"props":46,"children":48},"code",{"className":47},[],[49],{"type":31,"value":14},{"type":31,"value":51},"、",{"type":25,"tag":45,"props":53,"children":55},{"className":54},[],[56],{"type":31,"value":15},{"type":31,"value":58}," 和 ",{"type":25,"tag":45,"props":60,"children":62},{"className":61},[],[63],{"type":31,"value":64},"$fetch",{"type":31,"value":66}," 三种数据获取方式，它们在服务端和客户端的行为有所不同。正确使用这些工具可以实现高效的 SSR 数据预取，避免水合不匹配问题。",{"type":25,"tag":26,"props":68,"children":70},{"id":69},"核心概念",[71],{"type":31,"value":69},{"type":25,"tag":73,"props":74,"children":76},"h3",{"id":75},"nuxt-数据获取体系",[77],{"type":31,"value":78},"Nuxt 数据获取体系",{"type":25,"tag":80,"props":81,"children":83},"pre",{"code":82},"Nuxt 3 数据获取工具对比\n\nuseFetch\n├── 封装了 useAsyncData + $fetch\n├── 适合：获取 API 数据\n├── 自动处理：SSR、缓存、去重\n└── 最常用的数据获取方式\n\nuseAsyncData\n├── 通用的异步数据获取\n├── 适合：非 HTTP 请求的异步操作\n├── 可自定义：获取逻辑\n└── 更灵活的控制\n\n$fetch\n├── 基于 ofetch 的 HTTP 客户端\n├── 适合：事件处理器、非组件代码\n├── 无 SSR 集成：不会自动传输到客户端\n└── 轻量级请求\n",[84],{"type":25,"tag":45,"props":85,"children":86},{"__ignoreMap":7},[87],{"type":31,"value":82},{"type":25,"tag":73,"props":89,"children":91},{"id":90},"服务端渲染中的数据流",[92],{"type":31,"value":90},{"type":25,"tag":80,"props":94,"children":96},{"code":95},"SSR 数据获取流程\n\n服务端\n├── 1. 接收请求\n├── 2. 执行 useFetch/useAsyncData\n├── 3. 等待数据返回\n├── 4. 使用数据渲染 HTML\n├── 5. 将数据序列化到 payload\n└── 6. 发送 HTML + payload\n\n客户端（水合）\n├── 1. 接收 HTML\n├── 2. 解析 payload\n├── 3. useFetch/useAsyncData 直接使用 payload\n├── 4. 无需重复请求\n└── 5. 完成水合\n",[97],{"type":25,"tag":45,"props":98,"children":99},{"__ignoreMap":7},[100],{"type":31,"value":95},{"type":25,"tag":26,"props":102,"children":104},{"id":103},"usefetch-详解",[105],{"type":31,"value":106},"useFetch 详解",{"type":25,"tag":73,"props":108,"children":110},{"id":109},"基本用法",[111],{"type":31,"value":109},{"type":25,"tag":80,"props":113,"children":118},{"code":114,"language":115,"meta":7,"className":116},"\u003Cscript setup>\n// 基础用法\nconst { data, pending, error, refresh } = await useFetch('/api/users')\n\n// 带参数\nconst { data: user } = await useFetch(`/api/users/${userId}`)\n\n// 完整配置\nconst { data, pending, error, refresh, status } = await useFetch('/api/posts', {\n  // 请求方法\n  method: 'GET',\n  \n  // 查询参数\n  query: {\n    page: 1,\n    limit: 10\n  },\n  \n  // 请求头\n  headers: {\n    'Authorization': `Bearer ${token}`\n  },\n  \n  // 请求体（POST/PUT）\n  body: {\n    title: 'New Post'\n  },\n  \n  // 缓存键（用于去重和缓存）\n  key: 'posts-page-1',\n  \n  // 只在服务端获取\n  server: true,\n  \n  // 懒加载（不阻塞导航）\n  lazy: false,\n  \n  // 立即执行（默认 true）\n  immediate: true,\n  \n  // 数据转换\n  transform: (data) => data.items,\n  \n  // 默认值\n  default: () => []\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cdiv v-if=\"pending\">加载中...\u003C/div>\n    \u003Cdiv v-else-if=\"error\">错误: {{ error.message }}\u003C/div>\n    \u003Cul v-else>\n      \u003Cli v-for=\"post in data\" :key=\"post.id\">{{ post.title }}\u003C/li>\n    \u003C/ul>\n  \u003C/div>\n\u003C/template>\n","vue",[117],"language-vue",[119],{"type":25,"tag":45,"props":120,"children":121},{"__ignoreMap":7},[122],{"type":31,"value":114},{"type":25,"tag":73,"props":124,"children":126},{"id":125},"响应式参数",[127],{"type":31,"value":125},{"type":25,"tag":80,"props":129,"children":132},{"code":130,"language":115,"meta":7,"className":131},"\u003Cscript setup>\nconst page = ref(1)\nconst category = ref('all')\n\n// 方法 1：使用函数返回 URL\nconst { data: posts } = await useFetch(() => `/api/posts?page=${page.value}`)\n\n// 方法 2：使用响应式 query\nconst { data: articles } = await useFetch('/api/articles', {\n  query: {\n    page,        // 直接使用 ref\n    category,    // 会自动追踪变化\n    limit: 10\n  }\n})\n\n// 方法 3：使用计算属性\nconst apiUrl = computed(() => `/api/users/${userId.value}/posts`)\nconst { data: userPosts } = await useFetch(apiUrl)\n\n// 当参数变化时，会自动重新获取数据\nfunction nextPage() {\n  page.value++  // 自动触发请求\n}\n\u003C/script>\n",[117],[133],{"type":25,"tag":45,"props":134,"children":135},{"__ignoreMap":7},[136],{"type":31,"value":130},{"type":25,"tag":73,"props":138,"children":140},{"id":139},"请求拦截",[141],{"type":31,"value":139},{"type":25,"tag":80,"props":143,"children":146},{"code":144,"language":115,"meta":7,"className":145},"\u003Cscript setup>\nconst { data } = await useFetch('/api/protected', {\n  // 请求前拦截\n  onRequest({ request, options }) {\n    // 添加认证头\n    options.headers = options.headers || {}\n    options.headers.Authorization = `Bearer ${useAuthToken().value}`\n    \n    console.log('发起请求:', request)\n  },\n  \n  // 请求错误拦截\n  onRequestError({ request, error }) {\n    console.error('请求失败:', error)\n  },\n  \n  // 响应拦截\n  onResponse({ response }) {\n    // 处理响应\n    console.log('响应状态:', response.status)\n  },\n  \n  // 响应错误拦截\n  onResponseError({ response }) {\n    if (response.status === 401) {\n      // 跳转到登录页\n      navigateTo('/login')\n    }\n  }\n})\n\u003C/script>\n",[117],[147],{"type":25,"tag":45,"props":148,"children":149},{"__ignoreMap":7},[150],{"type":31,"value":144},{"type":25,"tag":73,"props":152,"children":154},{"id":153},"条件获取",[155],{"type":31,"value":153},{"type":25,"tag":80,"props":157,"children":160},{"code":158,"language":115,"meta":7,"className":159},"\u003Cscript setup>\nconst userId = ref(null)\n\n// 只有当 userId 存在时才获取\nconst { data: user } = await useFetch(() => `/api/users/${userId.value}`, {\n  // 控制是否立即执行\n  immediate: !!userId.value,\n  \n  // 使用 watch 选项控制\n  watch: [userId]\n})\n\n// 或使用 watch: false 完全禁用自动获取\nconst { data: profile, execute } = await useFetch('/api/profile', {\n  immediate: false,\n  watch: false\n})\n\n// 手动触发\nfunction loadProfile() {\n  execute()\n}\n\u003C/script>\n",[117],[161],{"type":25,"tag":45,"props":162,"children":163},{"__ignoreMap":7},[164],{"type":31,"value":158},{"type":25,"tag":26,"props":166,"children":168},{"id":167},"useasyncdata-详解",[169],{"type":31,"value":170},"useAsyncData 详解",{"type":25,"tag":73,"props":172,"children":174},{"id":173},"基本用法-1",[175],{"type":31,"value":109},{"type":25,"tag":80,"props":177,"children":180},{"code":178,"language":115,"meta":7,"className":179},"\u003Cscript setup>\n// 基础用法\nconst { data, pending, error, refresh } = await useAsyncData(\n  'users',  // 唯一键\n  () => $fetch('/api/users')  // 异步函数\n)\n\n// 完整配置\nconst { data, pending, error, refresh, status } = await useAsyncData(\n  'posts',\n  async () => {\n    const posts = await $fetch('/api/posts')\n    const comments = await $fetch('/api/comments')\n    return { posts, comments }\n  },\n  {\n    // 缓存键（可选，默认使用第一个参数）\n    key: 'posts-with-comments',\n    \n    // 只在服务端执行\n    server: true,\n    \n    // 懒加载\n    lazy: false,\n    \n    // 立即执行\n    immediate: true,\n    \n    // 数据转换\n    transform: (result) => result.posts,\n    \n    // 选择性获取（优化 payload 大小）\n    pick: ['id', 'title', 'summary'],\n    \n    // 默认值\n    default: () => ({ posts: [], comments: [] }),\n    \n    // 监听依赖\n    watch: [someRef]\n  }\n)\n\u003C/script>\n",[117],[181],{"type":25,"tag":45,"props":182,"children":183},{"__ignoreMap":7},[184],{"type":31,"value":178},{"type":25,"tag":73,"props":186,"children":188},{"id":187},"复杂数据获取场景",[189],{"type":31,"value":187},{"type":25,"tag":80,"props":191,"children":194},{"code":192,"language":115,"meta":7,"className":193},"\u003Cscript setup>\n// 场景 1：聚合多个 API\nconst { data: dashboard } = await useAsyncData('dashboard', async () => {\n  const [stats, recentOrders, topProducts] = await Promise.all([\n    $fetch('/api/stats'),\n    $fetch('/api/orders/recent'),\n    $fetch('/api/products/top')\n  ])\n  \n  return { stats, recentOrders, topProducts }\n})\n\n// 场景 2：依赖其他数据\nconst { data: user } = await useFetch('/api/user')\n\nconst { data: userPosts } = await useAsyncData(\n  'user-posts',\n  () => $fetch(`/api/users/${user.value.id}/posts`),\n  {\n    watch: [user],\n    immediate: !!user.value\n  }\n)\n\n// 场景 3：非 HTTP 异步操作\nconst { data: config } = await useAsyncData('config', async () => {\n  // 从本地存储或其他来源获取\n  if (process.server) {\n    return await readServerConfig()\n  }\n  return loadClientConfig()\n})\n\u003C/script>\n",[117],[195],{"type":25,"tag":45,"props":196,"children":197},{"__ignoreMap":7},[198],{"type":31,"value":192},{"type":25,"tag":73,"props":200,"children":202},{"id":201},"缓存策略",[203],{"type":31,"value":201},{"type":25,"tag":80,"props":205,"children":208},{"code":206,"language":115,"meta":7,"className":207},"\u003Cscript setup>\n// getCachedData 允许自定义缓存行为\nconst { data } = await useAsyncData('cached-data', \n  () => $fetch('/api/data'),\n  {\n    getCachedData(key) {\n      // 返回 undefined 表示需要重新获取\n      // 返回数据表示使用缓存\n      \n      const nuxtApp = useNuxtApp()\n      const cachedData = nuxtApp.payload.data[key] || nuxtApp.static.data[key]\n      \n      if (!cachedData) {\n        return undefined\n      }\n      \n      // 检查缓存是否过期（示例：1 小时）\n      const expirationTime = 60 * 60 * 1000\n      const now = Date.now()\n      \n      if (cachedData._fetchedAt && now - cachedData._fetchedAt > expirationTime) {\n        return undefined\n      }\n      \n      return cachedData\n    },\n    \n    transform(data) {\n      return {\n        ...data,\n        _fetchedAt: Date.now()\n      }\n    }\n  }\n)\n\u003C/script>\n",[117],[209],{"type":25,"tag":45,"props":210,"children":211},{"__ignoreMap":7},[212],{"type":31,"value":206},{"type":25,"tag":26,"props":214,"children":216},{"id":215},"usefetch-vs-useasyncdata",[217],{"type":31,"value":218},"useFetch vs useAsyncData",{"type":25,"tag":73,"props":220,"children":222},{"id":221},"选择指南",[223],{"type":31,"value":221},{"type":25,"tag":80,"props":225,"children":230},{"code":226,"language":227,"meta":7,"className":228},"// 选择决策树\nconst chooseDataFetchMethod = {\n  // 使用 useFetch 的场景\n  useFetch: [\n    '获取 REST API 数据',\n    '简单的 CRUD 操作',\n    '需要自动处理 baseURL',\n    '大多数标准数据获取场景'\n  ],\n\n  // 使用 useAsyncData 的场景\n  useAsyncData: [\n    '需要聚合多个请求',\n    '非 HTTP 异步操作',\n    '需要自定义获取逻辑',\n    '需要更细粒度的控制'\n  ],\n\n  // 使用 $fetch 的场景\n  '$fetch': [\n    '事件处理器中的请求',\n    '不需要 SSR 的客户端请求',\n    '非组件代码（utils、stores）',\n    '服务端 API 路由中'\n  ]\n}\n","javascript",[229],"language-javascript",[231],{"type":25,"tag":45,"props":232,"children":233},{"__ignoreMap":7},[234],{"type":31,"value":226},{"type":25,"tag":73,"props":236,"children":238},{"id":237},"代码对比",[239],{"type":31,"value":237},{"type":25,"tag":80,"props":241,"children":244},{"code":242,"language":115,"meta":7,"className":243},"\u003Cscript setup>\n// 场景：获取用户列表\n\n// 方式 1：useFetch（推荐）\nconst { data: users } = await useFetch('/api/users')\n\n// 方式 2：useAsyncData + $fetch（等效）\nconst { data: users2 } = await useAsyncData(\n  'users',\n  () => $fetch('/api/users')\n)\n\n// 场景：复杂数据获取\n\n// 方式 1：useAsyncData（更适合）\nconst { data: dashboard } = await useAsyncData('dashboard', async () => {\n  const [users, orders, stats] = await Promise.all([\n    $fetch('/api/users'),\n    $fetch('/api/orders'),\n    $fetch('/api/stats')\n  ])\n  return { users, orders, stats }\n})\n\n// 方式 2：多个 useFetch（并行但独立）\nconst { data: users } = useFetch('/api/users')\nconst { data: orders } = useFetch('/api/orders')\nconst { data: stats } = useFetch('/api/stats')\n// 需要等待所有完成\nawait Promise.all([users, orders, stats])\n\u003C/script>\n",[117],[245],{"type":25,"tag":45,"props":246,"children":247},{"__ignoreMap":7},[248],{"type":31,"value":242},{"type":25,"tag":26,"props":250,"children":252},{"id":251},"fetch-使用场景",[253],{"type":31,"value":254},"$fetch 使用场景",{"type":25,"tag":73,"props":256,"children":258},{"id":257},"事件处理中使用",[259],{"type":31,"value":257},{"type":25,"tag":80,"props":261,"children":264},{"code":262,"language":115,"meta":7,"className":263},"\u003Cscript setup>\nconst loading = ref(false)\n\n// 事件处理器中使用 $fetch\nasync function submitForm(formData) {\n  loading.value = true\n  \n  try {\n    const result = await $fetch('/api/submit', {\n      method: 'POST',\n      body: formData\n    })\n    \n    // 处理成功\n    console.log('提交成功:', result)\n  } catch (error) {\n    // 处理错误\n    console.error('提交失败:', error)\n  } finally {\n    loading.value = false\n  }\n}\n\n// 删除操作\nasync function deleteItem(id) {\n  await $fetch(`/api/items/${id}`, {\n    method: 'DELETE'\n  })\n  \n  // 刷新列表\n  await refreshItems()\n}\n\u003C/script>\n",[117],[265],{"type":25,"tag":45,"props":266,"children":267},{"__ignoreMap":7},[268],{"type":31,"value":262},{"type":25,"tag":73,"props":270,"children":272},{"id":271},"服务端-api-路由中使用",[273],{"type":31,"value":274},"服务端 API 路由中使用",{"type":25,"tag":80,"props":276,"children":281},{"code":277,"language":278,"meta":7,"className":279},"// server/api/aggregate.ts\nexport default defineEventHandler(async (event) => {\n  // 在服务端 API 中使用 $fetch 请求其他服务\n  const [users, products] = await Promise.all([\n    $fetch('https://api.example.com/users'),\n    $fetch('https://api.example.com/products')\n  ])\n\n  return {\n    users,\n    products,\n    timestamp: Date.now()\n  }\n})\n","typescript",[280],"language-typescript",[282],{"type":25,"tag":45,"props":283,"children":284},{"__ignoreMap":7},[285],{"type":31,"value":277},{"type":25,"tag":73,"props":287,"children":289},{"id":288},"工具函数中使用",[290],{"type":31,"value":288},{"type":25,"tag":80,"props":292,"children":295},{"code":293,"language":278,"meta":7,"className":294},"// utils/api.ts\nexport const api = {\n  async getUsers(params?: { page?: number; limit?: number }) {\n    return await $fetch('/api/users', {\n      query: params\n    })\n  },\n\n  async createUser(userData: CreateUserInput) {\n    return await $fetch('/api/users', {\n      method: 'POST',\n      body: userData\n    })\n  },\n\n  async updateUser(id: string, userData: UpdateUserInput) {\n    return await $fetch(`/api/users/${id}`, {\n      method: 'PUT',\n      body: userData\n    })\n  },\n\n  async deleteUser(id: string) {\n    return await $fetch(`/api/users/${id}`, {\n      method: 'DELETE'\n    })\n  }\n}\n\n// 在组件中使用\n// const users = await api.getUsers({ page: 1 })\n",[280],[296],{"type":25,"tag":45,"props":297,"children":298},{"__ignoreMap":7},[299],{"type":31,"value":293},{"type":25,"tag":26,"props":301,"children":303},{"id":302},"高级用法",[304],{"type":31,"value":302},{"type":25,"tag":73,"props":306,"children":308},{"id":307},"数据刷新策略",[309],{"type":31,"value":307},{"type":25,"tag":80,"props":311,"children":314},{"code":312,"language":115,"meta":7,"className":313},"\u003Cscript setup>\n// 基础刷新\nconst { data, refresh, pending } = await useFetch('/api/data')\n\n// 手动刷新\nasync function handleRefresh() {\n  await refresh()\n}\n\n// 定时刷新\nconst refreshInterval = ref(null)\n\nonMounted(() => {\n  refreshInterval.value = setInterval(() => {\n    refresh()\n  }, 30000) // 每 30 秒刷新\n})\n\nonUnmounted(() => {\n  clearInterval(refreshInterval.value)\n})\n\n// 条件刷新\nconst shouldRefresh = ref(false)\n\nwatch(shouldRefresh, (newVal) => {\n  if (newVal) {\n    refresh()\n    shouldRefresh.value = false\n  }\n})\n\u003C/script>\n",[117],[315],{"type":25,"tag":45,"props":316,"children":317},{"__ignoreMap":7},[318],{"type":31,"value":312},{"type":25,"tag":73,"props":320,"children":322},{"id":321},"乐观更新",[323],{"type":31,"value":321},{"type":25,"tag":80,"props":325,"children":328},{"code":326,"language":115,"meta":7,"className":327},"\u003Cscript setup>\nconst { data: todos, refresh } = await useFetch('/api/todos')\n\nasync function toggleTodo(todo) {\n  // 乐观更新：先更新 UI\n  const originalStatus = todo.completed\n  todo.completed = !todo.completed\n\n  try {\n    // 发送请求\n    await $fetch(`/api/todos/${todo.id}`, {\n      method: 'PATCH',\n      body: { completed: todo.completed }\n    })\n  } catch (error) {\n    // 失败时回滚\n    todo.completed = originalStatus\n    console.error('更新失败:', error)\n  }\n}\n\nasync function addTodo(title) {\n  // 创建临时项\n  const tempId = `temp-${Date.now()}`\n  const newTodo = { id: tempId, title, completed: false }\n  \n  // 乐观添加\n  todos.value.push(newTodo)\n\n  try {\n    const created = await $fetch('/api/todos', {\n      method: 'POST',\n      body: { title }\n    })\n    \n    // 替换临时 ID\n    const index = todos.value.findIndex(t => t.id === tempId)\n    todos.value[index] = created\n  } catch (error) {\n    // 失败时移除\n    todos.value = todos.value.filter(t => t.id !== tempId)\n  }\n}\n\u003C/script>\n",[117],[329],{"type":25,"tag":45,"props":330,"children":331},{"__ignoreMap":7},[332],{"type":31,"value":326},{"type":25,"tag":73,"props":334,"children":336},{"id":335},"分页与无限滚动",[337],{"type":31,"value":335},{"type":25,"tag":80,"props":339,"children":342},{"code":340,"language":115,"meta":7,"className":341},"\u003Cscript setup>\nconst page = ref(1)\nconst allPosts = ref([])\n\nconst { data, pending } = await useFetch('/api/posts', {\n  query: {\n    page,\n    limit: 10\n  },\n  transform: (response) => response.data\n})\n\n// 监听数据变化，累积结果\nwatch(data, (newPosts) => {\n  if (newPosts) {\n    if (page.value === 1) {\n      allPosts.value = newPosts\n    } else {\n      allPosts.value = [...allPosts.value, ...newPosts]\n    }\n  }\n})\n\n// 无限滚动实现\nfunction loadMore() {\n  page.value++\n}\n\n// 使用 Intersection Observer\nconst loadMoreRef = ref(null)\n\nonMounted(() => {\n  const observer = new IntersectionObserver((entries) => {\n    if (entries[0].isIntersecting && !pending.value) {\n      loadMore()\n    }\n  })\n\n  if (loadMoreRef.value) {\n    observer.observe(loadMoreRef.value)\n  }\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Cdiv v-for=\"post in allPosts\" :key=\"post.id\">\n      {{ post.title }}\n    \u003C/div>\n    \u003Cdiv ref=\"loadMoreRef\">\n      \u003Cspan v-if=\"pending\">加载中...\u003C/span>\n    \u003C/div>\n  \u003C/div>\n\u003C/template>\n",[117],[343],{"type":25,"tag":45,"props":344,"children":345},{"__ignoreMap":7},[346],{"type":31,"value":340},{"type":25,"tag":73,"props":348,"children":350},{"id":349},"错误处理",[351],{"type":31,"value":349},{"type":25,"tag":80,"props":353,"children":356},{"code":354,"language":115,"meta":7,"className":355},"\u003Cscript setup>\nconst { data, error, refresh } = await useFetch('/api/data', {\n  // 自定义错误处理\n  onResponseError({ response }) {\n    const statusCode = response.status\n    \n    switch (statusCode) {\n      case 401:\n        navigateTo('/login')\n        break\n      case 403:\n        throw createError({\n          statusCode: 403,\n          message: '没有权限访问此资源'\n        })\n      case 404:\n        throw createError({\n          statusCode: 404,\n          message: '资源不存在'\n        })\n      case 500:\n        // 记录错误\n        console.error('服务器错误:', response._data)\n        break\n    }\n  }\n})\n\n// 全局错误处理（通过插件）\n// plugins/fetch-error.ts\nexport default defineNuxtPlugin((nuxtApp) => {\n  nuxtApp.hook('app:error', (error) => {\n    console.error('应用错误:', error)\n    // 可以上报到错误监控服务\n  })\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003Ctemplate v-if=\"error\">\n      \u003Cdiv class=\"error-container\">\n        \u003Ch2>出错了\u003C/h2>\n        \u003Cp>{{ error.message }}\u003C/p>\n        \u003Cbutton @click=\"refresh\">重试\u003C/button>\n      \u003C/div>\n    \u003C/template>\n    \u003Ctemplate v-else>\n      \u003C!-- 正常内容 -->\n    \u003C/template>\n  \u003C/div>\n\u003C/template>\n",[117],[357],{"type":25,"tag":45,"props":358,"children":359},{"__ignoreMap":7},[360],{"type":31,"value":354},{"type":25,"tag":26,"props":362,"children":364},{"id":363},"性能优化",[365],{"type":31,"value":363},{"type":25,"tag":73,"props":367,"children":369},{"id":368},"减少-payload-大小",[370],{"type":31,"value":371},"减少 Payload 大小",{"type":25,"tag":80,"props":373,"children":376},{"code":374,"language":115,"meta":7,"className":375},"\u003Cscript setup>\n// 使用 pick 只选择需要的字段\nconst { data: posts } = await useFetch('/api/posts', {\n  pick: ['id', 'title', 'summary', 'createdAt']\n  // 完整的 post 对象可能有 20+ 个字段\n  // 只传输需要的字段可以显著减少 payload\n})\n\n// 使用 transform 处理数据\nconst { data: users } = await useFetch('/api/users', {\n  transform: (users) => users.map(u => ({\n    id: u.id,\n    name: u.name,\n    avatar: u.avatar\n  }))\n})\n\u003C/script>\n",[117],[377],{"type":25,"tag":45,"props":378,"children":379},{"__ignoreMap":7},[380],{"type":31,"value":374},{"type":25,"tag":73,"props":382,"children":384},{"id":383},"并行请求优化",[385],{"type":31,"value":383},{"type":25,"tag":80,"props":387,"children":390},{"code":388,"language":115,"meta":7,"className":389},"\u003Cscript setup>\n// ❌ 串行请求（慢）\nconst { data: user } = await useFetch('/api/user')\nconst { data: posts } = await useFetch('/api/posts')\nconst { data: comments } = await useFetch('/api/comments')\n// 总时间 = user + posts + comments\n\n// ✅ 并行请求（快）\nconst [\n  { data: user },\n  { data: posts },\n  { data: comments }\n] = await Promise.all([\n  useFetch('/api/user'),\n  useFetch('/api/posts'),\n  useFetch('/api/comments')\n])\n// 总时间 = max(user, posts, comments)\n\n// ✅ 或使用 useAsyncData 聚合\nconst { data } = await useAsyncData('page-data', async () => {\n  const [user, posts, comments] = await Promise.all([\n    $fetch('/api/user'),\n    $fetch('/api/posts'),\n    $fetch('/api/comments')\n  ])\n  return { user, posts, comments }\n})\n\u003C/script>\n",[117],[391],{"type":25,"tag":45,"props":392,"children":393},{"__ignoreMap":7},[394],{"type":31,"value":388},{"type":25,"tag":73,"props":396,"children":398},{"id":397},"懒加载非关键数据",[399],{"type":31,"value":397},{"type":25,"tag":80,"props":401,"children":404},{"code":402,"language":115,"meta":7,"className":403},"\u003Cscript setup>\n// 关键数据：阻塞渲染（SSR）\nconst { data: mainContent } = await useFetch('/api/main')\n\n// 非关键数据：懒加载（不阻塞）\nconst { data: relatedPosts, pending: loadingRelated } = useFetch('/api/related', {\n  lazy: true  // 不阻塞页面渲染\n})\n\nconst { data: comments, pending: loadingComments } = useFetch('/api/comments', {\n  lazy: true,\n  server: false  // 完全在客户端获取\n})\n\u003C/script>\n\n\u003Ctemplate>\n  \u003Cdiv>\n    \u003C!-- 主要内容立即显示 -->\n    \u003Cmain>{{ mainContent }}\u003C/main>\n    \n    \u003C!-- 相关文章懒加载 -->\n    \u003Caside>\n      \u003Cdiv v-if=\"loadingRelated\">加载相关文章...\u003C/div>\n      \u003CRelatedPosts v-else :posts=\"relatedPosts\" />\n    \u003C/aside>\n    \n    \u003C!-- 评论客户端加载 -->\n    \u003Csection>\n      \u003Cdiv v-if=\"loadingComments\">加载评论...\u003C/div>\n      \u003CComments v-else :comments=\"comments\" />\n    \u003C/section>\n  \u003C/div>\n\u003C/template>\n",[117],[405],{"type":25,"tag":45,"props":406,"children":407},{"__ignoreMap":7},[408],{"type":31,"value":402},{"type":25,"tag":26,"props":410,"children":412},{"id":411},"常见问题解答",[413],{"type":31,"value":411},{"type":25,"tag":39,"props":415,"children":416},{},[417,423,425,430,432,437,439,444,446,451],{"type":25,"tag":418,"props":419,"children":420},"strong",{},[421],{"type":31,"value":422},"Q: useFetch 和 useAsyncData 的主要区别是什么？",{"type":31,"value":424},"\nA: ",{"type":25,"tag":45,"props":426,"children":428},{"className":427},[],[429],{"type":31,"value":14},{"type":31,"value":431}," 是 ",{"type":25,"tag":45,"props":433,"children":435},{"className":434},[],[436],{"type":31,"value":15},{"type":31,"value":438}," + ",{"type":25,"tag":45,"props":440,"children":442},{"className":441},[],[443],{"type":31,"value":64},{"type":31,"value":445}," 的封装，专门用于 HTTP 请求。",{"type":25,"tag":45,"props":447,"children":449},{"className":448},[],[450],{"type":31,"value":15},{"type":31,"value":452}," 更通用，可以用于任何异步操作。",{"type":25,"tag":39,"props":454,"children":455},{},[456,461,462,467,469,474],{"type":25,"tag":418,"props":457,"children":458},{},[459],{"type":31,"value":460},"Q: 为什么不能在事件处理器中使用 useFetch？",{"type":31,"value":424},{"type":25,"tag":45,"props":463,"children":465},{"className":464},[],[466],{"type":31,"value":14},{"type":31,"value":468}," 需要在组件 setup 阶段调用，以便进行 SSR 数据传输。事件处理器在用户交互时触发，此时应使用 ",{"type":25,"tag":45,"props":470,"children":472},{"className":471},[],[473],{"type":31,"value":64},{"type":31,"value":475},"。",{"type":25,"tag":39,"props":477,"children":478},{},[479,484],{"type":25,"tag":418,"props":480,"children":481},{},[482],{"type":31,"value":483},"Q: 如何避免数据重复请求？",{"type":31,"value":485},"\nA: Nuxt 会自动根据 key 去重。确保使用一致的 key，或让 Nuxt 自动生成（基于 URL 和参数）。",{"type":25,"tag":39,"props":487,"children":488},{},[489,494],{"type":25,"tag":418,"props":490,"children":491},{},[492],{"type":31,"value":493},"Q: 如何处理认证 token？",{"type":31,"value":495},"\nA: 使用请求拦截器（onRequest）动态添加 Authorization 头，或创建自定义的 $fetch 实例。",{"type":25,"tag":26,"props":497,"children":499},{"id":498},"总结",[500],{"type":31,"value":498},{"type":25,"tag":39,"props":502,"children":503},{},[504],{"type":31,"value":505},"Nuxt 3 的数据获取体系强大而灵活：",{"type":25,"tag":507,"props":508,"children":509},"ol",{},[510,520,529],{"type":25,"tag":511,"props":512,"children":513},"li",{},[514,518],{"type":25,"tag":418,"props":515,"children":516},{},[517],{"type":31,"value":14},{"type":31,"value":519}," - 大多数 API 请求的首选",{"type":25,"tag":511,"props":521,"children":522},{},[523,527],{"type":25,"tag":418,"props":524,"children":525},{},[526],{"type":31,"value":15},{"type":31,"value":528}," - 复杂异步场景的选择",{"type":25,"tag":511,"props":530,"children":531},{},[532,536],{"type":25,"tag":418,"props":533,"children":534},{},[535],{"type":31,"value":64},{"type":31,"value":537}," - 事件处理和非组件代码",{"type":25,"tag":39,"props":539,"children":540},{},[541],{"type":25,"tag":418,"props":542,"children":543},{},[544],{"type":31,"value":545},"最佳实践：",{"type":25,"tag":547,"props":548,"children":549},"ul",{},[550,555,560,565,570],{"type":25,"tag":511,"props":551,"children":552},{},[553],{"type":31,"value":554},"使用响应式参数实现自动刷新",{"type":25,"tag":511,"props":556,"children":557},{},[558],{"type":31,"value":559},"合理使用 lazy 和 server 选项",{"type":25,"tag":511,"props":561,"children":562},{},[563],{"type":31,"value":564},"通过 pick/transform 减少 payload",{"type":25,"tag":511,"props":566,"children":567},{},[568],{"type":31,"value":569},"使用 Promise.all 并行请求",{"type":25,"tag":511,"props":571,"children":572},{},[573],{"type":31,"value":574},"实现恰当的错误处理",{"type":25,"tag":26,"props":576,"children":578},{"id":577},"参考资源",[579],{"type":31,"value":577},{"type":25,"tag":547,"props":581,"children":582},{},[583,595,605,615],{"type":25,"tag":511,"props":584,"children":585},{},[586],{"type":25,"tag":587,"props":588,"children":592},"a",{"href":589,"rel":590},"https://nuxt.com/docs/getting-started/data-fetching",[591],"nofollow",[593],{"type":31,"value":594},"Nuxt 3 Data Fetching",{"type":25,"tag":511,"props":596,"children":597},{},[598],{"type":25,"tag":587,"props":599,"children":602},{"href":600,"rel":601},"https://nuxt.com/docs/api/composables/use-fetch",[591],[603],{"type":31,"value":604},"useFetch API",{"type":25,"tag":511,"props":606,"children":607},{},[608],{"type":25,"tag":587,"props":609,"children":612},{"href":610,"rel":611},"https://nuxt.com/docs/api/composables/use-async-data",[591],[613],{"type":31,"value":614},"useAsyncData API",{"type":25,"tag":511,"props":616,"children":617},{},[618],{"type":25,"tag":587,"props":619,"children":622},{"href":620,"rel":621},"https://github.com/unjs/ofetch",[591],[623],{"type":31,"value":624},"ofetch",{"title":7,"searchDepth":626,"depth":626,"links":627},3,[628,630,631,635,641,646,650,655,661,666,667,668],{"id":28,"depth":629,"text":32},2,{"id":35,"depth":629,"text":35},{"id":69,"depth":629,"text":69,"children":632},[633,634],{"id":75,"depth":626,"text":78},{"id":90,"depth":626,"text":90},{"id":103,"depth":629,"text":106,"children":636},[637,638,639,640],{"id":109,"depth":626,"text":109},{"id":125,"depth":626,"text":125},{"id":139,"depth":626,"text":139},{"id":153,"depth":626,"text":153},{"id":167,"depth":629,"text":170,"children":642},[643,644,645],{"id":173,"depth":626,"text":109},{"id":187,"depth":626,"text":187},{"id":201,"depth":626,"text":201},{"id":215,"depth":629,"text":218,"children":647},[648,649],{"id":221,"depth":626,"text":221},{"id":237,"depth":626,"text":237},{"id":251,"depth":629,"text":254,"children":651},[652,653,654],{"id":257,"depth":626,"text":257},{"id":271,"depth":626,"text":274},{"id":288,"depth":626,"text":288},{"id":302,"depth":629,"text":302,"children":656},[657,658,659,660],{"id":307,"depth":626,"text":307},{"id":321,"depth":626,"text":321},{"id":335,"depth":626,"text":335},{"id":349,"depth":626,"text":349},{"id":363,"depth":629,"text":363,"children":662},[663,664,665],{"id":368,"depth":626,"text":371},{"id":383,"depth":626,"text":383},{"id":397,"depth":626,"text":397},{"id":411,"depth":629,"text":411},{"id":498,"depth":629,"text":498},{"id":577,"depth":629,"text":577},"markdown","content:topics:nuxt:nuxt-data-fetching-guide.md","content","topics/nuxt/nuxt-data-fetching-guide.md","topics/nuxt/nuxt-data-fetching-guide","md",[676,1658,2442],{"_path":677,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":678,"description":679,"date":680,"topic":5,"author":11,"tags":681,"image":687,"featured":19,"readingTime":688,"body":689,"_type":669,"_id":1655,"_source":671,"_file":1656,"_stem":1657,"_extension":674},"/topics/nuxt/nitro-engine-deep-dive","Nitro 引擎深度剖析","讲透 Nuxt/Nitro 的运行时模型、路由与中间件、存储层与缓存、部署适配与性能调优，帮助你把服务端能力当成可控的工程系统。","2026-01-20",[682,683,16,684,685,686],"Nuxt","Nitro","Serverless","Edge","缓存","/images/topics/nuxt/nitro.jpg",21,{"type":22,"children":690,"toc":1623},[691,696,707,712,770,775,780,784,790,795,818,823,841,844,850,855,878,883,886,908,919,937,948,961,967,990,993,999,1004,1035,1040,1053,1056,1062,1074,1087,1092,1110,1115,1128,1131,1137,1142,1160,1166,1185,1191,1196,1201,1230,1233,1239,1244,1262,1267,1285,1291,1304,1310,1323,1329,1342,1347,1360,1363,1369,1375,1388,1394,1407,1413,1426,1429,1435,1440,1463,1468,1481,1484,1490,1495,1553,1558,1576,1579,1583,1595,1600],{"type":25,"tag":26,"props":692,"children":694},{"id":693},"nitro-引擎深度剖析",[695],{"type":31,"value":678},{"type":25,"tag":39,"props":697,"children":698},{},[699,701,706],{"type":31,"value":700},"在 Nuxt 3/4 的体系里，Nitro 不是“一个服务器”，而是一套",{"type":25,"tag":418,"props":702,"children":703},{},[704],{"type":31,"value":705},"可移植的服务端运行时与构建产物规范",{"type":31,"value":475},{"type":25,"tag":39,"props":708,"children":709},{},[710],{"type":31,"value":711},"它把你在开发时写的：",{"type":25,"tag":547,"props":713,"children":714},{},[715,726,737,748,759],{"type":25,"tag":511,"props":716,"children":717},{},[718,724],{"type":25,"tag":45,"props":719,"children":721},{"className":720},[],[722],{"type":31,"value":723},"server/api/*",{"type":31,"value":725},"（API 路由）",{"type":25,"tag":511,"props":727,"children":728},{},[729,735],{"type":25,"tag":45,"props":730,"children":732},{"className":731},[],[733],{"type":31,"value":734},"server/routes/*",{"type":31,"value":736},"（更底层路由）",{"type":25,"tag":511,"props":738,"children":739},{},[740,746],{"type":25,"tag":45,"props":741,"children":743},{"className":742},[],[744],{"type":31,"value":745},"server/middleware/*",{"type":31,"value":747},"（中间件）",{"type":25,"tag":511,"props":749,"children":750},{},[751,757],{"type":25,"tag":45,"props":752,"children":754},{"className":753},[],[755],{"type":31,"value":756},"server/plugins/*",{"type":31,"value":758},"（启动插件）",{"type":25,"tag":511,"props":760,"children":761},{},[762,768],{"type":25,"tag":45,"props":763,"children":765},{"className":764},[],[766],{"type":31,"value":767},"storage",{"type":31,"value":769},"（KV/文件/内存等存储抽象）",{"type":25,"tag":39,"props":771,"children":772},{},[773],{"type":31,"value":774},"统一编译成一个可以部署到多种环境的产物：Node Server、Serverless、Edge（取决于适配器与能力集）。",{"type":25,"tag":39,"props":776,"children":777},{},[778],{"type":31,"value":779},"这篇文章按“你要在生产上稳定运行”的视角，拆解 Nitro 的关键构件，并给出性能与可观测性落地建议。",{"type":25,"tag":781,"props":782,"children":783},"hr",{},[],{"type":25,"tag":26,"props":785,"children":787},{"id":786},"_1-nitro-的定位从-nuxt-ssr-到通用服务端运行时",[788],{"type":31,"value":789},"1. Nitro 的定位：从 Nuxt SSR 到“通用服务端运行时”",{"type":25,"tag":39,"props":791,"children":792},{},[793],{"type":31,"value":794},"Nitro 解决两类问题：",{"type":25,"tag":507,"props":796,"children":797},{},[798,808],{"type":25,"tag":511,"props":799,"children":800},{},[801,806],{"type":25,"tag":418,"props":802,"children":803},{},[804],{"type":31,"value":805},"运行时统一",{"type":31,"value":807},"：开发/生产环境一致的请求处理模型",{"type":25,"tag":511,"props":809,"children":810},{},[811,816],{"type":25,"tag":418,"props":812,"children":813},{},[814],{"type":31,"value":815},"部署可移植",{"type":31,"value":817},"：同一套代码可输出到不同部署目标",{"type":25,"tag":39,"props":819,"children":820},{},[821],{"type":31,"value":822},"你可以把 Nitro 看作 Nuxt 的“服务端内核”，而 Nuxt 只是围绕它提供：",{"type":25,"tag":547,"props":824,"children":825},{},[826,831,836],{"type":25,"tag":511,"props":827,"children":828},{},[829],{"type":31,"value":830},"视图渲染（SSR/RSC 相关能力）",{"type":25,"tag":511,"props":832,"children":833},{},[834],{"type":31,"value":835},"资源构建（Vite/Webpack）",{"type":25,"tag":511,"props":837,"children":838},{},[839],{"type":31,"value":840},"路由与数据获取的上层抽象",{"type":25,"tag":781,"props":842,"children":843},{},[],{"type":25,"tag":26,"props":845,"children":847},{"id":846},"_2-请求生命周期一次请求在-nitro-里怎么走",[848],{"type":31,"value":849},"2. 请求生命周期：一次请求在 Nitro 里怎么走？",{"type":25,"tag":39,"props":851,"children":852},{},[853],{"type":31,"value":854},"简化后的请求链路：",{"type":25,"tag":507,"props":856,"children":857},{},[858,863,868,873],{"type":25,"tag":511,"props":859,"children":860},{},[861],{"type":31,"value":862},"入口适配器接收请求（Node/Serverless/Edge）",{"type":25,"tag":511,"props":864,"children":865},{},[866],{"type":31,"value":867},"进入 Nitro 的 H3 请求处理器（统一事件模型）",{"type":25,"tag":511,"props":869,"children":870},{},[871],{"type":31,"value":872},"依次执行：中间件 → 路由匹配 → handler",{"type":25,"tag":511,"props":874,"children":875},{},[876],{"type":31,"value":877},"写回响应（含 headers、缓存策略、流式输出等）",{"type":25,"tag":39,"props":879,"children":880},{},[881],{"type":31,"value":882},"关键点：Nitro 用统一的事件对象承载请求上下文，这让你在不同部署目标下写出的 server 代码保持一致。",{"type":25,"tag":781,"props":884,"children":885},{},[],{"type":25,"tag":26,"props":887,"children":889},{"id":888},"_3-路由系统serverapi-与-serverroutes-的区别",[890,892,898,900,906],{"type":31,"value":891},"3. 路由系统：",{"type":25,"tag":45,"props":893,"children":895},{"className":894},[],[896],{"type":31,"value":897},"server/api",{"type":31,"value":899}," 与 ",{"type":25,"tag":45,"props":901,"children":903},{"className":902},[],[904],{"type":31,"value":905},"server/routes",{"type":31,"value":907}," 的区别",{"type":25,"tag":73,"props":909,"children":911},{"id":910},"_31-serverapi",[912,914],{"type":31,"value":913},"3.1 ",{"type":25,"tag":45,"props":915,"children":917},{"className":916},[],[918],{"type":31,"value":723},{"type":25,"tag":547,"props":920,"children":921},{},[922,927,932],{"type":25,"tag":511,"props":923,"children":924},{},[925],{"type":31,"value":926},"面向 API 的约定式目录",{"type":25,"tag":511,"props":928,"children":929},{},[930],{"type":31,"value":931},"通常返回 JSON",{"type":25,"tag":511,"props":933,"children":934},{},[935],{"type":31,"value":936},"与 Nuxt 的开发体验高度整合",{"type":25,"tag":73,"props":938,"children":940},{"id":939},"_32-serverroutes",[941,943],{"type":31,"value":942},"3.2 ",{"type":25,"tag":45,"props":944,"children":946},{"className":945},[],[947],{"type":31,"value":734},{"type":25,"tag":547,"props":949,"children":950},{},[951,956],{"type":25,"tag":511,"props":952,"children":953},{},[954],{"type":31,"value":955},"更底层，更贴近“HTTP 路由”",{"type":25,"tag":511,"props":957,"children":958},{},[959],{"type":31,"value":960},"更适合做：Webhook、回调、代理、特殊 content-type",{"type":25,"tag":73,"props":962,"children":964},{"id":963},"_33-实践建议",[965],{"type":31,"value":966},"3.3 实践建议",{"type":25,"tag":547,"props":968,"children":969},{},[970,980],{"type":25,"tag":511,"props":971,"children":972},{},[973,975],{"type":31,"value":974},"普通业务 API：优先 ",{"type":25,"tag":45,"props":976,"children":978},{"className":977},[],[979],{"type":31,"value":897},{"type":25,"tag":511,"props":981,"children":982},{},[983,985],{"type":31,"value":984},"需要更强控制（stream、代理、非 JSON）：用 ",{"type":25,"tag":45,"props":986,"children":988},{"className":987},[],[989],{"type":31,"value":905},{"type":25,"tag":781,"props":991,"children":992},{},[],{"type":25,"tag":26,"props":994,"children":996},{"id":995},"_4-中间件全局逻辑的正确放置",[997],{"type":31,"value":998},"4. 中间件：全局逻辑的正确放置",{"type":25,"tag":39,"props":1000,"children":1001},{},[1002],{"type":31,"value":1003},"Nitro 中的中间件通常用于：",{"type":25,"tag":547,"props":1005,"children":1006},{},[1007,1012,1025,1030],{"type":25,"tag":511,"props":1008,"children":1009},{},[1010],{"type":31,"value":1011},"鉴权/鉴别请求来源",{"type":25,"tag":511,"props":1013,"children":1014},{},[1015,1017,1023],{"type":31,"value":1016},"注入 ",{"type":25,"tag":45,"props":1018,"children":1020},{"className":1019},[],[1021],{"type":31,"value":1022},"requestId",{"type":31,"value":1024},"、trace 信息",{"type":25,"tag":511,"props":1026,"children":1027},{},[1028],{"type":31,"value":1029},"统一错误处理与日志",{"type":25,"tag":511,"props":1031,"children":1032},{},[1033],{"type":31,"value":1034},"基础安全 headers",{"type":25,"tag":39,"props":1036,"children":1037},{},[1038],{"type":31,"value":1039},"一个推荐的中间件职责边界：",{"type":25,"tag":547,"props":1041,"children":1042},{},[1043,1048],{"type":25,"tag":511,"props":1044,"children":1045},{},[1046],{"type":31,"value":1047},"中间件只做“横切关注点”",{"type":25,"tag":511,"props":1049,"children":1050},{},[1051],{"type":31,"value":1052},"不做具体业务（避免耦合与隐式依赖）",{"type":25,"tag":781,"props":1054,"children":1055},{},[],{"type":25,"tag":26,"props":1057,"children":1059},{"id":1058},"_5-storage-抽象让缓存与数据存取可替换",[1060],{"type":31,"value":1061},"5. Storage 抽象：让缓存与数据存取可替换",{"type":25,"tag":39,"props":1063,"children":1064},{},[1065,1067,1072],{"type":31,"value":1066},"Nitro 的一个被低估的能力是 ",{"type":25,"tag":45,"props":1068,"children":1070},{"className":1069},[],[1071],{"type":31,"value":767},{"type":31,"value":1073},"：",{"type":25,"tag":547,"props":1075,"children":1076},{},[1077,1082],{"type":25,"tag":511,"props":1078,"children":1079},{},[1080],{"type":31,"value":1081},"提供 KV 风格 API",{"type":25,"tag":511,"props":1083,"children":1084},{},[1085],{"type":31,"value":1086},"可接入内存、文件、Redis 等（取决于配置与环境）",{"type":25,"tag":39,"props":1088,"children":1089},{},[1090],{"type":31,"value":1091},"你可以用它做：",{"type":25,"tag":547,"props":1093,"children":1094},{},[1095,1100,1105],{"type":25,"tag":511,"props":1096,"children":1097},{},[1098],{"type":31,"value":1099},"缓存（页面片段、API 结果）",{"type":25,"tag":511,"props":1101,"children":1102},{},[1103],{"type":31,"value":1104},"限流计数器",{"type":25,"tag":511,"props":1106,"children":1107},{},[1108],{"type":31,"value":1109},"临时会话信息",{"type":25,"tag":39,"props":1111,"children":1112},{},[1113],{"type":31,"value":1114},"设计原则：",{"type":25,"tag":547,"props":1116,"children":1117},{},[1118,1123],{"type":25,"tag":511,"props":1119,"children":1120},{},[1121],{"type":31,"value":1122},"把 storage 当成“可失效缓存”，不要当主数据库",{"type":25,"tag":511,"props":1124,"children":1125},{},[1126],{"type":31,"value":1127},"明确 TTL 与清理策略",{"type":25,"tag":781,"props":1129,"children":1130},{},[],{"type":25,"tag":26,"props":1132,"children":1134},{"id":1133},"_6-缓存策略把快变成可控的工程能力",[1135],{"type":31,"value":1136},"6. 缓存策略：把“快”变成可控的工程能力",{"type":25,"tag":39,"props":1138,"children":1139},{},[1140],{"type":31,"value":1141},"Nitro 里的缓存往往涉及三层：",{"type":25,"tag":507,"props":1143,"children":1144},{},[1145,1150,1155],{"type":25,"tag":511,"props":1146,"children":1147},{},[1148],{"type":31,"value":1149},"CDN 缓存（边缘）",{"type":25,"tag":511,"props":1151,"children":1152},{},[1153],{"type":31,"value":1154},"Nitro 运行时缓存（storage）",{"type":25,"tag":511,"props":1156,"children":1157},{},[1158],{"type":31,"value":1159},"上游服务缓存（数据库/服务端）",{"type":25,"tag":73,"props":1161,"children":1163},{"id":1162},"_61-api-缓存的推荐做法",[1164],{"type":31,"value":1165},"6.1 API 缓存的推荐做法",{"type":25,"tag":547,"props":1167,"children":1168},{},[1169,1180],{"type":25,"tag":511,"props":1170,"children":1171},{},[1172,1174],{"type":31,"value":1173},"对“读多写少”的接口做 ",{"type":25,"tag":45,"props":1175,"children":1177},{"className":1176},[],[1178],{"type":31,"value":1179},"stale-while-revalidate",{"type":25,"tag":511,"props":1181,"children":1182},{},[1183],{"type":31,"value":1184},"缓存 key 必须包含：用户态/语言/地区/权限等关键维度",{"type":25,"tag":73,"props":1186,"children":1188},{"id":1187},"_62-不要缓存带用户身份的响应除非你非常确定",[1189],{"type":31,"value":1190},"6.2 不要缓存“带用户身份”的响应（除非你非常确定）",{"type":25,"tag":39,"props":1192,"children":1193},{},[1194],{"type":31,"value":1195},"最容易出事故的是把 A 用户的数据缓存给 B 用户。",{"type":25,"tag":39,"props":1197,"children":1198},{},[1199],{"type":31,"value":1200},"建议：",{"type":25,"tag":547,"props":1202,"children":1203},{},[1204,1209],{"type":25,"tag":511,"props":1205,"children":1206},{},[1207],{"type":31,"value":1208},"默认对用户态接口不缓存",{"type":25,"tag":511,"props":1210,"children":1211},{},[1212,1214,1220,1222,1228],{"type":31,"value":1213},"必须缓存时，key 中加入 ",{"type":25,"tag":45,"props":1215,"children":1217},{"className":1216},[],[1218],{"type":31,"value":1219},"userId",{"type":31,"value":1221}," 或 ",{"type":25,"tag":45,"props":1223,"children":1225},{"className":1224},[],[1226],{"type":31,"value":1227},"session",{"type":31,"value":1229}," 维度",{"type":25,"tag":781,"props":1231,"children":1232},{},[],{"type":25,"tag":26,"props":1234,"children":1236},{"id":1235},"_7-部署适配为什么同一套代码能跑在不同环境",[1237],{"type":31,"value":1238},"7. 部署适配：为什么同一套代码能跑在不同环境？",{"type":25,"tag":39,"props":1240,"children":1241},{},[1242],{"type":31,"value":1243},"Nitro 的部署产物通常包含：",{"type":25,"tag":547,"props":1245,"children":1246},{},[1247,1252,1257],{"type":25,"tag":511,"props":1248,"children":1249},{},[1250],{"type":31,"value":1251},"编译后的 server bundle",{"type":25,"tag":511,"props":1253,"children":1254},{},[1255],{"type":31,"value":1256},"路由清单与运行时配置",{"type":25,"tag":511,"props":1258,"children":1259},{},[1260],{"type":31,"value":1261},"静态资源与预渲染结果（如果启用）",{"type":25,"tag":39,"props":1263,"children":1264},{},[1265],{"type":31,"value":1266},"在不同目标下的差异主要在：",{"type":25,"tag":547,"props":1268,"children":1269},{},[1270,1275,1280],{"type":25,"tag":511,"props":1271,"children":1272},{},[1273],{"type":31,"value":1274},"运行时能力（Node API 是否可用）",{"type":25,"tag":511,"props":1276,"children":1277},{},[1278],{"type":31,"value":1279},"冷启动与并发模型",{"type":25,"tag":511,"props":1281,"children":1282},{},[1283],{"type":31,"value":1284},"文件系统是否可写",{"type":25,"tag":73,"props":1286,"children":1288},{"id":1287},"_71-node-server",[1289],{"type":31,"value":1290},"7.1 Node Server",{"type":25,"tag":547,"props":1292,"children":1293},{},[1294,1299],{"type":25,"tag":511,"props":1295,"children":1296},{},[1297],{"type":31,"value":1298},"能力最完整",{"type":25,"tag":511,"props":1300,"children":1301},{},[1302],{"type":31,"value":1303},"适合长连接、websocket（需配合平台）",{"type":25,"tag":73,"props":1305,"children":1307},{"id":1306},"_72-serverless",[1308],{"type":31,"value":1309},"7.2 Serverless",{"type":25,"tag":547,"props":1311,"children":1312},{},[1313,1318],{"type":25,"tag":511,"props":1314,"children":1315},{},[1316],{"type":31,"value":1317},"冷启动成本、执行时长限制",{"type":25,"tag":511,"props":1319,"children":1320},{},[1321],{"type":31,"value":1322},"更适合 API 型工作负载",{"type":25,"tag":73,"props":1324,"children":1326},{"id":1325},"_73-edge",[1327],{"type":31,"value":1328},"7.3 Edge",{"type":25,"tag":547,"props":1330,"children":1331},{},[1332,1337],{"type":25,"tag":511,"props":1333,"children":1334},{},[1335],{"type":31,"value":1336},"延迟更低",{"type":25,"tag":511,"props":1338,"children":1339},{},[1340],{"type":31,"value":1341},"运行时限制更严格（例如 Node API 不可用）",{"type":25,"tag":39,"props":1343,"children":1344},{},[1345],{"type":31,"value":1346},"实践建议：",{"type":25,"tag":547,"props":1348,"children":1349},{},[1350,1355],{"type":25,"tag":511,"props":1351,"children":1352},{},[1353],{"type":31,"value":1354},"如果你依赖复杂 Node 能力（例如图像处理、原生模块），优先 Node/Serverless",{"type":25,"tag":511,"props":1356,"children":1357},{},[1358],{"type":31,"value":1359},"如果你追求极致延迟且逻辑简单，考虑 Edge",{"type":25,"tag":781,"props":1361,"children":1362},{},[],{"type":25,"tag":26,"props":1364,"children":1366},{"id":1365},"_8-性能调优nitro-侧你能做什么",[1367],{"type":31,"value":1368},"8. 性能调优：Nitro 侧你能做什么？",{"type":25,"tag":73,"props":1370,"children":1372},{"id":1371},"_81-减少阻塞-io",[1373],{"type":31,"value":1374},"8.1 减少阻塞 I/O",{"type":25,"tag":547,"props":1376,"children":1377},{},[1378,1383],{"type":25,"tag":511,"props":1379,"children":1380},{},[1381],{"type":31,"value":1382},"避免请求内做同步文件读写",{"type":25,"tag":511,"props":1384,"children":1385},{},[1386],{"type":31,"value":1387},"对“配置/规则”等可缓存数据做启动预热",{"type":25,"tag":73,"props":1389,"children":1391},{"id":1390},"_82-控制上游依赖",[1392],{"type":31,"value":1393},"8.2 控制上游依赖",{"type":25,"tag":547,"props":1395,"children":1396},{},[1397,1402],{"type":25,"tag":511,"props":1398,"children":1399},{},[1400],{"type":31,"value":1401},"给外部请求设超时（例如 2~3s）",{"type":25,"tag":511,"props":1403,"children":1404},{},[1405],{"type":31,"value":1406},"加重试要谨慎（避免雪崩）",{"type":25,"tag":73,"props":1408,"children":1410},{"id":1409},"_83-响应体积与压缩",[1411],{"type":31,"value":1412},"8.3 响应体积与压缩",{"type":25,"tag":547,"props":1414,"children":1415},{},[1416,1421],{"type":25,"tag":511,"props":1417,"children":1418},{},[1419],{"type":31,"value":1420},"JSON 输出控制字段",{"type":25,"tag":511,"props":1422,"children":1423},{},[1424],{"type":31,"value":1425},"开启 gzip/br",{"type":25,"tag":781,"props":1427,"children":1428},{},[],{"type":25,"tag":26,"props":1430,"children":1432},{"id":1431},"_9-可观测性没有观测就没有稳定",[1433],{"type":31,"value":1434},"9. 可观测性：没有观测就没有“稳定”",{"type":25,"tag":39,"props":1436,"children":1437},{},[1438],{"type":31,"value":1439},"建议 Nitro 侧最小可观测集合：",{"type":25,"tag":547,"props":1441,"children":1442},{},[1443,1448,1453,1458],{"type":25,"tag":511,"props":1444,"children":1445},{},[1446],{"type":31,"value":1447},"requestId/traceId",{"type":25,"tag":511,"props":1449,"children":1450},{},[1451],{"type":31,"value":1452},"关键路由耗时（p50/p95）",{"type":25,"tag":511,"props":1454,"children":1455},{},[1456],{"type":31,"value":1457},"错误率（按路由/按状态码）",{"type":25,"tag":511,"props":1459,"children":1460},{},[1461],{"type":31,"value":1462},"上游依赖耗时（DB/HTTP）",{"type":25,"tag":39,"props":1464,"children":1465},{},[1466],{"type":31,"value":1467},"落地方式：",{"type":25,"tag":547,"props":1469,"children":1470},{},[1471,1476],{"type":25,"tag":511,"props":1472,"children":1473},{},[1474],{"type":31,"value":1475},"在中间件注入 requestId",{"type":25,"tag":511,"props":1477,"children":1478},{},[1479],{"type":31,"value":1480},"在统一错误处理处记录结构化日志",{"type":25,"tag":781,"props":1482,"children":1483},{},[],{"type":25,"tag":26,"props":1485,"children":1487},{"id":1486},"_10-一个推荐的-nitro-工程结构",[1488],{"type":31,"value":1489},"10. 一个推荐的 Nitro 工程结构",{"type":25,"tag":39,"props":1491,"children":1492},{},[1493],{"type":31,"value":1494},"在 Nuxt 项目里，你可以这样组织服务端代码：",{"type":25,"tag":547,"props":1496,"children":1497},{},[1498,1509,1520,1531,1542],{"type":25,"tag":511,"props":1499,"children":1500},{},[1501,1507],{"type":25,"tag":45,"props":1502,"children":1504},{"className":1503},[],[1505],{"type":31,"value":1506},"server/middleware/",{"type":31,"value":1508},"：鉴权、日志、headers、rate limit",{"type":25,"tag":511,"props":1510,"children":1511},{},[1512,1518],{"type":25,"tag":45,"props":1513,"children":1515},{"className":1514},[],[1516],{"type":31,"value":1517},"server/api/",{"type":31,"value":1519},"：业务 API（薄控制器）",{"type":25,"tag":511,"props":1521,"children":1522},{},[1523,1529],{"type":25,"tag":45,"props":1524,"children":1526},{"className":1525},[],[1527],{"type":31,"value":1528},"server/services/",{"type":31,"value":1530},"：领域服务（可复用）",{"type":25,"tag":511,"props":1532,"children":1533},{},[1534,1540],{"type":25,"tag":45,"props":1535,"children":1537},{"className":1536},[],[1538],{"type":31,"value":1539},"server/repositories/",{"type":31,"value":1541},"：数据访问层",{"type":25,"tag":511,"props":1543,"children":1544},{},[1545,1551],{"type":25,"tag":45,"props":1546,"children":1548},{"className":1547},[],[1549],{"type":31,"value":1550},"server/utils/",{"type":31,"value":1552},"：纯工具",{"type":25,"tag":39,"props":1554,"children":1555},{},[1556],{"type":31,"value":1557},"目标是：",{"type":25,"tag":547,"props":1559,"children":1560},{},[1561,1566,1571],{"type":25,"tag":511,"props":1562,"children":1563},{},[1564],{"type":31,"value":1565},"handler 只做协议适配",{"type":25,"tag":511,"props":1567,"children":1568},{},[1569],{"type":31,"value":1570},"业务逻辑可复用、可测试",{"type":25,"tag":511,"props":1572,"children":1573},{},[1574],{"type":31,"value":1575},"横切能力集中化",{"type":25,"tag":781,"props":1577,"children":1578},{},[],{"type":25,"tag":26,"props":1580,"children":1581},{"id":498},[1582],{"type":31,"value":498},{"type":25,"tag":39,"props":1584,"children":1585},{},[1586,1588,1593],{"type":31,"value":1587},"Nitro 的本质是：把 Nuxt 的服务端能力变成一个",{"type":25,"tag":418,"props":1589,"children":1590},{},[1591],{"type":31,"value":1592},"可编译、可移植、可观测",{"type":31,"value":1594},"的运行时系统。",{"type":25,"tag":39,"props":1596,"children":1597},{},[1598],{"type":31,"value":1599},"你一旦理解了它的生命周期与边界，就可以更有信心地在 Nuxt 里做：",{"type":25,"tag":547,"props":1601,"children":1602},{},[1603,1608,1613,1618],{"type":25,"tag":511,"props":1604,"children":1605},{},[1606],{"type":31,"value":1607},"性能友好的 API",{"type":25,"tag":511,"props":1609,"children":1610},{},[1611],{"type":31,"value":1612},"可控的缓存",{"type":25,"tag":511,"props":1614,"children":1615},{},[1616],{"type":31,"value":1617},"稳定的鉴权与错误处理",{"type":25,"tag":511,"props":1619,"children":1620},{},[1621],{"type":31,"value":1622},"面向多环境部署的工程架构",{"title":7,"searchDepth":626,"depth":626,"links":1624},[1625,1626,1627,1628,1636,1637,1638,1642,1647,1652,1653,1654],{"id":693,"depth":629,"text":678},{"id":786,"depth":629,"text":789},{"id":846,"depth":629,"text":849},{"id":888,"depth":629,"text":1629,"children":1630},"3. 路由系统：server/api 与 server/routes 的区别",[1631,1633,1635],{"id":910,"depth":626,"text":1632},"3.1 server/api/*",{"id":939,"depth":626,"text":1634},"3.2 server/routes/*",{"id":963,"depth":626,"text":966},{"id":995,"depth":629,"text":998},{"id":1058,"depth":629,"text":1061},{"id":1133,"depth":629,"text":1136,"children":1639},[1640,1641],{"id":1162,"depth":626,"text":1165},{"id":1187,"depth":626,"text":1190},{"id":1235,"depth":629,"text":1238,"children":1643},[1644,1645,1646],{"id":1287,"depth":626,"text":1290},{"id":1306,"depth":626,"text":1309},{"id":1325,"depth":626,"text":1328},{"id":1365,"depth":629,"text":1368,"children":1648},[1649,1650,1651],{"id":1371,"depth":626,"text":1374},{"id":1390,"depth":626,"text":1393},{"id":1409,"depth":626,"text":1412},{"id":1431,"depth":629,"text":1434},{"id":1486,"depth":629,"text":1489},{"id":498,"depth":629,"text":498},"content:topics:nuxt:nitro-engine-deep-dive.md","topics/nuxt/nitro-engine-deep-dive.md","topics/nuxt/nitro-engine-deep-dive",{"_path":1659,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":1660,"description":1661,"date":680,"topic":5,"author":11,"tags":1662,"image":1666,"featured":19,"readingTime":1667,"body":1668,"_type":669,"_id":2439,"_source":671,"_file":2440,"_stem":2441,"_extension":674},"/topics/nuxt/nuxt-rendering-modes-guide","Nuxt 渲染模式选择指南","从 SEO、性能、成本与一致性出发，系统对比 Nuxt 的 CSR/SSR/SSG/ISR（与预渲染）等模式，给出可执行的选型矩阵与落地架构建议。",[682,16,1663,1664,1665],"SSG","ISR","SEO","/images/topics/nuxt/rendering-modes.jpg",22,{"type":22,"children":1669,"toc":2422},[1670,1675,1680,1685,1713,1725,1728,1734,1739,1762,1767,1770,1776,1782,1787,1805,1810,1829,1835,1839,1852,1856,1869,1875,1879,1892,1896,1909,1915,1920,1933,1937,1950,1954,1967,1973,1977,1990,1994,2007,2010,2016,2021,2188,2191,2197,2202,2220,2225,2238,2241,2247,2252,2257,2280,2285,2303,2306,2312,2330,2333,2339,2392,2395,2399,2404],{"type":25,"tag":26,"props":1671,"children":1673},{"id":1672},"nuxt-渲染模式选择指南",[1674],{"type":31,"value":1660},{"type":25,"tag":39,"props":1676,"children":1677},{},[1678],{"type":31,"value":1679},"“到底要不要 SSR？”是 Nuxt 项目里最常见、也最容易吵起来的问题。",{"type":25,"tag":39,"props":1681,"children":1682},{},[1683],{"type":31,"value":1684},"原因是：渲染模式不是一个单点选择，它同时牵动：",{"type":25,"tag":547,"props":1686,"children":1687},{},[1688,1693,1698,1703,1708],{"type":25,"tag":511,"props":1689,"children":1690},{},[1691],{"type":31,"value":1692},"SEO（可索引内容是否直出）",{"type":25,"tag":511,"props":1694,"children":1695},{},[1696],{"type":31,"value":1697},"性能（TTFB/LCP/INP）",{"type":25,"tag":511,"props":1699,"children":1700},{},[1701],{"type":31,"value":1702},"成本（回源、算力、带宽）",{"type":25,"tag":511,"props":1704,"children":1705},{},[1706],{"type":31,"value":1707},"一致性（内容更新策略、缓存失效）",{"type":25,"tag":511,"props":1709,"children":1710},{},[1711],{"type":31,"value":1712},"工程复杂度（部署、观测、回滚）",{"type":25,"tag":39,"props":1714,"children":1715},{},[1716,1718,1723],{"type":31,"value":1717},"这篇文章给你一套",{"type":25,"tag":418,"props":1719,"children":1720},{},[1721],{"type":31,"value":1722},"可执行的选型方法",{"type":31,"value":1724},"：先定义目标，再选模式，最后给落地结构与检查清单。",{"type":25,"tag":781,"props":1726,"children":1727},{},[],{"type":25,"tag":26,"props":1729,"children":1731},{"id":1730},"_1-四个维度决定你的模式",[1732],{"type":31,"value":1733},"1. 四个维度，决定你的模式",{"type":25,"tag":39,"props":1735,"children":1736},{},[1737],{"type":31,"value":1738},"在做任何选择前，先回答四个问题：",{"type":25,"tag":507,"props":1740,"children":1741},{},[1742,1747,1752,1757],{"type":25,"tag":511,"props":1743,"children":1744},{},[1745],{"type":31,"value":1746},"页面是否需要 SEO？（搜索引擎是否必须看到正文）",{"type":25,"tag":511,"props":1748,"children":1749},{},[1750],{"type":31,"value":1751},"数据是否强一致？（用户态/支付/权限）",{"type":25,"tag":511,"props":1753,"children":1754},{},[1755],{"type":31,"value":1756},"更新频率如何？（发布频繁 vs 偶尔）",{"type":25,"tag":511,"props":1758,"children":1759},{},[1760],{"type":31,"value":1761},"流量模型是什么？（突发、平稳、长尾）",{"type":25,"tag":39,"props":1763,"children":1764},{},[1765],{"type":31,"value":1766},"这些问题比“SSR 快还是慢”更重要。",{"type":25,"tag":781,"props":1768,"children":1769},{},[],{"type":25,"tag":26,"props":1771,"children":1773},{"id":1772},"_2-主要模式概览csr-ssr-ssg-isr-预渲染",[1774],{"type":31,"value":1775},"2. 主要模式概览：CSR / SSR / SSG / ISR / 预渲染",{"type":25,"tag":73,"props":1777,"children":1779},{"id":1778},"_21-csr纯客户端渲染",[1780],{"type":31,"value":1781},"2.1 CSR（纯客户端渲染）",{"type":25,"tag":39,"props":1783,"children":1784},{},[1785],{"type":31,"value":1786},"特点：",{"type":25,"tag":547,"props":1788,"children":1789},{},[1790,1795,1800],{"type":25,"tag":511,"props":1791,"children":1792},{},[1793],{"type":31,"value":1794},"HTML 只有壳",{"type":25,"tag":511,"props":1796,"children":1797},{},[1798],{"type":31,"value":1799},"SEO 风险大（除非你不索引）",{"type":25,"tag":511,"props":1801,"children":1802},{},[1803],{"type":31,"value":1804},"首屏性能取决于 JS 与接口",{"type":25,"tag":39,"props":1806,"children":1807},{},[1808],{"type":31,"value":1809},"适用：",{"type":25,"tag":547,"props":1811,"children":1812},{},[1813,1818],{"type":25,"tag":511,"props":1814,"children":1815},{},[1816],{"type":31,"value":1817},"用户中心、后台、强交互工具",{"type":25,"tag":511,"props":1819,"children":1820},{},[1821,1823],{"type":31,"value":1822},"不需要索引或明确 ",{"type":25,"tag":45,"props":1824,"children":1826},{"className":1825},[],[1827],{"type":31,"value":1828},"noindex",{"type":25,"tag":73,"props":1830,"children":1832},{"id":1831},"_22-ssr服务端渲染",[1833],{"type":31,"value":1834},"2.2 SSR（服务端渲染）",{"type":25,"tag":39,"props":1836,"children":1837},{},[1838],{"type":31,"value":1786},{"type":25,"tag":547,"props":1840,"children":1841},{},[1842,1847],{"type":25,"tag":511,"props":1843,"children":1844},{},[1845],{"type":31,"value":1846},"首屏 HTML 直出，SEO 友好",{"type":25,"tag":511,"props":1848,"children":1849},{},[1850],{"type":31,"value":1851},"每次请求可能都需要回源（需要缓存）",{"type":25,"tag":39,"props":1853,"children":1854},{},[1855],{"type":31,"value":1809},{"type":25,"tag":547,"props":1857,"children":1858},{},[1859,1864],{"type":25,"tag":511,"props":1860,"children":1861},{},[1862],{"type":31,"value":1863},"内容需要 SEO，但数据强动态",{"type":25,"tag":511,"props":1865,"children":1866},{},[1867],{"type":31,"value":1868},"你有完善的缓存策略",{"type":25,"tag":73,"props":1870,"children":1872},{"id":1871},"_23-ssg静态生成",[1873],{"type":31,"value":1874},"2.3 SSG（静态生成）",{"type":25,"tag":39,"props":1876,"children":1877},{},[1878],{"type":31,"value":1786},{"type":25,"tag":547,"props":1880,"children":1881},{},[1882,1887],{"type":25,"tag":511,"props":1883,"children":1884},{},[1885],{"type":31,"value":1886},"性能与稳定性最好",{"type":25,"tag":511,"props":1888,"children":1889},{},[1890],{"type":31,"value":1891},"更新成本在“构建时”",{"type":25,"tag":39,"props":1893,"children":1894},{},[1895],{"type":31,"value":1809},{"type":25,"tag":547,"props":1897,"children":1898},{},[1899,1904],{"type":25,"tag":511,"props":1900,"children":1901},{},[1902],{"type":31,"value":1903},"内容站、文档站、营销页",{"type":25,"tag":511,"props":1905,"children":1906},{},[1907],{"type":31,"value":1908},"更新频率不高或可接受构建延迟",{"type":25,"tag":73,"props":1910,"children":1912},{"id":1911},"_24-isr增量静态再生按需生成",[1913],{"type":31,"value":1914},"2.4 ISR（增量静态再生/按需生成）",{"type":25,"tag":39,"props":1916,"children":1917},{},[1918],{"type":31,"value":1919},"在 Nuxt 体系里，ISR 的表达可能来自：",{"type":25,"tag":547,"props":1921,"children":1922},{},[1923,1928],{"type":25,"tag":511,"props":1924,"children":1925},{},[1926],{"type":31,"value":1927},"生成策略 + 缓存策略",{"type":25,"tag":511,"props":1929,"children":1930},{},[1931],{"type":31,"value":1932},"或配合边缘缓存与按需失效",{"type":25,"tag":39,"props":1934,"children":1935},{},[1936],{"type":31,"value":1786},{"type":25,"tag":547,"props":1938,"children":1939},{},[1940,1945],{"type":25,"tag":511,"props":1941,"children":1942},{},[1943],{"type":31,"value":1944},"静态化收益 + 可控更新",{"type":25,"tag":511,"props":1946,"children":1947},{},[1948],{"type":31,"value":1949},"需要你设计“失效与再生成”",{"type":25,"tag":39,"props":1951,"children":1952},{},[1953],{"type":31,"value":1809},{"type":25,"tag":547,"props":1955,"children":1956},{},[1957,1962],{"type":25,"tag":511,"props":1958,"children":1959},{},[1960],{"type":31,"value":1961},"内容更新频繁，但仍要 SEO",{"type":25,"tag":511,"props":1963,"children":1964},{},[1965],{"type":31,"value":1966},"你希望在高峰也保持稳定",{"type":25,"tag":73,"props":1968,"children":1970},{"id":1969},"_25-预渲染prerender",[1971],{"type":31,"value":1972},"2.5 预渲染（prerender）",{"type":25,"tag":39,"props":1974,"children":1975},{},[1976],{"type":31,"value":1786},{"type":25,"tag":547,"props":1978,"children":1979},{},[1980,1985],{"type":25,"tag":511,"props":1981,"children":1982},{},[1983],{"type":31,"value":1984},"对部分路由预先生成 HTML",{"type":25,"tag":511,"props":1986,"children":1987},{},[1988],{"type":31,"value":1989},"适合混合站点",{"type":25,"tag":39,"props":1991,"children":1992},{},[1993],{"type":31,"value":1809},{"type":25,"tag":547,"props":1995,"children":1996},{},[1997,2002],{"type":25,"tag":511,"props":1998,"children":1999},{},[2000],{"type":31,"value":2001},"首页/核心落地页需要 SEO",{"type":25,"tag":511,"props":2003,"children":2004},{},[2005],{"type":31,"value":2006},"工具页/用户页不需要 SEO",{"type":25,"tag":781,"props":2008,"children":2009},{},[],{"type":25,"tag":26,"props":2011,"children":2013},{"id":2012},"_3-选型矩阵可直接用",[2014],{"type":31,"value":2015},"3. 选型矩阵（可直接用）",{"type":25,"tag":39,"props":2017,"children":2018},{},[2019],{"type":31,"value":2020},"你可以按路由维度做选型，而不是全站一刀切。",{"type":25,"tag":2022,"props":2023,"children":2024},"table",{},[2025,2053],{"type":25,"tag":2026,"props":2027,"children":2028},"thead",{},[2029],{"type":25,"tag":2030,"props":2031,"children":2032},"tr",{},[2033,2039,2043,2048],{"type":25,"tag":2034,"props":2035,"children":2036},"th",{},[2037],{"type":31,"value":2038},"页面类型",{"type":25,"tag":2034,"props":2040,"children":2041},{},[2042],{"type":31,"value":1665},{"type":25,"tag":2034,"props":2044,"children":2045},{},[2046],{"type":31,"value":2047},"更新频率",{"type":25,"tag":2034,"props":2049,"children":2050},{},[2051],{"type":31,"value":2052},"推荐",{"type":25,"tag":2054,"props":2055,"children":2056},"tbody",{},[2057,2081,2102,2123,2144,2166],{"type":25,"tag":2030,"props":2058,"children":2059},{},[2060,2066,2071,2076],{"type":25,"tag":2061,"props":2062,"children":2063},"td",{},[2064],{"type":31,"value":2065},"文章详情",{"type":25,"tag":2061,"props":2067,"children":2068},{},[2069],{"type":31,"value":2070},"高",{"type":25,"tag":2061,"props":2072,"children":2073},{},[2074],{"type":31,"value":2075},"中",{"type":25,"tag":2061,"props":2077,"children":2078},{},[2079],{"type":31,"value":2080},"SSG/ISR",{"type":25,"tag":2030,"props":2082,"children":2083},{},[2084,2089,2093,2097],{"type":25,"tag":2061,"props":2085,"children":2086},{},[2087],{"type":31,"value":2088},"文章列表",{"type":25,"tag":2061,"props":2090,"children":2091},{},[2092],{"type":31,"value":2070},{"type":25,"tag":2061,"props":2094,"children":2095},{},[2096],{"type":31,"value":2075},{"type":25,"tag":2061,"props":2098,"children":2099},{},[2100],{"type":31,"value":2101},"SSG/ISR（注意聚合页）",{"type":25,"tag":2030,"props":2103,"children":2104},{},[2105,2110,2114,2118],{"type":25,"tag":2061,"props":2106,"children":2107},{},[2108],{"type":31,"value":2109},"产品详情",{"type":25,"tag":2061,"props":2111,"children":2112},{},[2113],{"type":31,"value":2070},{"type":25,"tag":2061,"props":2115,"children":2116},{},[2117],{"type":31,"value":2070},{"type":25,"tag":2061,"props":2119,"children":2120},{},[2121],{"type":31,"value":2122},"ISR/SSR（配缓存）",{"type":25,"tag":2030,"props":2124,"children":2125},{},[2126,2131,2135,2139],{"type":25,"tag":2061,"props":2127,"children":2128},{},[2129],{"type":31,"value":2130},"搜索结果",{"type":25,"tag":2061,"props":2132,"children":2133},{},[2134],{"type":31,"value":2075},{"type":25,"tag":2061,"props":2136,"children":2137},{},[2138],{"type":31,"value":2070},{"type":25,"tag":2061,"props":2140,"children":2141},{},[2142],{"type":31,"value":2143},"SSR/CSR（配 noindex）",{"type":25,"tag":2030,"props":2145,"children":2146},{},[2147,2152,2157,2161],{"type":25,"tag":2061,"props":2148,"children":2149},{},[2150],{"type":31,"value":2151},"用户中心",{"type":25,"tag":2061,"props":2153,"children":2154},{},[2155],{"type":31,"value":2156},"低",{"type":25,"tag":2061,"props":2158,"children":2159},{},[2160],{"type":31,"value":2070},{"type":25,"tag":2061,"props":2162,"children":2163},{},[2164],{"type":31,"value":2165},"CSR",{"type":25,"tag":2030,"props":2167,"children":2168},{},[2169,2174,2179,2183],{"type":25,"tag":2061,"props":2170,"children":2171},{},[2172],{"type":31,"value":2173},"工具页",{"type":25,"tag":2061,"props":2175,"children":2176},{},[2177],{"type":31,"value":2178},"低/中",{"type":25,"tag":2061,"props":2180,"children":2181},{},[2182],{"type":31,"value":2075},{"type":25,"tag":2061,"props":2184,"children":2185},{},[2186],{"type":31,"value":2187},"CSR + 预渲染核心路由",{"type":25,"tag":781,"props":2189,"children":2190},{},[],{"type":25,"tag":26,"props":2192,"children":2194},{"id":2193},"_4-混合渲染真正的生产最优解",[2195],{"type":31,"value":2196},"4. 混合渲染：真正的生产最优解",{"type":25,"tag":39,"props":2198,"children":2199},{},[2200],{"type":31,"value":2201},"生产上最常见的模式是混合：",{"type":25,"tag":547,"props":2203,"children":2204},{},[2205,2210,2215],{"type":25,"tag":511,"props":2206,"children":2207},{},[2208],{"type":31,"value":2209},"公共内容：静态化（SSG/ISR）+ CDN",{"type":25,"tag":511,"props":2211,"children":2212},{},[2213],{"type":31,"value":2214},"用户态内容：CSR 或 SSR（private/no-store）",{"type":25,"tag":511,"props":2216,"children":2217},{},[2218],{"type":31,"value":2219},"关键落地页：预渲染",{"type":25,"tag":39,"props":2221,"children":2222},{},[2223],{"type":31,"value":2224},"好处：",{"type":25,"tag":547,"props":2226,"children":2227},{},[2228,2233],{"type":25,"tag":511,"props":2229,"children":2230},{},[2231],{"type":31,"value":2232},"SEO 与性能兼得",{"type":25,"tag":511,"props":2234,"children":2235},{},[2236],{"type":31,"value":2237},"成本可控",{"type":25,"tag":781,"props":2239,"children":2240},{},[],{"type":25,"tag":26,"props":2242,"children":2244},{"id":2243},"_5-缓存与失效模式落地的关键",[2245],{"type":31,"value":2246},"5. 缓存与失效：模式落地的关键",{"type":25,"tag":39,"props":2248,"children":2249},{},[2250],{"type":31,"value":2251},"无论你选 SSR 还是 ISR，本质都离不开缓存。",{"type":25,"tag":39,"props":2253,"children":2254},{},[2255],{"type":31,"value":2256},"建议把缓存分层：",{"type":25,"tag":547,"props":2258,"children":2259},{},[2260,2265,2270,2275],{"type":25,"tag":511,"props":2261,"children":2262},{},[2263],{"type":31,"value":2264},"浏览器",{"type":25,"tag":511,"props":2266,"children":2267},{},[2268],{"type":31,"value":2269},"CDN",{"type":25,"tag":511,"props":2271,"children":2272},{},[2273],{"type":31,"value":2274},"应用侧（server runtime）",{"type":25,"tag":511,"props":2276,"children":2277},{},[2278],{"type":31,"value":2279},"数据侧（Redis/DB）",{"type":25,"tag":39,"props":2281,"children":2282},{},[2283],{"type":31,"value":2284},"并给每条路由明确：",{"type":25,"tag":547,"props":2286,"children":2287},{},[2288,2293,2298],{"type":25,"tag":511,"props":2289,"children":2290},{},[2291],{"type":31,"value":2292},"是否 public/private",{"type":25,"tag":511,"props":2294,"children":2295},{},[2296],{"type":31,"value":2297},"TTL 多久",{"type":25,"tag":511,"props":2299,"children":2300},{},[2301],{"type":31,"value":2302},"写操作后如何失效",{"type":25,"tag":781,"props":2304,"children":2305},{},[],{"type":25,"tag":26,"props":2307,"children":2309},{"id":2308},"_6-常见误区",[2310],{"type":31,"value":2311},"6. 常见误区",{"type":25,"tag":547,"props":2313,"children":2314},{},[2315,2320,2325],{"type":25,"tag":511,"props":2316,"children":2317},{},[2318],{"type":31,"value":2319},"“SSR 一定更快”：不一定，TTFB 可能更慢；LCP 受资源与主线程影响更大",{"type":25,"tag":511,"props":2321,"children":2322},{},[2323],{"type":31,"value":2324},"“SSG 一定更好”：构建成本与发布延迟可能无法接受",{"type":25,"tag":511,"props":2326,"children":2327},{},[2328],{"type":31,"value":2329},"“全站一个模式最省事”：短期省事，长期很难优化与扩展",{"type":25,"tag":781,"props":2331,"children":2332},{},[],{"type":25,"tag":26,"props":2334,"children":2336},{"id":2335},"_7-上线检查清单",[2337],{"type":31,"value":2338},"7. 上线检查清单",{"type":25,"tag":547,"props":2340,"children":2343},{"className":2341},[2342],"contains-task-list",[2344,2356,2365,2374,2383],{"type":25,"tag":511,"props":2345,"children":2348},{"className":2346},[2347],"task-list-item",[2349,2354],{"type":25,"tag":2350,"props":2351,"children":2353},"input",{"disabled":19,"type":2352},"checkbox",[],{"type":31,"value":2355}," 按路由明确 SEO 需求（哪些可索引）",{"type":25,"tag":511,"props":2357,"children":2359},{"className":2358},[2347],[2360,2363],{"type":25,"tag":2350,"props":2361,"children":2362},{"disabled":19,"type":2352},[],{"type":31,"value":2364}," 用户态页面是否 private/no-store",{"type":25,"tag":511,"props":2366,"children":2368},{"className":2367},[2347],[2369,2372],{"type":25,"tag":2350,"props":2370,"children":2371},{"disabled":19,"type":2352},[],{"type":31,"value":2373}," 公共内容是否走 CDN 并有合理 TTL",{"type":25,"tag":511,"props":2375,"children":2377},{"className":2376},[2347],[2378,2381],{"type":25,"tag":2350,"props":2379,"children":2380},{"disabled":19,"type":2352},[],{"type":31,"value":2382}," 更新路径是否有失效机制（发布事件）",{"type":25,"tag":511,"props":2384,"children":2386},{"className":2385},[2347],[2387,2390],{"type":25,"tag":2350,"props":2388,"children":2389},{"disabled":19,"type":2352},[],{"type":31,"value":2391}," 是否有 RUM/日志来验证效果",{"type":25,"tag":781,"props":2393,"children":2394},{},[],{"type":25,"tag":26,"props":2396,"children":2397},{"id":498},[2398],{"type":31,"value":498},{"type":25,"tag":39,"props":2400,"children":2401},{},[2402],{"type":31,"value":2403},"Nuxt 渲染模式选型的正确做法是：",{"type":25,"tag":547,"props":2405,"children":2406},{},[2407,2412,2417],{"type":25,"tag":511,"props":2408,"children":2409},{},[2410],{"type":31,"value":2411},"以“页面类型”而不是“站点整体”做选择",{"type":25,"tag":511,"props":2413,"children":2414},{},[2415],{"type":31,"value":2416},"把缓存与失效当成一等公民",{"type":25,"tag":511,"props":2418,"children":2419},{},[2420],{"type":31,"value":2421},"用观测验证，而不是凭感觉",{"title":7,"searchDepth":626,"depth":626,"links":2423},[2424,2425,2426,2433,2434,2435,2436,2437,2438],{"id":1672,"depth":629,"text":1660},{"id":1730,"depth":629,"text":1733},{"id":1772,"depth":629,"text":1775,"children":2427},[2428,2429,2430,2431,2432],{"id":1778,"depth":626,"text":1781},{"id":1831,"depth":626,"text":1834},{"id":1871,"depth":626,"text":1874},{"id":1911,"depth":626,"text":1914},{"id":1969,"depth":626,"text":1972},{"id":2012,"depth":629,"text":2015},{"id":2193,"depth":629,"text":2196},{"id":2243,"depth":629,"text":2246},{"id":2308,"depth":629,"text":2311},{"id":2335,"depth":629,"text":2338},{"id":498,"depth":629,"text":498},"content:topics:nuxt:nuxt-rendering-modes-guide.md","topics/nuxt/nuxt-rendering-modes-guide.md","topics/nuxt/nuxt-rendering-modes-guide",{"_path":2443,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":2444,"description":2445,"date":2446,"topic":5,"author":11,"tags":2447,"image":2452,"featured":19,"readingTime":2453,"body":2454,"_type":669,"_id":2973,"_source":671,"_file":2974,"_stem":2975,"_extension":674},"/topics/nuxt/nuxt4-major-updates-overview","Nuxt 4 重大更新全面解读：架构升级与开发体验革新","深入解析 Nuxt 4 的重大更新，包括新目录结构、Nitro 2.0 引擎、兼容性层变化、性能优化等核心改进，帮助开发者全面了解新版本特性并做好升级准备。","2026-01-18",[2448,2449,16,2450,2451],"Nuxt 4","Vue","全栈框架","版本升级","/images/topics/nuxt/nuxt4-features-overview.jpg",16,{"type":22,"children":2455,"toc":2934},[2456,2462,2468,2473,2478,2484,2490,2495,2503,2511,2519,2525,2530,2539,2545,2554,2560,2566,2571,2580,2586,2595,2601,2610,2616,2622,2631,2637,2646,2652,2661,2667,2673,2682,2688,2697,2703,2712,2721,2727,2733,2742,2748,2757,2763,2772,2778,2784,2793,2799,2808,2814,2820,2830,2836,2845,2851,2856,2861,2866,2884,2887,2891],{"type":25,"tag":26,"props":2457,"children":2459},{"id":2458},"nuxt-4-重大更新全面解读",[2460],{"type":31,"value":2461},"Nuxt 4 重大更新全面解读",{"type":25,"tag":26,"props":2463,"children":2465},{"id":2464},"引言nuxt-的又一次进化",[2466],{"type":31,"value":2467},"引言：Nuxt 的又一次进化",{"type":25,"tag":39,"props":2469,"children":2470},{},[2471],{"type":31,"value":2472},"Nuxt 4 的发布标志着这个 Vue 生态中最受欢迎的全栈框架又迈入了新阶段。从 Nuxt 2 到 Nuxt 3 是一次彻底重写，而 Nuxt 3 到 Nuxt 4 则是在成熟架构上的精进打磨——更清晰的目录结构、更强大的引擎、更好的开发体验。",{"type":25,"tag":39,"props":2474,"children":2475},{},[2476],{"type":31,"value":2477},"这篇文章将全面解读 Nuxt 4 的核心变化，帮助你理解这些改动背后的设计理念，以及它们将如何影响你的日常开发。",{"type":25,"tag":26,"props":2479,"children":2481},{"id":2480},"第一部分新目录结构",[2482],{"type":31,"value":2483},"第一部分：新目录结构",{"type":25,"tag":73,"props":2485,"children":2487},{"id":2486},"_11-从扁平到分层",[2488],{"type":31,"value":2489},"1.1 从扁平到分层",{"type":25,"tag":39,"props":2491,"children":2492},{},[2493],{"type":31,"value":2494},"Nuxt 4 引入了新的目录结构，将应用代码与配置分离：",{"type":25,"tag":80,"props":2496,"children":2498},{"code":2497},"# Nuxt 3 目录结构\nproject/\n├── .nuxt/\n├── app.vue\n├── components/\n├── composables/\n├── layouts/\n├── middleware/\n├── pages/\n├── plugins/\n├── public/\n├── server/\n├── nuxt.config.ts\n└── package.json\n\n# Nuxt 4 新目录结构\nproject/\n├── .nuxt/\n├── app/                  # 应用代码集中在 app/ 目录\n│   ├── app.vue\n│   ├── components/\n│   ├── composables/\n│   ├── layouts/\n│   ├── middleware/\n│   ├── pages/\n│   └── plugins/\n├── public/\n├── server/\n├── nuxt.config.ts\n└── package.json\n",[2499],{"type":25,"tag":45,"props":2500,"children":2501},{"__ignoreMap":7},[2502],{"type":31,"value":2497},{"type":25,"tag":39,"props":2504,"children":2505},{},[2506],{"type":25,"tag":418,"props":2507,"children":2508},{},[2509],{"type":31,"value":2510},"为什么这样设计？",{"type":25,"tag":80,"props":2512,"children":2514},{"code":2513},"┌────────────────────────────────────────────────────────────┐\n│              新目录结构的设计理念                            │\n├────────────────────────────────────────────────────────────┤\n│                                                            │\n│  1. 关注点分离                                             │\n│     ├── app/ - 客户端/同构代码                             │\n│     ├── server/ - 服务端代码                               │\n│     └── 根目录 - 配置和公共资源                             │\n│                                                            │\n│  2. 更清晰的项目边界                                       │\n│     ├── Monorepo 友好                                      │\n│     ├── 多应用项目更清晰                                   │\n│     └── 与其他框架惯例对齐                                 │\n│                                                            │\n│  3. 未来扩展性                                             │\n│     ├── 为多前端支持做准备                                 │\n│     └── 便于工具链识别和处理                               │\n│                                                            │\n└────────────────────────────────────────────────────────────┘\n",[2515],{"type":25,"tag":45,"props":2516,"children":2517},{"__ignoreMap":7},[2518],{"type":31,"value":2513},{"type":25,"tag":73,"props":2520,"children":2522},{"id":2521},"_12-向后兼容",[2523],{"type":31,"value":2524},"1.2 向后兼容",{"type":25,"tag":39,"props":2526,"children":2527},{},[2528],{"type":31,"value":2529},"Nuxt 4 提供了兼容性选项，允许继续使用旧目录结构：",{"type":25,"tag":80,"props":2531,"children":2534},{"code":2532,"language":278,"meta":7,"className":2533},"// nuxt.config.ts\nexport default defineNuxtConfig({\n  future: {\n    compatibilityVersion: 4  // 启用 Nuxt 4 特性\n  },\n  \n  // 如果需要继续使用旧目录结构\n  srcDir: './',  // 而不是 'app/'\n  \n  // 或者自定义目录\n  dir: {\n    app: 'src',\n    pages: 'src/pages',\n    layouts: 'src/layouts'\n  }\n});\n",[280],[2535],{"type":25,"tag":45,"props":2536,"children":2537},{"__ignoreMap":7},[2538],{"type":31,"value":2532},{"type":25,"tag":73,"props":2540,"children":2542},{"id":2541},"_13-appconfigts-变化",[2543],{"type":31,"value":2544},"1.3 app.config.ts 变化",{"type":25,"tag":80,"props":2546,"children":2549},{"code":2547,"language":278,"meta":7,"className":2548},"// Nuxt 3: app.config.ts 在项目根目录\n// Nuxt 4: app.config.ts 移入 app/ 目录\n\n// app/app.config.ts\nexport default defineAppConfig({\n  ui: {\n    primary: 'green',\n    gray: 'slate'\n  },\n  \n  // 类型安全的应用配置\n  meta: {\n    name: 'My App',\n    description: 'A Nuxt 4 Application'\n  }\n});\n\n// 使用方式不变\nconst appConfig = useAppConfig();\nconsole.log(appConfig.ui.primary);  // 'green'\n",[280],[2550],{"type":25,"tag":45,"props":2551,"children":2552},{"__ignoreMap":7},[2553],{"type":31,"value":2547},{"type":25,"tag":26,"props":2555,"children":2557},{"id":2556},"第二部分nitro-20-引擎升级",[2558],{"type":31,"value":2559},"第二部分：Nitro 2.0 引擎升级",{"type":25,"tag":73,"props":2561,"children":2563},{"id":2562},"_21-性能提升",[2564],{"type":31,"value":2565},"2.1 性能提升",{"type":25,"tag":39,"props":2567,"children":2568},{},[2569],{"type":31,"value":2570},"Nitro 2.0 带来了显著的性能改进：",{"type":25,"tag":80,"props":2572,"children":2575},{"code":2573,"language":278,"meta":7,"className":2574},"// 冷启动时间优化\n// Nitro 1.x: ~150ms\n// Nitro 2.0: ~80ms (约 47% 提升)\n\n// 内存占用优化\n// 同样的应用，内存占用减少约 20%\n\n// 原因：\n// - 更高效的模块加载\n// - 优化的树摇（tree-shaking）\n// - 减少运行时开销\n",[280],[2576],{"type":25,"tag":45,"props":2577,"children":2578},{"__ignoreMap":7},[2579],{"type":31,"value":2573},{"type":25,"tag":73,"props":2581,"children":2583},{"id":2582},"_22-新的路由系统",[2584],{"type":31,"value":2585},"2.2 新的路由系统",{"type":25,"tag":80,"props":2587,"children":2590},{"code":2588,"language":278,"meta":7,"className":2589},"// server/routes/api/[...slug].ts\n\n// Nitro 2.0 新的路由定义方式\nexport default defineEventHandler({\n  // 路由级别配置\n  config: {\n    // 缓存配置\n    cache: {\n      maxAge: 60,\n      staleMaxAge: 3600,\n      swr: true\n    },\n    \n    // CORS 配置\n    cors: {\n      origin: ['https://example.com'],\n      methods: ['GET', 'POST']\n    }\n  },\n  \n  // 处理函数\n  handler: async (event) => {\n    const slug = event.context.params?.slug;\n    return { data: await fetchData(slug) };\n  }\n});\n\n// 支持中间件链\nexport default defineEventHandler({\n  onRequest: [authMiddleware, rateLimitMiddleware],\n  onBeforeResponse: [logMiddleware],\n  \n  handler: (event) => {\n    return { message: 'Hello' };\n  }\n});\n",[280],[2591],{"type":25,"tag":45,"props":2592,"children":2593},{"__ignoreMap":7},[2594],{"type":31,"value":2588},{"type":25,"tag":73,"props":2596,"children":2598},{"id":2597},"_23-增强的数据获取",[2599],{"type":31,"value":2600},"2.3 增强的数据获取",{"type":25,"tag":80,"props":2602,"children":2605},{"code":2603,"language":278,"meta":7,"className":2604},"// Nitro 2.0 改进的 $fetch\n\n// 自动请求去重\nconst [user, posts] = await Promise.all([\n  $fetch('/api/user/1'),\n  $fetch('/api/user/1')  // 相同请求自动去重\n]);\n\n// 请求拦截器\nexport default defineNuxtPlugin(() => {\n  const { $fetch } = useNuxtApp();\n  \n  // 全局请求配置\n  globalThis.$fetch = $fetch.create({\n    onRequest({ request, options }) {\n      options.headers = {\n        ...options.headers,\n        Authorization: `Bearer ${getToken()}`\n      };\n    },\n    \n    onResponseError({ response }) {\n      if (response.status === 401) {\n        navigateTo('/login');\n      }\n    }\n  });\n});\n",[280],[2606],{"type":25,"tag":45,"props":2607,"children":2608},{"__ignoreMap":7},[2609],{"type":31,"value":2603},{"type":25,"tag":26,"props":2611,"children":2613},{"id":2612},"第三部分兼容性层变化",[2614],{"type":31,"value":2615},"第三部分：兼容性层变化",{"type":25,"tag":73,"props":2617,"children":2619},{"id":2618},"_31-移除的废弃-api",[2620],{"type":31,"value":2621},"3.1 移除的废弃 API",{"type":25,"tag":80,"props":2623,"children":2626},{"code":2624,"language":278,"meta":7,"className":2625},"// Nuxt 4 移除了 Nuxt 3 中标记为废弃的 API\n\n// ❌ 已移除\nimport { defineNuxtRouteMiddleware } from '#app'\n\n// ✅ 使用新的 API\nimport { defineNuxtRouteMiddleware } from 'nuxt/app'\n\n// ❌ 已移除\nconst nuxtApp = useNuxtApp()\nnuxtApp.$router  // 不再有 $ 前缀\n\n// ✅ 使用 composables\nconst router = useRouter()\n\n// ❌ 已移除\nuseAsyncData('key', () => fetch(), { lazy: true })\n\n// ✅ 使用 useLazyAsyncData\nuseLazyAsyncData('key', () => fetch())\n",[280],[2627],{"type":25,"tag":45,"props":2628,"children":2629},{"__ignoreMap":7},[2630],{"type":31,"value":2624},{"type":25,"tag":73,"props":2632,"children":2634},{"id":2633},"_32-类型系统改进",[2635],{"type":31,"value":2636},"3.2 类型系统改进",{"type":25,"tag":80,"props":2638,"children":2641},{"code":2639,"language":278,"meta":7,"className":2640},"// Nuxt 4 增强的类型推导\n\n// 页面元数据类型\n// pages/dashboard.vue\n\u003Cscript setup lang=\"ts\">\ndefinePageMeta({\n  // 类型自动推导，IDE 自动补全\n  layout: 'admin',  // 只能填已定义的布局\n  middleware: ['auth'],  // 只能填已定义的中间件\n  \n  // 自定义元数据\n  title: '仪表盘',\n  requiresAuth: true\n});\n\u003C/script>\n\n// 路由参数类型\n// pages/users/[id].vue\n\u003Cscript setup lang=\"ts\">\nconst route = useRoute('users-id');\n//             ^? RouteLocationNormalized\u003C'users-id'>\n\nroute.params.id  // 类型: string\n\u003C/script>\n\n// 运行时配置类型\n// nuxt.config.ts\nexport default defineNuxtConfig({\n  runtimeConfig: {\n    // 私有配置（仅服务端）\n    apiSecret: '',\n    \n    // 公开配置\n    public: {\n      apiBase: ''\n    }\n  }\n});\n\n// 使用时自动推导类型\nconst config = useRuntimeConfig();\nconfig.apiSecret;  // 服务端可用\nconfig.public.apiBase;  // 客户端可用\n",[280],[2642],{"type":25,"tag":45,"props":2643,"children":2644},{"__ignoreMap":7},[2645],{"type":31,"value":2639},{"type":25,"tag":73,"props":2647,"children":2649},{"id":2648},"_33-useasyncdata-改进",[2650],{"type":31,"value":2651},"3.3 useAsyncData 改进",{"type":25,"tag":80,"props":2653,"children":2656},{"code":2654,"language":278,"meta":7,"className":2655},"// Nuxt 4 中 useAsyncData 的改进\n\n// 改进 1：更好的错误处理\nconst { data, error, status } = await useAsyncData('users', () => $fetch('/api/users'));\n\n// status 新增更多状态\n// 'idle' | 'pending' | 'success' | 'error'\n\n// 改进 2：简化的刷新机制\nconst { refresh, clear } = await useAsyncData('users', () => $fetch('/api/users'));\n\n// 带参数刷新\nawait refresh({ dedupe: true });\n\n// 清除缓存\nclear();\n\n// 改进 3：深度响应式默认关闭\nconst { data } = await useAsyncData('config', () => $fetch('/api/config'), {\n  deep: false  // 默认 false，提升性能\n});\n\n// 需要深度响应式时显式开启\nconst { data } = await useAsyncData('form', () => $fetch('/api/form'), {\n  deep: true\n});\n",[280],[2657],{"type":25,"tag":45,"props":2658,"children":2659},{"__ignoreMap":7},[2660],{"type":31,"value":2654},{"type":25,"tag":26,"props":2662,"children":2664},{"id":2663},"第四部分开发体验改进",[2665],{"type":31,"value":2666},"第四部分：开发体验改进",{"type":25,"tag":73,"props":2668,"children":2670},{"id":2669},"_41-nuxt-devtools-增强",[2671],{"type":31,"value":2672},"4.1 Nuxt DevTools 增强",{"type":25,"tag":80,"props":2674,"children":2677},{"code":2675,"language":278,"meta":7,"className":2676},"// Nuxt 4 内置增强版 DevTools\n\n// 新功能：\n// 1. 组件性能分析\n// - 渲染时间追踪\n// - 不必要渲染检测\n// - 内存使用监控\n\n// 2. 数据流可视化\n// - useAsyncData 调用时序图\n// - 数据缓存状态\n// - 请求去重可视化\n\n// 3. 路由调试\n// - 路由匹配过程\n// - 中间件执行顺序\n// - 导航守卫状态\n\n// 启用高级功能\nexport default defineNuxtConfig({\n  devtools: {\n    enabled: true,\n    \n    // 新选项\n    timeline: {\n      enabled: true  // 启用时间线\n    }\n  }\n});\n",[280],[2678],{"type":25,"tag":45,"props":2679,"children":2680},{"__ignoreMap":7},[2681],{"type":31,"value":2675},{"type":25,"tag":73,"props":2683,"children":2685},{"id":2684},"_42-热更新优化",[2686],{"type":31,"value":2687},"4.2 热更新优化",{"type":25,"tag":80,"props":2689,"children":2692},{"code":2690,"language":278,"meta":7,"className":2691},"// Nuxt 4 大幅改进了热更新体验\n\n// 1. 更快的 HMR\n// - 组件变更：\u003C 100ms\n// - 页面变更：\u003C 200ms\n// - 配置变更：\u003C 1s\n\n// 2. 保持状态的更新\n// composables 更新不再丢失组件状态\nconst count = ref(0);  // 更新文件后，值保持\n\n// 3. 错误恢复\n// 修复语法错误后自动恢复，无需重启\n",[280],[2693],{"type":25,"tag":45,"props":2694,"children":2695},{"__ignoreMap":7},[2696],{"type":31,"value":2690},{"type":25,"tag":73,"props":2698,"children":2700},{"id":2699},"_43-错误处理增强",[2701],{"type":31,"value":2702},"4.3 错误处理增强",{"type":25,"tag":80,"props":2704,"children":2707},{"code":2705,"language":115,"meta":7,"className":2706},"\u003C!-- app/error.vue - 增强的错误页面 -->\n\u003Ctemplate>\n  \u003Cdiv class=\"error-page\">\n    \u003Ch1>{{ error.statusCode }}\u003C/h1>\n    \u003Cp>{{ error.message }}\u003C/p>\n    \n    \u003C!-- Nuxt 4 新增：错误堆栈（开发环境） -->\n    \u003Cpre v-if=\"isDev && error.stack\">{{ error.stack }}\u003C/pre>\n    \n    \u003C!-- 新增：错误上下文 -->\n    \u003Cdetails v-if=\"error.data\">\n      \u003Csummary>详细信息\u003C/summary>\n      \u003Cpre>{{ error.data }}\u003C/pre>\n    \u003C/details>\n    \n    \u003Cbutton @click=\"handleError\">重试\u003C/button>\n  \u003C/div>\n\u003C/template>\n\n\u003Cscript setup lang=\"ts\">\nconst props = defineProps\u003C{\n  error: {\n    statusCode: number\n    message: string\n    stack?: string\n    data?: Record\u003Cstring, unknown>\n  }\n}>();\n\nconst isDev = process.dev;\n\nfunction handleError() {\n  clearError({ redirect: '/' });\n}\n\u003C/script>\n",[117],[2708],{"type":25,"tag":45,"props":2709,"children":2710},{"__ignoreMap":7},[2711],{"type":31,"value":2705},{"type":25,"tag":80,"props":2713,"children":2716},{"code":2714,"language":278,"meta":7,"className":2715},"// server/api/users.ts - 增强的服务端错误\n\nexport default defineEventHandler((event) => {\n  const id = getRouterParam(event, 'id');\n  \n  if (!id) {\n    throw createError({\n      statusCode: 400,\n      message: '缺少用户 ID',\n      \n      // Nuxt 4 新增：结构化错误数据\n      data: {\n        field: 'id',\n        constraint: 'required'\n      }\n    });\n  }\n  \n  // 业务错误\n  throw createError({\n    statusCode: 404,\n    message: '用户不存在',\n    data: {\n      userId: id,\n      suggestion: '请检查用户 ID 是否正确'\n    }\n  });\n});\n",[280],[2717],{"type":25,"tag":45,"props":2718,"children":2719},{"__ignoreMap":7},[2720],{"type":31,"value":2714},{"type":25,"tag":26,"props":2722,"children":2724},{"id":2723},"第五部分性能优化特性",[2725],{"type":31,"value":2726},"第五部分：性能优化特性",{"type":25,"tag":73,"props":2728,"children":2730},{"id":2729},"_51-更智能的代码分割",[2731],{"type":31,"value":2732},"5.1 更智能的代码分割",{"type":25,"tag":80,"props":2734,"children":2737},{"code":2735,"language":278,"meta":7,"className":2736},"// Nuxt 4 的自动代码分割更加智能\n\n// 自动路由分割\n// pages/dashboard/\n//   index.vue      -> chunks/dashboard.js\n//   settings.vue   -> chunks/dashboard-settings.js\n//   analytics.vue  -> chunks/dashboard-analytics.js\n\n// 组件级分割\n// components/\n//   HeavyChart.vue -> chunks/heavy-chart.js (自动延迟加载)\n\n// 手动优化\nexport default defineNuxtConfig({\n  vite: {\n    build: {\n      rollupOptions: {\n        output: {\n          // 自定义分块策略\n          manualChunks: {\n            'vendor-vue': ['vue', 'vue-router', 'pinia'],\n            'vendor-ui': ['element-plus']\n          }\n        }\n      }\n    }\n  }\n});\n",[280],[2738],{"type":25,"tag":45,"props":2739,"children":2740},{"__ignoreMap":7},[2741],{"type":31,"value":2735},{"type":25,"tag":73,"props":2743,"children":2745},{"id":2744},"_52-图片优化增强",[2746],{"type":31,"value":2747},"5.2 图片优化增强",{"type":25,"tag":80,"props":2749,"children":2752},{"code":2750,"language":115,"meta":7,"className":2751},"\u003C!-- Nuxt 4 的 nuxt-img 增强 -->\n\u003Ctemplate>\n  \u003CNuxtImg\n    src=\"/images/hero.jpg\"\n    \n    \u003C!-- 新增：自动格式选择 -->\n    format=\"webp,avif\"\n    \n    \u003C!-- 新增：艺术指导响应式 -->\n    :sources=\"[\n      { media: '(max-width: 640px)', src: '/images/hero-mobile.jpg' },\n      { media: '(max-width: 1024px)', src: '/images/hero-tablet.jpg' }\n    ]\"\n    \n    \u003C!-- 新增：模糊占位符 -->\n    placeholder=\"/images/hero-blur.jpg\"\n    \n    \u003C!-- 新增：性能提示 -->\n    :priority=\"true\"\n    fetchpriority=\"high\"\n  />\n\u003C/template>\n\n\u003Cscript setup>\n// 编程式使用\nconst img = useImage();\n\n// 生成优化后的 URL\nconst optimizedUrl = img('/images/photo.jpg', {\n  width: 800,\n  height: 600,\n  format: 'webp',\n  quality: 80\n});\n\u003C/script>\n",[117],[2753],{"type":25,"tag":45,"props":2754,"children":2755},{"__ignoreMap":7},[2756],{"type":31,"value":2750},{"type":25,"tag":73,"props":2758,"children":2760},{"id":2759},"_53-服务端渲染优化",[2761],{"type":31,"value":2762},"5.3 服务端渲染优化",{"type":25,"tag":80,"props":2764,"children":2767},{"code":2765,"language":278,"meta":7,"className":2766},"// Nuxt 4 SSR 性能优化\n\n// 1. 流式 SSR\n// nuxt.config.ts\nexport default defineNuxtConfig({\n  nitro: {\n    // 启用流式 SSR\n    experimental: {\n      wasm: true\n    }\n  },\n  \n  // 组件流式渲染\n  experimental: {\n    componentIslands: true,  // 组件岛\n    payloadExtraction: true  // Payload 提取\n  }\n});\n\n// 2. 选择性 Hydration\n// pages/article/[id].vue\n\u003Ctemplate>\n  \u003Carticle>\n    \u003C!-- 静态内容，不需要 hydration -->\n    \u003CNuxtIsland name=\"ArticleContent\" :props=\"{ content }\" />\n    \n    \u003C!-- 需要交互的部分 -->\n    \u003CCommentSection :articleId=\"id\" />\n  \u003C/article>\n\u003C/template>\n\n// 3. 预加载优化\n\u003Cscript setup>\n// 智能预加载\nconst { data } = await useAsyncData('article', () => $fetch('/api/article/' + id), {\n  // 预加载相关数据\n  preload: [\n    () => $fetch('/api/comments/' + id),\n    () => $fetch('/api/related/' + id)\n  ]\n});\n\u003C/script>\n",[280],[2768],{"type":25,"tag":45,"props":2769,"children":2770},{"__ignoreMap":7},[2771],{"type":31,"value":2765},{"type":25,"tag":26,"props":2773,"children":2775},{"id":2774},"第六部分模块生态更新",[2776],{"type":31,"value":2777},"第六部分：模块生态更新",{"type":25,"tag":73,"props":2779,"children":2781},{"id":2780},"_61-官方模块适配",[2782],{"type":31,"value":2783},"6.1 官方模块适配",{"type":25,"tag":80,"props":2785,"children":2788},{"code":2786,"language":278,"meta":7,"className":2787},"// 主要官方模块的 Nuxt 4 兼容版本\n\n// @nuxtjs/i18n v9\nexport default defineNuxtConfig({\n  modules: ['@nuxtjs/i18n'],\n  \n  i18n: {\n    // 新增：编译时优化\n    bundle: {\n      optimizeTranslations: true\n    },\n    \n    // 新增：类型生成\n    types: 'composition'\n  }\n});\n\n// @nuxt/content v3\nexport default defineNuxtConfig({\n  modules: ['@nuxt/content'],\n  \n  content: {\n    // 新增：更强的查询 API\n    experimental: {\n      clientDB: true,\n      stripQueryParameters: true\n    }\n  }\n});\n\n// @pinia/nuxt v0.6\nexport default defineNuxtConfig({\n  modules: ['@pinia/nuxt'],\n  \n  pinia: {\n    // 新增：自动导入优化\n    storesDirs: ['./stores/**']\n  }\n});\n",[280],[2789],{"type":25,"tag":45,"props":2790,"children":2791},{"__ignoreMap":7},[2792],{"type":31,"value":2786},{"type":25,"tag":73,"props":2794,"children":2796},{"id":2795},"_62-创建-nuxt-4-兼容模块",[2797],{"type":31,"value":2798},"6.2 创建 Nuxt 4 兼容模块",{"type":25,"tag":80,"props":2800,"children":2803},{"code":2801,"language":278,"meta":7,"className":2802},"// 模块开发的新约定\n\n// my-module/src/module.ts\nimport { defineNuxtModule, createResolver } from '@nuxt/kit'\n\nexport default defineNuxtModule({\n  meta: {\n    name: 'my-module',\n    configKey: 'myModule',\n    \n    // Nuxt 4 要求\n    compatibility: {\n      nuxt: '^4.0.0'\n    }\n  },\n  \n  defaults: {\n    enabled: true\n  },\n  \n  setup(options, nuxt) {\n    const resolver = createResolver(import.meta.url);\n    \n    // 使用新的 hook API\n    nuxt.hook('app:resolve', (app) => {\n      // app 配置\n    });\n    \n    // 添加运行时插件\n    addPlugin(resolver.resolve('./runtime/plugin'));\n    \n    // 添加组件\n    addComponentsDir({\n      path: resolver.resolve('./runtime/components'),\n      prefix: 'MyModule'\n    });\n  }\n});\n",[280],[2804],{"type":25,"tag":45,"props":2805,"children":2806},{"__ignoreMap":7},[2807],{"type":31,"value":2801},{"type":25,"tag":26,"props":2809,"children":2811},{"id":2810},"第七部分迁移准备",[2812],{"type":31,"value":2813},"第七部分：迁移准备",{"type":25,"tag":73,"props":2815,"children":2817},{"id":2816},"_71-兼容性检查清单",[2818],{"type":31,"value":2819},"7.1 兼容性检查清单",{"type":25,"tag":80,"props":2821,"children":2825},{"code":2822,"language":669,"meta":7,"className":2823},"## Nuxt 4 迁移检查清单\n\n### 依赖版本\n- [ ] Node.js >= 20\n- [ ] Vue >= 3.4\n- [ ] TypeScript >= 5.3（推荐）\n\n### 代码检查\n- [ ] 移除已废弃的 API 调用\n- [ ] 更新 composables 导入路径\n- [ ] 检查 useAsyncData 用法\n- [ ] 审查中间件语法\n\n### 目录结构\n- [ ] 决定是否采用新目录结构\n- [ ] 移动文件到 app/ 目录（如果采用）\n- [ ] 更新 nuxt.config.ts 配置\n\n### 模块更新\n- [ ] 更新官方模块到兼容版本\n- [ ] 检查第三方模块兼容性\n- [ ] 更新自定义模块\n\n### 测试\n- [ ] 运行全部测试套件\n- [ ] 验证 SSR/SSG 输出\n- [ ] 检查 hydration 错误\n- [ ] 性能基准测试\n",[2824],"language-markdown",[2826],{"type":25,"tag":45,"props":2827,"children":2828},{"__ignoreMap":7},[2829],{"type":31,"value":2822},{"type":25,"tag":73,"props":2831,"children":2833},{"id":2832},"_72-渐进式升级路径",[2834],{"type":31,"value":2835},"7.2 渐进式升级路径",{"type":25,"tag":80,"props":2837,"children":2840},{"code":2838,"language":278,"meta":7,"className":2839},"// 使用 compatibilityVersion 实现渐进升级\n\n// 阶段 1：启用 Nuxt 4 特性（保持旧目录结构）\nexport default defineNuxtConfig({\n  future: {\n    compatibilityVersion: 4\n  },\n  srcDir: './'  // 保持旧目录结构\n});\n\n// 阶段 2：迁移到新目录结构\n// 1. 创建 app/ 目录\n// 2. 移动文件\n// 3. 更新导入路径\n\n// 阶段 3：完全升级\nexport default defineNuxtConfig({\n  // 移除 future 配置，默认使用 Nuxt 4 行为\n});\n",[280],[2841],{"type":25,"tag":45,"props":2842,"children":2843},{"__ignoreMap":7},[2844],{"type":31,"value":2838},{"type":25,"tag":26,"props":2846,"children":2848},{"id":2847},"结语稳步前进的进化",[2849],{"type":31,"value":2850},"结语：稳步前进的进化",{"type":25,"tag":39,"props":2852,"children":2853},{},[2854],{"type":31,"value":2855},"Nuxt 4 不是一次颠覆性的重写，而是在 Nuxt 3 坚实基础上的持续改进。新的目录结构带来更好的组织性，Nitro 2.0 带来更好的性能，增强的类型系统带来更好的开发体验。",{"type":25,"tag":39,"props":2857,"children":2858},{},[2859],{"type":31,"value":2860},"对于 Nuxt 3 用户来说，升级路径相对平滑。核心概念没有变化，熟悉的 API 依然工作。Nuxt 团队显然吸取了 Nuxt 2 到 Nuxt 3 升级的经验，这次提供了更友好的迁移体验。",{"type":25,"tag":39,"props":2862,"children":2863},{},[2864],{"type":31,"value":2865},"如果你正在考虑是否升级，建议：",{"type":25,"tag":547,"props":2867,"children":2868},{},[2869,2874,2879],{"type":25,"tag":511,"props":2870,"children":2871},{},[2872],{"type":31,"value":2873},"新项目直接使用 Nuxt 4",{"type":25,"tag":511,"props":2875,"children":2876},{},[2877],{"type":31,"value":2878},"现有项目评估迁移成本后决定",{"type":25,"tag":511,"props":2880,"children":2881},{},[2882],{"type":31,"value":2883},"关注官方迁移指南的更新",{"type":25,"tag":781,"props":2885,"children":2886},{},[],{"type":25,"tag":26,"props":2888,"children":2889},{"id":577},[2890],{"type":31,"value":577},{"type":25,"tag":547,"props":2892,"children":2893},{},[2894,2904,2914,2924],{"type":25,"tag":511,"props":2895,"children":2896},{},[2897],{"type":25,"tag":587,"props":2898,"children":2901},{"href":2899,"rel":2900},"https://nuxt.com/blog/v4",[591],[2902],{"type":31,"value":2903},"Nuxt 4 官方公告",{"type":25,"tag":511,"props":2905,"children":2906},{},[2907],{"type":25,"tag":587,"props":2908,"children":2911},{"href":2909,"rel":2910},"https://nuxt.com/docs/migration/upgrade",[591],[2912],{"type":31,"value":2913},"Nuxt 4 迁移指南",{"type":25,"tag":511,"props":2915,"children":2916},{},[2917],{"type":25,"tag":587,"props":2918,"children":2921},{"href":2919,"rel":2920},"https://nitro.unjs.io/changelog",[591],[2922],{"type":31,"value":2923},"Nitro 2.0 更新日志",{"type":25,"tag":511,"props":2925,"children":2926},{},[2927],{"type":25,"tag":587,"props":2928,"children":2931},{"href":2929,"rel":2930},"https://github.com/nuxt/nuxt/issues",[591],[2932],{"type":31,"value":2933},"Nuxt 路线图",{"title":7,"searchDepth":626,"depth":626,"links":2935},[2936,2937,2938,2943,2948,2953,2958,2963,2967,2971,2972],{"id":2458,"depth":629,"text":2461},{"id":2464,"depth":629,"text":2467},{"id":2480,"depth":629,"text":2483,"children":2939},[2940,2941,2942],{"id":2486,"depth":626,"text":2489},{"id":2521,"depth":626,"text":2524},{"id":2541,"depth":626,"text":2544},{"id":2556,"depth":629,"text":2559,"children":2944},[2945,2946,2947],{"id":2562,"depth":626,"text":2565},{"id":2582,"depth":626,"text":2585},{"id":2597,"depth":626,"text":2600},{"id":2612,"depth":629,"text":2615,"children":2949},[2950,2951,2952],{"id":2618,"depth":626,"text":2621},{"id":2633,"depth":626,"text":2636},{"id":2648,"depth":626,"text":2651},{"id":2663,"depth":629,"text":2666,"children":2954},[2955,2956,2957],{"id":2669,"depth":626,"text":2672},{"id":2684,"depth":626,"text":2687},{"id":2699,"depth":626,"text":2702},{"id":2723,"depth":629,"text":2726,"children":2959},[2960,2961,2962],{"id":2729,"depth":626,"text":2732},{"id":2744,"depth":626,"text":2747},{"id":2759,"depth":626,"text":2762},{"id":2774,"depth":629,"text":2777,"children":2964},[2965,2966],{"id":2780,"depth":626,"text":2783},{"id":2795,"depth":626,"text":2798},{"id":2810,"depth":629,"text":2813,"children":2968},[2969,2970],{"id":2816,"depth":626,"text":2819},{"id":2832,"depth":626,"text":2835},{"id":2847,"depth":629,"text":2850},{"id":577,"depth":629,"text":577},"content:topics:nuxt:nuxt4-major-updates-overview.md","topics/nuxt/nuxt4-major-updates-overview.md","topics/nuxt/nuxt4-major-updates-overview",{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"topic":5,"author":11,"tags":2977,"image":18,"featured":19,"readingTime":20,"body":2978,"_type":669,"_id":670,"_source":671,"_file":672,"_stem":673,"_extension":674},[13,14,15,16,17],{"type":22,"children":2979,"toc":3464},[2980,2984,2988,3010,3014,3018,3025,3029,3036,3040,3044,3052,3056,3064,3068,3076,3080,3088,3092,3096,3104,3108,3116,3120,3128,3132,3136,3144,3148,3156,3160,3164,3172,3176,3184,3188,3196,3200,3204,3212,3216,3224,3228,3236,3240,3248,3252,3256,3264,3268,3276,3280,3288,3292,3324,3344,3352,3360,3364,3368,3395,3402,3425,3429],{"type":25,"tag":26,"props":2981,"children":2982},{"id":28},[2983],{"type":31,"value":32},{"type":25,"tag":26,"props":2985,"children":2986},{"id":35},[2987],{"type":31,"value":35},{"type":25,"tag":39,"props":2989,"children":2990},{},[2991,2992,2997,2998,3003,3004,3009],{"type":31,"value":43},{"type":25,"tag":45,"props":2993,"children":2995},{"className":2994},[],[2996],{"type":31,"value":14},{"type":31,"value":51},{"type":25,"tag":45,"props":2999,"children":3001},{"className":3000},[],[3002],{"type":31,"value":15},{"type":31,"value":58},{"type":25,"tag":45,"props":3005,"children":3007},{"className":3006},[],[3008],{"type":31,"value":64},{"type":31,"value":66},{"type":25,"tag":26,"props":3011,"children":3012},{"id":69},[3013],{"type":31,"value":69},{"type":25,"tag":73,"props":3015,"children":3016},{"id":75},[3017],{"type":31,"value":78},{"type":25,"tag":80,"props":3019,"children":3020},{"code":82},[3021],{"type":25,"tag":45,"props":3022,"children":3023},{"__ignoreMap":7},[3024],{"type":31,"value":82},{"type":25,"tag":73,"props":3026,"children":3027},{"id":90},[3028],{"type":31,"value":90},{"type":25,"tag":80,"props":3030,"children":3031},{"code":95},[3032],{"type":25,"tag":45,"props":3033,"children":3034},{"__ignoreMap":7},[3035],{"type":31,"value":95},{"type":25,"tag":26,"props":3037,"children":3038},{"id":103},[3039],{"type":31,"value":106},{"type":25,"tag":73,"props":3041,"children":3042},{"id":109},[3043],{"type":31,"value":109},{"type":25,"tag":80,"props":3045,"children":3047},{"code":114,"language":115,"meta":7,"className":3046},[117],[3048],{"type":25,"tag":45,"props":3049,"children":3050},{"__ignoreMap":7},[3051],{"type":31,"value":114},{"type":25,"tag":73,"props":3053,"children":3054},{"id":125},[3055],{"type":31,"value":125},{"type":25,"tag":80,"props":3057,"children":3059},{"code":130,"language":115,"meta":7,"className":3058},[117],[3060],{"type":25,"tag":45,"props":3061,"children":3062},{"__ignoreMap":7},[3063],{"type":31,"value":130},{"type":25,"tag":73,"props":3065,"children":3066},{"id":139},[3067],{"type":31,"value":139},{"type":25,"tag":80,"props":3069,"children":3071},{"code":144,"language":115,"meta":7,"className":3070},[117],[3072],{"type":25,"tag":45,"props":3073,"children":3074},{"__ignoreMap":7},[3075],{"type":31,"value":144},{"type":25,"tag":73,"props":3077,"children":3078},{"id":153},[3079],{"type":31,"value":153},{"type":25,"tag":80,"props":3081,"children":3083},{"code":158,"language":115,"meta":7,"className":3082},[117],[3084],{"type":25,"tag":45,"props":3085,"children":3086},{"__ignoreMap":7},[3087],{"type":31,"value":158},{"type":25,"tag":26,"props":3089,"children":3090},{"id":167},[3091],{"type":31,"value":170},{"type":25,"tag":73,"props":3093,"children":3094},{"id":173},[3095],{"type":31,"value":109},{"type":25,"tag":80,"props":3097,"children":3099},{"code":178,"language":115,"meta":7,"className":3098},[117],[3100],{"type":25,"tag":45,"props":3101,"children":3102},{"__ignoreMap":7},[3103],{"type":31,"value":178},{"type":25,"tag":73,"props":3105,"children":3106},{"id":187},[3107],{"type":31,"value":187},{"type":25,"tag":80,"props":3109,"children":3111},{"code":192,"language":115,"meta":7,"className":3110},[117],[3112],{"type":25,"tag":45,"props":3113,"children":3114},{"__ignoreMap":7},[3115],{"type":31,"value":192},{"type":25,"tag":73,"props":3117,"children":3118},{"id":201},[3119],{"type":31,"value":201},{"type":25,"tag":80,"props":3121,"children":3123},{"code":206,"language":115,"meta":7,"className":3122},[117],[3124],{"type":25,"tag":45,"props":3125,"children":3126},{"__ignoreMap":7},[3127],{"type":31,"value":206},{"type":25,"tag":26,"props":3129,"children":3130},{"id":215},[3131],{"type":31,"value":218},{"type":25,"tag":73,"props":3133,"children":3134},{"id":221},[3135],{"type":31,"value":221},{"type":25,"tag":80,"props":3137,"children":3139},{"code":226,"language":227,"meta":7,"className":3138},[229],[3140],{"type":25,"tag":45,"props":3141,"children":3142},{"__ignoreMap":7},[3143],{"type":31,"value":226},{"type":25,"tag":73,"props":3145,"children":3146},{"id":237},[3147],{"type":31,"value":237},{"type":25,"tag":80,"props":3149,"children":3151},{"code":242,"language":115,"meta":7,"className":3150},[117],[3152],{"type":25,"tag":45,"props":3153,"children":3154},{"__ignoreMap":7},[3155],{"type":31,"value":242},{"type":25,"tag":26,"props":3157,"children":3158},{"id":251},[3159],{"type":31,"value":254},{"type":25,"tag":73,"props":3161,"children":3162},{"id":257},[3163],{"type":31,"value":257},{"type":25,"tag":80,"props":3165,"children":3167},{"code":262,"language":115,"meta":7,"className":3166},[117],[3168],{"type":25,"tag":45,"props":3169,"children":3170},{"__ignoreMap":7},[3171],{"type":31,"value":262},{"type":25,"tag":73,"props":3173,"children":3174},{"id":271},[3175],{"type":31,"value":274},{"type":25,"tag":80,"props":3177,"children":3179},{"code":277,"language":278,"meta":7,"className":3178},[280],[3180],{"type":25,"tag":45,"props":3181,"children":3182},{"__ignoreMap":7},[3183],{"type":31,"value":277},{"type":25,"tag":73,"props":3185,"children":3186},{"id":288},[3187],{"type":31,"value":288},{"type":25,"tag":80,"props":3189,"children":3191},{"code":293,"language":278,"meta":7,"className":3190},[280],[3192],{"type":25,"tag":45,"props":3193,"children":3194},{"__ignoreMap":7},[3195],{"type":31,"value":293},{"type":25,"tag":26,"props":3197,"children":3198},{"id":302},[3199],{"type":31,"value":302},{"type":25,"tag":73,"props":3201,"children":3202},{"id":307},[3203],{"type":31,"value":307},{"type":25,"tag":80,"props":3205,"children":3207},{"code":312,"language":115,"meta":7,"className":3206},[117],[3208],{"type":25,"tag":45,"props":3209,"children":3210},{"__ignoreMap":7},[3211],{"type":31,"value":312},{"type":25,"tag":73,"props":3213,"children":3214},{"id":321},[3215],{"type":31,"value":321},{"type":25,"tag":80,"props":3217,"children":3219},{"code":326,"language":115,"meta":7,"className":3218},[117],[3220],{"type":25,"tag":45,"props":3221,"children":3222},{"__ignoreMap":7},[3223],{"type":31,"value":326},{"type":25,"tag":73,"props":3225,"children":3226},{"id":335},[3227],{"type":31,"value":335},{"type":25,"tag":80,"props":3229,"children":3231},{"code":340,"language":115,"meta":7,"className":3230},[117],[3232],{"type":25,"tag":45,"props":3233,"children":3234},{"__ignoreMap":7},[3235],{"type":31,"value":340},{"type":25,"tag":73,"props":3237,"children":3238},{"id":349},[3239],{"type":31,"value":349},{"type":25,"tag":80,"props":3241,"children":3243},{"code":354,"language":115,"meta":7,"className":3242},[117],[3244],{"type":25,"tag":45,"props":3245,"children":3246},{"__ignoreMap":7},[3247],{"type":31,"value":354},{"type":25,"tag":26,"props":3249,"children":3250},{"id":363},[3251],{"type":31,"value":363},{"type":25,"tag":73,"props":3253,"children":3254},{"id":368},[3255],{"type":31,"value":371},{"type":25,"tag":80,"props":3257,"children":3259},{"code":374,"language":115,"meta":7,"className":3258},[117],[3260],{"type":25,"tag":45,"props":3261,"children":3262},{"__ignoreMap":7},[3263],{"type":31,"value":374},{"type":25,"tag":73,"props":3265,"children":3266},{"id":383},[3267],{"type":31,"value":383},{"type":25,"tag":80,"props":3269,"children":3271},{"code":388,"language":115,"meta":7,"className":3270},[117],[3272],{"type":25,"tag":45,"props":3273,"children":3274},{"__ignoreMap":7},[3275],{"type":31,"value":388},{"type":25,"tag":73,"props":3277,"children":3278},{"id":397},[3279],{"type":31,"value":397},{"type":25,"tag":80,"props":3281,"children":3283},{"code":402,"language":115,"meta":7,"className":3282},[117],[3284],{"type":25,"tag":45,"props":3285,"children":3286},{"__ignoreMap":7},[3287],{"type":31,"value":402},{"type":25,"tag":26,"props":3289,"children":3290},{"id":411},[3291],{"type":31,"value":411},{"type":25,"tag":39,"props":3293,"children":3294},{},[3295,3299,3300,3305,3306,3311,3312,3317,3318,3323],{"type":25,"tag":418,"props":3296,"children":3297},{},[3298],{"type":31,"value":422},{"type":31,"value":424},{"type":25,"tag":45,"props":3301,"children":3303},{"className":3302},[],[3304],{"type":31,"value":14},{"type":31,"value":431},{"type":25,"tag":45,"props":3307,"children":3309},{"className":3308},[],[3310],{"type":31,"value":15},{"type":31,"value":438},{"type":25,"tag":45,"props":3313,"children":3315},{"className":3314},[],[3316],{"type":31,"value":64},{"type":31,"value":445},{"type":25,"tag":45,"props":3319,"children":3321},{"className":3320},[],[3322],{"type":31,"value":15},{"type":31,"value":452},{"type":25,"tag":39,"props":3325,"children":3326},{},[3327,3331,3332,3337,3338,3343],{"type":25,"tag":418,"props":3328,"children":3329},{},[3330],{"type":31,"value":460},{"type":31,"value":424},{"type":25,"tag":45,"props":3333,"children":3335},{"className":3334},[],[3336],{"type":31,"value":14},{"type":31,"value":468},{"type":25,"tag":45,"props":3339,"children":3341},{"className":3340},[],[3342],{"type":31,"value":64},{"type":31,"value":475},{"type":25,"tag":39,"props":3345,"children":3346},{},[3347,3351],{"type":25,"tag":418,"props":3348,"children":3349},{},[3350],{"type":31,"value":483},{"type":31,"value":485},{"type":25,"tag":39,"props":3353,"children":3354},{},[3355,3359],{"type":25,"tag":418,"props":3356,"children":3357},{},[3358],{"type":31,"value":493},{"type":31,"value":495},{"type":25,"tag":26,"props":3361,"children":3362},{"id":498},[3363],{"type":31,"value":498},{"type":25,"tag":39,"props":3365,"children":3366},{},[3367],{"type":31,"value":505},{"type":25,"tag":507,"props":3369,"children":3370},{},[3371,3379,3387],{"type":25,"tag":511,"props":3372,"children":3373},{},[3374,3378],{"type":25,"tag":418,"props":3375,"children":3376},{},[3377],{"type":31,"value":14},{"type":31,"value":519},{"type":25,"tag":511,"props":3380,"children":3381},{},[3382,3386],{"type":25,"tag":418,"props":3383,"children":3384},{},[3385],{"type":31,"value":15},{"type":31,"value":528},{"type":25,"tag":511,"props":3388,"children":3389},{},[3390,3394],{"type":25,"tag":418,"props":3391,"children":3392},{},[3393],{"type":31,"value":64},{"type":31,"value":537},{"type":25,"tag":39,"props":3396,"children":3397},{},[3398],{"type":25,"tag":418,"props":3399,"children":3400},{},[3401],{"type":31,"value":545},{"type":25,"tag":547,"props":3403,"children":3404},{},[3405,3409,3413,3417,3421],{"type":25,"tag":511,"props":3406,"children":3407},{},[3408],{"type":31,"value":554},{"type":25,"tag":511,"props":3410,"children":3411},{},[3412],{"type":31,"value":559},{"type":25,"tag":511,"props":3414,"children":3415},{},[3416],{"type":31,"value":564},{"type":25,"tag":511,"props":3418,"children":3419},{},[3420],{"type":31,"value":569},{"type":25,"tag":511,"props":3422,"children":3423},{},[3424],{"type":31,"value":574},{"type":25,"tag":26,"props":3426,"children":3427},{"id":577},[3428],{"type":31,"value":577},{"type":25,"tag":547,"props":3430,"children":3431},{},[3432,3440,3448,3456],{"type":25,"tag":511,"props":3433,"children":3434},{},[3435],{"type":25,"tag":587,"props":3436,"children":3438},{"href":589,"rel":3437},[591],[3439],{"type":31,"value":594},{"type":25,"tag":511,"props":3441,"children":3442},{},[3443],{"type":25,"tag":587,"props":3444,"children":3446},{"href":600,"rel":3445},[591],[3447],{"type":31,"value":604},{"type":25,"tag":511,"props":3449,"children":3450},{},[3451],{"type":25,"tag":587,"props":3452,"children":3454},{"href":610,"rel":3453},[591],[3455],{"type":31,"value":614},{"type":25,"tag":511,"props":3457,"children":3458},{},[3459],{"type":25,"tag":587,"props":3460,"children":3462},{"href":620,"rel":3461},[591],[3463],{"type":31,"value":624},{"title":7,"searchDepth":626,"depth":626,"links":3465},[3466,3467,3468,3472,3478,3483,3487,3492,3498,3503,3504,3505],{"id":28,"depth":629,"text":32},{"id":35,"depth":629,"text":35},{"id":69,"depth":629,"text":69,"children":3469},[3470,3471],{"id":75,"depth":626,"text":78},{"id":90,"depth":626,"text":90},{"id":103,"depth":629,"text":106,"children":3473},[3474,3475,3476,3477],{"id":109,"depth":626,"text":109},{"id":125,"depth":626,"text":125},{"id":139,"depth":626,"text":139},{"id":153,"depth":626,"text":153},{"id":167,"depth":629,"text":170,"children":3479},[3480,3481,3482],{"id":173,"depth":626,"text":109},{"id":187,"depth":626,"text":187},{"id":201,"depth":626,"text":201},{"id":215,"depth":629,"text":218,"children":3484},[3485,3486],{"id":221,"depth":626,"text":221},{"id":237,"depth":626,"text":237},{"id":251,"depth":629,"text":254,"children":3488},[3489,3490,3491],{"id":257,"depth":626,"text":257},{"id":271,"depth":626,"text":274},{"id":288,"depth":626,"text":288},{"id":302,"depth":629,"text":302,"children":3493},[3494,3495,3496,3497],{"id":307,"depth":626,"text":307},{"id":321,"depth":626,"text":321},{"id":335,"depth":626,"text":335},{"id":349,"depth":626,"text":349},{"id":363,"depth":629,"text":363,"children":3499},[3500,3501,3502],{"id":368,"depth":626,"text":371},{"id":383,"depth":626,"text":383},{"id":397,"depth":626,"text":397},{"id":411,"depth":629,"text":411},{"id":498,"depth":629,"text":498},{"id":577,"depth":629,"text":577},1782088259134]