# Nuxt 3 按需引入 Bootstrap JS 与移动端折叠菜单初始化

URL: https://caijiao.org/posts/15
Source: docs/posts/15.md
Description: 介绍如何在 Nuxt 3 项目中按需引入 Bootstrap JS 组件（Collapse、Dropdown、Modal），并确保移动端 Navbar 默认折叠。

在 Nuxt 3 项目中，如果直接引入 `bootstrap/dist/js/bootstrap.bundle.js`，会导致打包体积增大，并且 HMR 可能报错。按需引入需要注意 `Collapse`、`Dropdown`、`Modal` 的初始化，以及移动端折叠菜单默认状态。

## 1. 创建 Bootstrap 客户端插件

在 `plugins/bootstrap.client.js` 中按需引入组件，并提供可调用的工厂函数：

```js
// plugins/bootstrap.client.js
export default defineNuxtPlugin(async (_nuxtApp) => {
  // 按需导入
  const { default: Modal } = await import("bootstrap/js/dist/modal");
  const { default: Collapse } = await import("bootstrap/js/dist/collapse");
  const { default: Dropdown } = await import("bootstrap/js/dist/dropdown");

  return {
    provide: {
      bootstrap: {
        collapse: (el, options = {}) => new Collapse(el, options),
        dropdown: (el, options = {}) => new Dropdown(el, options),
        modal: (el, options = {}) => new Modal(el, options),
      },
    },
  };
});
````

> 注意：这里的 `collapse`、`dropdown`、`modal` 工厂函数都支持第二个 `options` 参数，确保可以传入配置，例如 `toggle: false`。

## 2. 在组件中初始化 Navbar

在移动端，Bootstrap `Collapse` 默认会根据 `toggle` 自动展开，如果不设置，移动端菜单会默认展开。可以在 `onMounted` 中初始化：

```js
import { onMounted } from 'vue'

onMounted(() => {
  const nuxtApp = useNuxtApp()

  // 初始化 Collapse（移动端折叠菜单）
  document.querySelectorAll('.navbar-collapse').forEach(el => {
    if (!el._bsCollapse) {
      // toggle: false 确保默认折叠
      const collapseInstance = nuxtApp.$bootstrap.collapse(el, { toggle: false })
      el._bsCollapse = collapseInstance
    }
  })

  // 初始化 Dropdown（语言选择）
  document.querySelectorAll('[data-bs-toggle="dropdown"]').forEach(el => {
    if (!el._bsDropdown) {
      nuxtApp.$bootstrap.dropdown(el)
    }
  })
})
```

### 说明

1. `toggle: false`：确保 Collapse 初始化时不自动展开。
2. 保存实例到 DOM 上：`el._bsCollapse = collapseInstance`，便于后续操作。
3. 设置按钮 `aria-expanded="false"`：保持可访问性。
4. Dropdown 同样按需初始化，避免全局引入。

## 3. 使用示例

在 Navbar 组件中：

```html
<nav class="navbar navbar-expand-lg navbar-light">
  <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#mainNavbar">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="collapse navbar-collapse" id="mainNavbar">
    <ul class="navbar-nav">
      <li class="nav-item"><a class="nav-link" href="#home">Home</a></li>
      <li class="nav-item"><a class="nav-link" href="#about">About</a></li>
    </ul>
  </div>
</nav>
```

初始化完成后，移动端默认折叠菜单，不会自动展开，同时 Dropdown 功能可用。

## 4. 总结

* 使用按需导入，减少打包体积。
* Collapse 默认 `toggle: false` 可解决移动端折叠菜单自动展开问题。
* 保存实例在 DOM 上，便于后续手动调用 `show()` 或 `hide()`。
* Dropdown 与 Modal 同样可按需初始化。

这样即可在 Nuxt 3 项目中安全、轻量地使用 Bootstrap JS 组件，同时保证移动端折叠菜单默认收起状态。
