---
title: "v0 到 v1"
description: "从 Nuxt Scripts v0.x 升级到 v1.0 的迁移指南。"
canonical_url: "https://nuxt-scripts.zhcndoc.com/docs/migration-guide/v0-to-v1"
last_updated: "2026-09-23T10:33:11.057Z"
---

使用本指南将 Nuxt Scripts v0 项目升级到 v1。[v1 发布说明](/docs/releases/v1)介绍了新增功能。

::callout{icon="i-heroicons-information-circle" color="blue"}
大多数被替换的 API 仍可继续使用，但会显示弃用警告。表格标出了需要更新代码的变更。
::

## 总结

| 变更                                                                             | 状态             | 处理方式                                                            |
| ------------------------------------------------------------------------------ | -------------- | --------------------------------------------------------------- |
| Registry 条目在没有 `trigger` 的情况下自动加载                                              | 构建警告           | 添加 `trigger: 'onNuxtReady'` 或 `trigger: false`                  |
| `[input, options]` 元组形式                                                        | 仍然有效           | 可选：切换为扁平配置                                                      |
| `true` 简写形式                                                                    | 已弃用            | 使用 `{ trigger: 'onNuxtReady' }`                                 |
| PayPal SDK v5 API                                                              | 已移除            | 迁移到 v6（见下文）                                                     |
| `ScriptYouTubePlayer` 的 `width`/`height`                                       | 仍然有效           | 可选：使用 `ratio` 属性                                                |
| `ScriptYouTubePlayer` 占位符 `object-fit: contain` 默认值                            | 已更改为 `cover`   | 设置 `placeholder-object-fit="contain"` 以恢复原设置                    |
| GTM `onBeforeGtmStart` 的触发时机                                                   | 现在会对缓存的脚本触发    | 使用 `if (initialized) return` 进行保护                               |
| `ScriptGoogleMaps` 的 `markers`/`centerMarker` 属性                               | 已移除            | 使用子元素 `<ScriptGoogleMapsMarker>`{lang="html"}                   |
| `ScriptGoogleMaps` 的 `placeholderOptions`/`placeholderAttrs`/`aboveTheFold` 属性 | 已移除            | 在 `#placeholder` 中使用 `<ScriptGoogleMapsStaticMap>`{lang="html"} |
| `ScriptGoogleMaps` 的 `:center`/`:zoom` 属性                                      | 已弃用            | 使用 `:map-options="{ center, zoom }"`                            |
| `ScriptGoogleMaps` 的 `googleMaps` ref 键                                        | 已弃用            | 使用 `mapsApi`                                                    |
| `ScriptGoogleMapsAdvancedMarkerElement`                                        | 已弃用            | 使用 `ScriptGoogleMapsMarker`                                     |
| `ScriptGoogleMapsPinElement`                                                   | 已移除；仍保留插槽透传兼容层 | 在 `ScriptGoogleMapsMarker` 上使用 `#content` 插槽                    |
| 类型模板                                                                           | 已重新组织          | 运行 `nuxi prepare`                                               |

## 注册表配置

### 脚本在没有 `trigger` 的情况下不再自动加载

在 v0 中，任何已配置的注册表项都会通过 `defaultScriptOptions.trigger: 'onNuxtReady'`{lang="ts"} 全局自动加载。在 v1 中，存在配置只会注册基础设施（类型、打包、代理路由），但除非设置了 `trigger`，否则**不会**注入 `<script>`{lang="html"} 标签。当你提供了配置值但没有提供 `trigger` 时，会出现构建警告。参见 [PR #661](https://github.com/nuxt/scripts/pull/661)。

```diff [nuxt.config.ts]
scripts: {
   registry: {
-    googleAnalytics: { id: 'G-XXXXXX' },
+    googleAnalytics: { id: 'G-XXXXXX', trigger: 'onNuxtReady' },
   }
 }
```

如果你是从 composable（`useScriptGoogleAnalytics()`{lang="ts"} 等）按需加载脚本，而不是全局加载，请显式设置 `trigger: false`{lang="ts"}。这样可以消除构建警告，并在不注入 `<script>`{lang="html"} 标签的情况下保留代理路由、类型和打包配置。

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  scripts: {
    registry: {
      googleAnalytics: { id: 'G-XXXXXX', trigger: false }, // 由 composable 驱动
    }
  }
})
```

### 旧式简写（仍可使用）

`[input, options]` 元组形式、`true` 简写以及 `'mock'` 字符串形式都仍然可用。`true` 会发出弃用警告。

```diff [nuxt.config.ts]
scripts: {
   registry: {
-    googleAnalytics: true,
+    googleAnalytics: { trigger: 'onNuxtReady' },
-    plausibleAnalytics: [{ domain: 'mysite.com' }, { trigger: 'onNuxtReady' }],
+    plausibleAnalytics: { domain: 'mysite.com', trigger: 'onNuxtReady' },
     cloudflareWebAnalytics: 'mock', // 未更改
   }
 }
```

## 重大变更

### PayPal SDK v6 ([#628](https://github.com/nuxt/scripts/pull/628))

PayPal v6 使用基于实例的初始化（`createInstance()`{lang="ts"}）、渲染前的资格检查以及基于会话的支付流程。请参阅 [PayPal 文档](/scripts/paypal) 了解新的组件 API。

- SDK URL 现在使用 v6 端点（`/web-sdk/v6/core`）
- `PayPalOptions` 精简为 `clientId`、`clientToken` 和 `sandbox`；请提供 `clientId` 或 `clientToken`（v6 在 `createInstance()`{lang="ts"} 时配置，而不是通过 URL 查询参数配置）
- 开发环境中的沙盒模式默认为 `true`
- 已移除 `ScriptPayPalMarks`；没有对应的 v6 API，请改用 `sdkInstance.findEligibleMethods()`{lang="ts"}
- `PayPalNamespace` 类型替换为 `PayPalV6Namespace`

`<ScriptPayPalButtons>`{lang="html"} 不再直接渲染按钮。现在它通过 `#default` 作用域插槽暴露 v6 SDK 实例：

```diff
-<ScriptPayPalButtons
-  :client-id="clientId"
-  @paypal-payment-success="onSuccess"
-/>
+<ScriptPayPalButtons :client-id="clientId" :components="['paypal-payments']">
+  <template #default="{ sdkInstance }">
+    <button @click="pay(sdkInstance)">使用 PayPal 支付</button>
+  </template>
+</ScriptPayPalButtons>
```

支付流程改为使用会话而不是按钮回调：

```ts
const eligibility = await sdkInstance.findEligibleMethods()
if (eligibility.isEligible('paypal')) {
  const session = sdkInstance.createPayPalOneTimePaymentSession({
    onApprove: async (data) => { /* 捕获订单 */ },
  })
  await session.start({ presentationMode: 'auto' }, createOrderPromise)
}
```

```diff
-import type { PayPalNamespace } from '@paypal/paypal-js'
+import type { PayPalV6Namespace, SdkInstance } from '@paypal/paypal-js/sdk-v6'
```

### YouTube 播放器 ([#563](https://github.com/nuxt/scripts/pull/563), [#586](https://github.com/nuxt/scripts/pull/586))

#### 宽高比

使用 `ratio` 属性，而不是通过 `width`/`height` 推导宽高比。`width` 和 `height` 属性仍会用于 iframe 尺寸，但不再驱动外层容器的宽高比。

```diff
<ScriptYouTubePlayer
   video-id="..."
-  :width="1280"
-  :height="720"
+  ratio="16/9"
 />
```

默认为 `16/9`。

#### 占位图片

默认的 `object-fit` 已从 `contain` 改为 `cover`。要恢复 v0 行为：

```vue
<ScriptYouTubePlayer video-id="..." placeholder-object-fit="contain" />
```

#### 多个播放器

播放器实例不再共享状态。请移除页面上用于多个播放器的任何 v0 变通方案。

### Google Tag Manager ([#584](https://github.com/nuxt/scripts/pull/584))

#### `onBeforeGtmStart` 回调

v1 也会为缓存或预初始化的脚本调用此钩子。请防止重复初始化：

```diff
+let initialized = false
 useScriptGoogleTagManager({
   onBeforeGtmStart: (gtag) => {
+    if (initialized) return
+    initialized = true
     // 你的初始化代码
   }
 })
```

### Google Maps ([实现提交](https://github.com/nuxt/scripts/commit/d381c9a2))

v1 统一了 Google Maps 标记组件，移除了旧的 `google.maps.Marker`{lang="ts"} API，并将静态占位图提取为独立组件。

#### `ScriptGoogleMapsAdvancedMarkerElement` → `ScriptGoogleMapsMarker`（已弃用）

旧组件仍作为轻量兼容层保留，并会发出开发环境警告。

```diff
-<ScriptGoogleMapsAdvancedMarkerElement :position="{ lat: 0, lng: 0 }" />
+<ScriptGoogleMapsMarker :position="{ lat: 0, lng: 0 }" />
```

#### 已移除 `ScriptGoogleMapsPinElement`（保留兼容层）

旧组件现在只渲染其默认插槽，并会发出开发环境警告；其 `options` 属性不再创建 Google Maps 图钉。请将标记内容移入 `<ScriptGoogleMapsMarker>`{lang="html"} 的 `#content` 插槽：

```diff
-<ScriptGoogleMapsAdvancedMarkerElement :position="pos">
-  <ScriptGoogleMapsPinElement :options="{ background: 'red' }" />
-</ScriptGoogleMapsAdvancedMarkerElement>
+<ScriptGoogleMapsMarker :position="pos">
+  <template #content>
+    <div class="custom-pin" style="background: red;">📍</div>
+  </template>
+</ScriptGoogleMapsMarker>
```

#### 已移除 `markers` 和 `centerMarker` 属性

改为使用子级 `<ScriptGoogleMapsMarker>`{lang="html"} 组件：

```diff
-<ScriptGoogleMaps
-  :center="center"
-  :markers="[{ position: { lat: 0, lng: 0 } }]"
-  center-marker
-/>
+<ScriptGoogleMaps :map-options="{ center, zoom: 12 }">
+  <ScriptGoogleMapsMarker :position="center" />
+  <ScriptGoogleMapsMarker :position="{ lat: 0, lng: 0 }" />
+</ScriptGoogleMaps>
```

#### 已移除静态占位图属性 ([#673](https://github.com/nuxt/scripts/pull/673))

v1 从 `<ScriptGoogleMaps>`{lang="html"} 中移除了 `placeholderOptions`、`placeholderAttrs` 和 `aboveTheFold` 属性。请将独立的 `<ScriptGoogleMapsStaticMap>`{lang="html"} 组件放入 `#placeholder` 插槽中。该插槽默认为空，不再接收 `placeholder` URL。

```diff
-<ScriptGoogleMaps
-  :center="center"
-  :zoom="7"
-  above-the-fold
-  :placeholder-options="{ maptype: 'satellite' }"
-  :placeholder-attrs="{ class: 'rounded' }"
-/>
+<ScriptGoogleMaps :map-options="{ center, zoom: 7 }">
+  <template #placeholder>
+    <ScriptGoogleMapsStaticMap
+      :center="center"
+      :zoom="7"
+      loading="eager"
+      maptype="satellite"
+      :img-attrs="{ class: 'rounded' }"
+    />
+  </template>
+</ScriptGoogleMaps>
```

#### 顶层 `:center` / `:zoom` 已弃用 ([#694](https://github.com/nuxt/scripts/pull/694))

建议改为通过 `:map-options` 传递这些属性。两种 API 仍然可用；旧版形式会在开发模式下发出警告。如果两者同时设置，则以 `mapOptions` 为准。

```diff
-<ScriptGoogleMaps :center="{ lat, lng }" :zoom="12" />
+<ScriptGoogleMaps :map-options="{ center: { lat, lng }, zoom: 12 }" />
```

#### 模板 ref `googleMaps` → `mapsApi` ([#695](https://github.com/nuxt/scripts/pull/695))

`mapsApi` 保存 `google.maps`{lang="ts"} API 命名空间。旧的 `googleMaps` 键仍作为已弃用的别名保留，并会在第一次读取时发出开发环境警告。

```diff
const mapRef = ref()
 onMounted(() => {
-  console.log(mapRef.value?.googleMaps)
+  console.log(mapRef.value?.mapsApi)
 })
```

同样的更名也适用于 `<ScriptGoogleMapsOverlayView>`{lang="html"}：其暴露的 `overlay` 键现在是 `overlayView`，同时保留 `overlay` 作为已弃用别名。

```diff
const overlayRef = ref()
 onMounted(() => {
-  console.log(overlayRef.value?.overlay)
+  console.log(overlayRef.value?.overlayView)
 })
```

### 类型扩展 ([#589](https://github.com/nuxt/scripts/pull/589))

v1 重新组织了生成的类型模板。升级后请运行 `nuxi prepare`：

```bash
npx nuxi prepare
```

## Sitemap

See the full [sitemap](/sitemap.md) for all pages.
