---
title: "useScript()"
description: "使用 Nuxt 特定选项加载和控制第三方脚本。"
canonical_url: "https://nuxt-scripts.zhcndoc.com/docs/api/use-script"
last_updated: "2026-08-11T09:33:09.236Z"
---

<callout icon="i-heroicons-play" target="_blank" to="https://stackblitz.com/github/nuxt/scripts/tree/main/examples/custom-script">

打开[实时 Custom Script 示例](https://stackblitz.com/github/nuxt/scripts/tree/main/examples/custom-script)。

</callout>

这个组合式函数封装了 Unhead 的 [`useScript()`](https://unhead.unjs.io/docs/head/guides/core-concepts/loading-scripts)，并添加了 Nuxt 触发器、打包、代理和 `reload()` 功能。它还提供了一个实验性的 Partytown 路径，具有更精简的 API，具体如下所述。

## 函数签名

```ts
export function useScript<T extends Record<symbol | string, any> = Record<symbol | string, any>>(
  input: UseScriptInput,
  options?: NuxtUseScriptOptions<T>,
): UseScriptContext<UseFunctionType<NuxtUseScriptOptions<T>, T>>
```

## 参数

### `UseScriptInput`

传入 URL 字符串或包含脚本标签属性的对象。

```ts
export type UseScriptInput = string | {
  src: string
  async?: boolean
  defer?: boolean
  type?: string
  integrity?: string
  crossorigin?: string
  innerHTML?: string
  textContent?: string
  referrerpolicy?: string
  // 支持其他 Unhead 脚本和数据属性。
}
```

Unhead 的[完整脚本示例](https://unhead.unjs.io/docs/head/guides/core-concepts/loading-scripts/#complete-example)展示了标签属性与加载选项的组合使用。

### `NuxtUseScriptOptions`

Nuxt Scripts 在 Unhead 的[脚本触发器和预热选项](https://unhead.unjs.io/docs/head/guides/core-concepts/loading-scripts/#how-do-i-control-when-scripts-load)基础上扩展了以下选项：

- `resolve` - 使用与生命周期绑定的 `signal` 和 `waitFor` 辅助函数解析已加载的 SDK。
- `use` - 传统的同步或异步 SDK 解析器。对于基于回调的就绪状态，建议使用 `resolve`。
- `trigger` - [触发脚本加载](/docs/guides/script-triggers)
- `bundle` - 控制[第一方打包](/docs/guides/first-party)。
- `proxy` - 为注册表脚本启用或禁用受支持的采集代理。
- `partytown` - 通过 Partytown 运行受支持的注册表脚本。

<callout color="amber">

`partytown: true` 会采用提前的 SSR 路径。无论 `trigger` 如何设置，都会立即写入 `<script type="text/partytown" src="…">` 标签，并忽略其他脚本属性和选项，例如 `use`、`beforeInit` 和 `warmupStrategy`。返回的存根会报告 `loaded`；`load()` 不执行任何操作，`remove()` 只会断开 DevTools 观察，而 `proxy`、`reload()` 和生命周期回调均不可用。请将 Partytown 的返回值视为实现细节。

</callout>

```ts
export type NuxtUseScriptOptions<T = any> = Omit<UseScriptOptions<T>, 'trigger'> & {
  /**
   * 加载脚本的触发时机：
   * - `onNuxtReady` - 当 Nuxt 准备就绪时加载脚本。
   * - `manual` - 通过调用 `load()` 手动加载脚本。
   * - `Promise` - 当 Promise 解析完成时加载脚本。
   */
  trigger?: UseScriptOptions<T>['trigger'] | 'onNuxtReady'
  /**
   * 将脚本作为资源打包，并从你的服务器提供服务。这样可以避免
   * 原始主机的 DNS 查询，并使初始请求保持在你的源站上。
   * - `true` - 将脚本作为资源打包。
   * - `'force'` - 重新打包并下载脚本，而不是使用构建缓存。
   * - `false` - 不打包脚本。（普通 useScript 调用的默认值）
   *
   * @deprecated 对于支持打包的注册表脚本，系统会自动启用打包。
   * 在注册表脚本上设置 `bundle: false` 可禁用此功能。
   */
  bundle?: boolean | 'force'
  /**
   * 使用 Partytown 在 Web Worker 中加载脚本。
   * 启用后，会将 `type="text/partytown"` 添加到脚本标签中。
   * 需要单独安装并配置 @nuxtjs/partytown。
   * @see https://partytown.qwik.dev/
   */
  partytown?: boolean
  /**
   * 控制此脚本的代理。
   * 当为 `false` 时，采集请求会直接发送到第三方服务器。
   * 当为 `true` 时，采集请求会通过 `/_scripts/p/` 进行代理。
   * 此选项适用于注册表脚本，默认使用其声明的 `proxy` 功能。
   */
  proxy?: boolean
  /**
   * 跳过脚本输入验证。用于不会加载实际脚本的开发存根。
   */
  skipValidation?: boolean
  /**
   * 指定预热与第三方脚本连接的策略。
   *  - `false` - 禁用预加载。
   *  - `'preload'` - 预加载脚本。
   *  - `'preconnect'` | `'dns-prefetch'` - 预连接到脚本源。
   */
  warmupStrategy?: false | 'preload' | 'preconnect' | 'dns-prefetch'
}
```

## 返回值

关于基础上下文 API，请参阅 Unhead 的[代理和直接访问示例](https://unhead.unjs.io/docs/head/guides/core-concepts/loading-scripts/#how-do-i-call-script-functions-before-loading-completes)。“[代理函数指南](/docs/guides/key-concepts)”介绍了脚本加载前如何将调用排队。

在 Partytown 路径之外，返回的对象包括：

- `proxy` - 一个类型化代理，会将调用排队，直到加载完成
- `status` - 包含脚本状态的响应式 ref：`'awaitingLoad'` | `'loading'` | `'loaded'` | `'error'` | `'removed'`
- `load()` - 手动加载脚本的函数
- `signal` - 作用域限定于此组合式函数使用者的 `AbortSignal`
- `dispose()` - 释放此使用者的回调和触发器，但不会移除共享脚本
- `script` - 共享的 Unhead 脚本实例
- `remove()` - 为所有使用者移除共享脚本
- `reload()` - 移除并重新加载脚本的函数（见下文）
- `onLoaded()` 和 `onError()` - 脚本生命周期回调

每次调用都会获得其自身的使用者作用域。当组件卸载时，Vue 会释放该作用域，而共享脚本仍可供其他调用者使用。
仅在需要全局移除脚本时调用 `remove()`。

### 感知生命周期的 SDK 就绪状态

当供应商提供一个在脚本元素的 `load` 事件触发后执行的回调时，请使用 `resolve({ waitFor })`。此时，监听器清理和中止拒绝都会与共享脚本的生命周期绑定。

```ts
const sdk = useScript<{ ready: true }>('https://example.com/sdk.js', {
  resolve: ({ waitFor }) => waitFor<{ ready: true }>((resolve) => {
    window.onExampleReady = () => resolve({ ready: true })
    return () => delete window.onExampleReady
  }),
})

const api = await sdk.load()
```

### `reload()`

移除脚本、再次插入脚本并重新执行脚本。对于只扫描一次 DOM、且必须在 SPA 导航后再次扫描的脚本，请使用此方法。

```ts
const { reload } = useScript('https://example.com/dom-scanner.js')

// 导航时重新加载
watch(() => route.path, () => reload())
```

<callout color="blue" icon="i-heroicons-light-bulb">

如果供应商提供了 SPA API，请优先使用该 API。例如，iubenda 的 [`_iub.cs.api.activateSnippets()`](https://www.iubenda.com/en/help/1205-how-to-configure-your-cookie-solution-advanced-guide-2/#5-7-api) 可以激活新添加的被阻止代码片段，而无需重新加载整个脚本。

</callout>
