---
title: "v1 到 v2"
description: "从 Nuxt Scripts v1.x 升级到 v2.0 的迁移指南。"
canonical_url: "https://nuxt-scripts.zhcndoc.com/docs/migration-guide/v1-to-v2"
last_updated: "2026-08-11T09:33:15.163Z"
---

Nuxt Scripts 2 将脚本所有权和 SDK 就绪状态交由 Unhead 3.3.1 中引入的生命周期 API 管理。当组件使用者卸载时，这些 API 会移除组件回调和触发器监听器，同时不会拆除仍被其他组件使用的脚本。

## 要求

<table>
<thead>
  <tr>
    <th>
      依赖
    </th>
    
    <th>
      要求版本
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <a href="https://nodejs.org" rel="nofollow">
        Node.js
      </a>
    </td>
    
    <td>
      <code>
        >=24
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      Nuxt
    </td>
    
    <td>
      <code>
        >=4.5.1
      </code>
      
      ，包括 Nuxt 5 和 Nitro 3
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        @unhead/vue
      </code>
    </td>
    
    <td>
      <code>
        >=3.3.1 <4
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        unhead
      </code>
    </td>
    
    <td>
      <code>
        >=3.3.1 <4
      </code>
    </td>
  </tr>
</tbody>
</table>

在安装 v2 之前升级 Nuxt 并刷新其锁定的依赖：

```bash
npx nuxi@latest upgrade --force
```

从项目根目录运行专用迁移 CLI。如果项目包含动态 Nuxt 配置，
请先预览其变更：

```bash
npx @nuxt/scripts-cli migrate v2 --dry-run
npx @nuxt/scripts-cli migrate v2
```

该 CLI 会处理静态注册表配置和机械式 API 重命名。
它会列出需要手动后续处理的动态配置和已移除组件。

现在，如果任一 Unhead 包缺失或版本超出支持范围，模块会显示可执行的错误信息并停止设置。

## 注册表配置

注册表条目现在接受扁平对象、`'mock'` 或 `false`。Nuxt Scripts 2
移除了已弃用的 `true`、`'proxy-only'`、元组、嵌套的
`scriptOptions` 以及 `reverseProxyIntercept` 形式。

```diff
scripts: {
   registry: {
-    googleAnalytics: true,
-    plausibleAnalytics: [{ scriptId: 'YOUR_SCRIPT_ID' }, { proxy: false }],
-    calendly: { scriptOptions: { bundle: false } },
-    posthog: { reverseProxyIntercept: false },
+    googleAnalytics: { trigger: 'onNuxtReady' },
+    plausibleAnalytics: { scriptId: 'YOUR_SCRIPT_ID', proxy: false },
+    calendly: { bundle: false },
+    posthog: { proxy: false },
   },
 }
```

Nuxt Scripts 2 还移除了已弃用的顶层 `globals` 数组。请使用
键控对象，以便每个脚本都有一个稳定的名称。

## Google 地图

Nuxt Scripts 2 移除了以下 v1 兼容别名和组件：

<table>
<thead>
  <tr>
    <th>
      已移除
    </th>
    
    <th>
      替代方案
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code className="language-html shiki shiki-themes github-light github-light material-theme-palenight" language="html" style="">
        <span class="sx-uw">
          <
        </span>
        
        <span class="sFfpx">
          ScriptGoogleMaps
        </span>
        
        <span class="sx-uw">
          >
        </span>
      </code>
      
       上的 <code>
        center
      </code>
      
       和 <code>
        zoom
      </code>
      
       props
    </td>
    
    <td>
      <code>
        mapOptions.center
      </code>
      
       和 <code>
        mapOptions.zoom
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        googleMaps
      </code>
      
       模板 ref 键
    </td>
    
    <td>
      <code>
        mapsApi
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        overlay
      </code>
      
       模板 ref 键
    </td>
    
    <td>
      <code>
        overlayView
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code className="language-html shiki shiki-themes github-light github-light material-theme-palenight" language="html" style="">
        <span class="sx-uw">
          <
        </span>
        
        <span class="sFfpx">
          ScriptGoogleMapsAdvancedMarkerElement
        </span>
        
        <span class="sx-uw">
          >
        </span>
      </code>
    </td>
    
    <td>
      <code className="language-html shiki shiki-themes github-light github-light material-theme-palenight" language="html" style="">
        <span class="sx-uw">
          <
        </span>
        
        <span class="sFfpx">
          ScriptGoogleMapsMarker
        </span>
        
        <span class="sx-uw">
          >
        </span>
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code className="language-html shiki shiki-themes github-light github-light material-theme-palenight" language="html" style="">
        <span class="sx-uw">
          <
        </span>
        
        <span class="sFfpx">
          ScriptGoogleMapsPinElement
        </span>
        
        <span class="sx-uw">
          >
        </span>
      </code>
    </td>
    
    <td>
      marker 的 <code>
        #content
      </code>
      
       插槽
    </td>
  </tr>
  
  <tr>
    <td>
      <code className="language-html shiki shiki-themes github-light github-light material-theme-palenight" language="html" style="">
        <span class="sx-uw">
          <
        </span>
        
        <span class="sFfpx">
          ScriptGoogleMapsHeatmapLayer
        </span>
        
        <span class="sx-uw">
          >
        </span>
      </code>
    </td>
    
    <td>
      使用 deck.gl 等受维护的热力图库
    </td>
  </tr>
</tbody>
</table>

Google 已从 Maps JavaScript API v3.65 中移除 `HeatmapLayer`，因此 Nuxt Scripts
不再提供依赖它的组件。

Nuxt Scripts 2 移除了旧版 `googleStaticMapsProxy` 选项和需要计费的 Google 地图服务器代理。静态地图会使用公开的浏览器密钥直接从 Google 加载。`resolveQueryToLatLng()` 使用客户端 Places 服务。为该密钥应用网站和 API 限制，然后配置配额限制。

## 注册表 API

Nuxt Scripts 2 移除了以下已弃用的注册表 API 形式：

<table>
<thead>
  <tr>
    <th>
      已移除
    </th>
    
    <th>
      替代方案
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code className="language-ts shiki shiki-themes github-light github-light material-theme-palenight" language="ts" style="">
        <span class="sqjlB">
          proxy
        </span>
        
        <span class="sx-uw">
          .
        </span>
        
        <span class="sqjlB">
          rybbit
        </span>
        
        <span class="sx-uw">
          .
        </span>
        
        <span class="s0YkB">
          pageview
        </span>
        
        <span class="sqjlB">
          ()
        </span>
      </code>
    </td>
    
    <td>
      <code className="language-ts shiki shiki-themes github-light github-light material-theme-palenight" language="ts" style="">
        <span class="sqjlB">
          proxy
        </span>
        
        <span class="sx-uw">
          .
        </span>
        
        <span class="s0YkB">
          pageview
        </span>
        
        <span class="sqjlB">
          ()
        </span>
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code className="language-ts shiki shiki-themes github-light github-light material-theme-palenight" language="ts" style="">
        <span class="sqjlB">
          proxy
        </span>
        
        <span class="sx-uw">
          .
        </span>
        
        <span class="s0YkB">
          ttq
        </span>
        
        <span class="sqjlB">
          (
        </span>
        
        <span class="sbw7o">
          '
        </span>
        
        <span class="sJnJ8">
          page
        </span>
        
        <span class="sbw7o">
          '
        </span>
        
        <span class="sqjlB">
          )
        </span>
      </code>
    </td>
    
    <td>
      <code className="language-ts shiki shiki-themes github-light github-light material-theme-palenight" language="ts" style="">
        <span class="sqjlB">
          proxy
        </span>
        
        <span class="sx-uw">
          .
        </span>
        
        <span class="sqjlB">
          ttq
        </span>
        
        <span class="sx-uw">
          .
        </span>
        
        <span class="s0YkB">
          page
        </span>
        
        <span class="sqjlB">
          ()
        </span>
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code className="language-ts shiki shiki-themes github-light github-light material-theme-palenight" language="ts" style="">
        <span class="sqjlB">
          proxy
        </span>
        
        <span class="sx-uw">
          .
        </span>
        
        <span class="s0YkB">
          ttq
        </span>
        
        <span class="sqjlB">
          (
        </span>
        
        <span class="sbw7o">
          '
        </span>
        
        <span class="sJnJ8">
          track
        </span>
        
        <span class="sbw7o">
          '
        </span>
        
        <span class="sx-uw">
          ,
        </span>
        
        <span class="sc1V3">
          ...
        </span>
        
        <span class="sqjlB">
          )
        </span>
      </code>
    </td>
    
    <td>
      <code className="language-ts shiki shiki-themes github-light github-light material-theme-palenight" language="ts" style="">
        <span class="sqjlB">
          proxy
        </span>
        
        <span class="sx-uw">
          .
        </span>
        
        <span class="sqjlB">
          ttq
        </span>
        
        <span class="sx-uw">
          .
        </span>
        
        <span class="s0YkB">
          track
        </span>
        
        <span class="sqjlB">
          (
        </span>
        
        <span class="sc1V3">
          ...
        </span>
        
        <span class="sqjlB">
          )
        </span>
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      Matomo <code>
        trackPageView
      </code>
      
       选项
    </td>
    
    <td>
      <code>
        watch
      </code>
      
      ，默认为 <code>
        true
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      Plausible <code>
        domain
      </code>
      
       和 <code>
        extension
      </code>
      
       选项
    </td>
    
    <td>
      <code>
        scriptId
      </code>
      
       和当前的初始化选项
    </td>
  </tr>
</tbody>
</table>

## 消费者作用域

每次 `useScript()` 调用现在都会返回一个 Unhead 消费者作用域。
组件卸载时会自动释放由该调用拥有的回调和触发器监听器。

- `dispose()` 仅释放当前消费者。
- 当你释放该消费者，或任何调用方移除共享脚本时，`signal` 会中止。
- `script` 指向共享脚本实例。
- `remove()` 仍会为所有消费者移除共享脚本。

如果应用代码使用 `remove()` 作为组件清理操作，请将其改为
`dispose()`。在 Vue 组件中，通常不再需要手动清理。

## 自定义就绪回调

`use` 选项仍受支持。基于回调的 SDK 应迁移到
`resolve({ waitFor })`，它会自动移除监听器，并在脚本生命周期结束时拒绝待处理的就绪请求。

```diff
const script = useScript('https://example.com/sdk.js', {
-  use: () => readyPromise.then(() => window.example),
+  resolve: ({ waitFor }) => waitFor((resolve) => {
+    window.onExampleReady = () => resolve(window.example)
+    return () => delete window.onExampleReady
+  }),
 })
```

现已将内置的 Google Maps、YouTube Player、Crisp 和 Usercentrics 集成改为使用此 API。`load()` 仅会在每个供应商的具体 SDK API 就绪后才完成解析。

## 脚本触发器

Nuxt 的空闲超时、交互和服务工作线程辅助函数现在会返回 Unhead 触发函数。现有的 `scriptOptions.trigger` 用法保持不变。自定义触发函数可以返回一个清理回调；当使用方作用域被销毁时，Unhead 会调用该回调。
