> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kontext.so/llms.txt
> Use this file to discover all available pages before exploring further.

# 实践指南

> Vue SDK 接入中常见任务的模式与配方。

## 处理 no-fill

订阅 `ad.no-fill` 以了解何时没有返回广告（地域限制、频次封顶、服务端跳过等）。payload 中的 `skipCode` 会说明原因。

```ts theme={null}
app.use(KontextAdsPlugin, {
  // ...
  onEvent: ({ name, payload }) => {
    if (name === 'ad.no-fill') {
      console.log('无广告可用:', payload.skipCode)
    }
  },
})
```

现在每次 preload 都会恰好产生一个 `ad.filled` / `ad.no-fill` / `ad.error` 事件，你可以依赖在每条用户消息后收到回应。

## 传入每一条消息，并用 `trackOnly` 抑制广告

请**始终**把每条消息都喂给会话，即使你不希望广告出现（例如用户处于免费试用、所在地区不投放广告、或你只想每 N 条消息展示一次广告）。跳过 `addMessage` 调用会破坏服务端用于定向的对话上下文。完整模式见 [节奏控制](/concepts/pacing)。

使用 `{ trackOnly: true }` 让 preload 仅用于分析，不生成广告：

```ts theme={null}
const { addMessage } = useAds()
const shouldShowAd = userMessageCount.value % 5 === 0

addMessage(
  { id: msg.id, role: 'user', content: msg.content, createdAt: new Date() },
  { trackOnly: !shouldShowAd }
)
```

`trackOnly: true` 时 preload 仍会发出（服务端保留完整分析数据），但该消息不会触发 `ad.filled` 事件，对应的 `<InlineAd>` 也不会渲染内容。

## 会话中途实时更新 consent

插件（或 `<AdsProvider>`）会把新的 props 响应式地传给底层会话。把 `regulatory` 绑定到你 CMP 的状态，下一次 preload 会自动采用新值：

```vue theme={null}
<AdsProvider
  :publisher-token="publisherToken"
  :user-id="userId"
  :conversation-id="conversationId"
  :regulatory="{ gdpr: gdprConsent.applies ? 1 : 0, gdprConsent: gdprConsent.tcString }"
>
  <Chat />
</AdsProvider>
```

无需重建会话。

## 切换 character

进行中的 `character` 不能实时更新——已累积的消息历史归属于原角色，会话中途切换会让消息被定向到错误的角色。

要切换角色，请同时修改 `<AdsProvider>` 上的 `conversationId`（与 `character`）prop。Provider 会自动销毁原会话并创建新会话：

```vue theme={null}
<AdsProvider
  :publisher-token="publisherToken"
  :user-id="userId"
  :conversation-id="conversationId"
  :character="currentCharacter"
>
  <Chat />
</AdsProvider>
```

`publisherToken`、`userId`、`conversationId`、`enabledPlacementCodes` 同理——其中任何一个变化都会重建会话。

## 加载历史消息（会话恢复）

从后端恢复对话时，请按顺序对每条历史消息调用一次 `addMessage(...)`。Preload 是经过防抖的（约 10 ms），所以连续的快速调用会合并成单次 preload（针对最新的用户消息）——不会出现"每恢复一条消息就发一次 preload"的情况。

```ts theme={null}
const { addMessage } = useAds()

for (const m of loadedFromBackend) {
  addMessage({
    id: m.id,
    role: m.role,
    content: m.content,
    createdAt: m.timestamp,
  })
}
```
