本章概述
本章将详细介绍 Bootstrap 的各种安装方式、配置方法以及开发环境的搭建。通过本章学习,你将掌握如何在不同的项目中集成 Bootstrap,并建立高效的开发工作流。
安装方式
1. CDN 引入(推荐入门)
CDN 是最简单快速的使用方式,适合快速原型开发和学习。
基本 CDN 引入
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bootstrap CDN 示例</title>
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
</head>
<body>
<div class="container">
<h1 class="text-primary">Hello Bootstrap!</h1>
<button class="btn btn-success">成功按钮</button>
</div>
<!-- Bootstrap JavaScript -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
</body>
</html>
分离式 JavaScript 引入
如果你需要单独控制 Popper.js,可以使用分离式引入:
<!-- Popper.js (必须在 Bootstrap JS 之前) -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/umd/popper.min.js" integrity="sha384-I7E8VVD/ismYTF4hNIPjVp/Zjvgyol6VFvRkX/vR+Vc4jQkC+hVqc2pM8ODewa9r" crossorigin="anonymous"></script>
<!-- Bootstrap JavaScript -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.min.js" integrity="sha384-BBtl+eGJRgqQAUMxJ7pMwbEyER4l1g+O15P+16Ep7Q9Q+zqX6gSbd85u4mG4QzX+" crossorigin="anonymous"></script>
国内 CDN 选择
<!-- 使用 BootCDN -->
<link href="https://cdn.bootcdn.net/ajax/libs/bootstrap/5.3.2/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/bootstrap/5.3.2/js/bootstrap.bundle.min.js"></script>
<!-- 使用 UNPKG -->
<link href="https://unpkg.com/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://unpkg.com/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<!-- 使用 cdnjs -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.2/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.2/js/bootstrap.bundle.min.js"></script>
2. 包管理器安装
npm 安装
# 安装最新版本
npm install bootstrap
# 安装指定版本
npm install bootstrap@5.3.2
# 同时安装 Popper.js(如果需要单独使用)
npm install @popperjs/core
在项目中使用:
// 导入 CSS
import 'bootstrap/dist/css/bootstrap.min.css';
// 导入 JavaScript
import 'bootstrap/dist/js/bootstrap.bundle.min.js';
// 或者按需导入
import { Modal, Tooltip } from 'bootstrap';
Yarn 安装
# 使用 Yarn 安装
yarn add bootstrap
# 安装指定版本
yarn add bootstrap@5.3.2
pnpm 安装
# 使用 pnpm 安装
pnpm add bootstrap
# 安装指定版本
pnpm add bootstrap@5.3.2
3. 下载源码
编译版本下载
从 Bootstrap 官网 下载编译好的版本:
bootstrap-5.3.2-dist/
├── css/
│ ├── bootstrap.css
│ ├── bootstrap.css.map
│ ├── bootstrap.min.css
│ ├── bootstrap.min.css.map
│ ├── bootstrap-grid.css
│ ├── bootstrap-grid.css.map
│ ├── bootstrap-grid.min.css
│ ├── bootstrap-grid.min.css.map
│ ├── bootstrap-reboot.css
│ ├── bootstrap-reboot.css.map
│ ├── bootstrap-reboot.min.css
│ ├── bootstrap-reboot.min.css.map
│ ├── bootstrap-utilities.css
│ ├── bootstrap-utilities.css.map
│ ├── bootstrap-utilities.min.css
│ └── bootstrap-utilities.min.css.map
└── js/
├── bootstrap.bundle.js
├── bootstrap.bundle.js.map
├── bootstrap.bundle.min.js
├── bootstrap.bundle.min.js.map
├── bootstrap.esm.js
├── bootstrap.esm.js.map
├── bootstrap.esm.min.js
├── bootstrap.esm.min.js.map
├── bootstrap.js
├── bootstrap.js.map
├── bootstrap.min.js
└── bootstrap.min.js.map
源码版本下载
下载源码进行自定义编译:
# 克隆 GitHub 仓库
git clone https://github.com/twbs/bootstrap.git
cd bootstrap
# 安装依赖
npm install
# 编译源码
npm run dist
项目结构配置
1. 基础项目结构
my-bootstrap-project/
├── index.html
├── css/
│ ├── bootstrap.min.css
│ └── custom.css
├── js/
│ ├── bootstrap.bundle.min.js
│ └── main.js
├── images/
└── assets/
基础 HTML 模板
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="网站描述">
<meta name="author" content="作者名称">
<title>Bootstrap 项目</title>
<!-- Bootstrap CSS -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<!-- 自定义 CSS -->
<link href="css/custom.css" rel="stylesheet">
<!-- Favicon -->
<link rel="icon" type="image/x-icon" href="assets/favicon.ico">
</head>
<body>
<!-- 导航栏 -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<a class="navbar-brand" href="#">我的网站</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav ms-auto">
<li class="nav-item">
<a class="nav-link active" href="#">首页</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">关于</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">联系</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- 主要内容 -->
<main class="container my-5">
<div class="row">
<div class="col-lg-8">
<h1>欢迎来到我的网站</h1>
<p class="lead">这是一个使用 Bootstrap 构建的示例页面。</p>
</div>
<div class="col-lg-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">侧边栏</h5>
<p class="card-text">这里是侧边栏内容。</p>
</div>
</div>
</div>
</div>
</main>
<!-- 页脚 -->
<footer class="bg-dark text-white text-center py-3">
<div class="container">
<p>© 2023 我的网站. 保留所有权利.</p>
</div>
</footer>
<!-- Bootstrap JavaScript -->
<script src="js/bootstrap.bundle.min.js"></script>
<!-- 自定义 JavaScript -->
<script src="js/main.js"></script>
</body>
</html>
2. 现代前端项目结构
Vite + Bootstrap 项目
# 创建 Vite 项目
npm create vite@latest my-bootstrap-app -- --template vanilla
cd my-bootstrap-app
# 安装 Bootstrap
npm install bootstrap @popperjs/core
# 安装 Sass(用于自定义)
npm install -D sass
项目结构:
my-bootstrap-app/
├── index.html
├── package.json
├── vite.config.js
├── src/
│ ├── main.js
│ ├── style.scss
│ └── components/
└── public/
vite.config.js 配置
import { defineConfig } from 'vite';
import path from 'path';
export default defineConfig({
root: path.resolve(__dirname, 'src'),
build: {
outDir: '../dist'
},
server: {
port: 8080
},
css: {
preprocessorOptions: {
scss: {
additionalData: `@import "bootstrap/scss/functions"; @import "bootstrap/scss/variables";`
}
}
}
});
main.js 入口文件
// 导入 Bootstrap CSS
import 'bootstrap/dist/css/bootstrap.min.css';
// 导入自定义样式
import './style.scss';
// 导入 Bootstrap JavaScript
import 'bootstrap/dist/js/bootstrap.bundle.min.js';
// 或者按需导入
// import { Modal, Tooltip, Popover } from 'bootstrap';
// 初始化应用
document.addEventListener('DOMContentLoaded', function() {
console.log('Bootstrap 应用已加载');
// 初始化工具提示
const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
const tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl);
});
});
自定义样式文件 (style.scss)
// 导入 Bootstrap 函数和变量
@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
// 自定义变量
$primary: #007bff;
$secondary: #6c757d;
$success: #28a745;
$info: #17a2b8;
$warning: #ffc107;
$danger: #dc3545;
$light: #f8f9fa;
$dark: #343a40;
// 自定义字体
$font-family-sans-serif: "Helvetica Neue", Arial, "Noto Sans", sans-serif;
// 导入 Bootstrap
@import "bootstrap/scss/bootstrap";
// 自定义样式
.custom-header {
background: linear-gradient(135deg, $primary, $info);
color: white;
padding: 2rem 0;
}
.custom-card {
border: none;
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
transition: box-shadow 0.15s ease-in-out;
&:hover {
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
}
}
3. Webpack 配置
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'js/[name].[contenthash].js',
clean: true
},
module: {
rules: [
{
test: /\.(scss|css)$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'sass-loader',
options: {
implementation: require('sass')
}
}
]
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource',
generator: {
filename: 'images/[name].[hash][ext]'
}
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource',
generator: {
filename: 'fonts/[name].[hash][ext]'
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
filename: 'index.html'
}),
new MiniCssExtractPlugin({
filename: 'css/[name].[contenthash].css'
})
],
devServer: {
static: './dist',
port: 8080,
open: true
}
};
构建工具集成
1. Gulp 集成
gulpfile.js
const gulp = require('gulp');
const sass = require('gulp-sass')(require('sass'));
const cleanCSS = require('gulp-clean-css');
const uglify = require('gulp-uglify');
const concat = require('gulp-concat');
const browserSync = require('browser-sync').create();
const del = require('del');
// 路径配置
const paths = {
scss: {
src: 'src/scss/**/*.scss',
dest: 'dist/css/'
},
js: {
src: 'src/js/**/*.js',
dest: 'dist/js/'
},
html: {
src: 'src/**/*.html',
dest: 'dist/'
},
bootstrap: {
css: 'node_modules/bootstrap/dist/css/bootstrap.min.css',
js: 'node_modules/bootstrap/dist/js/bootstrap.bundle.min.js'
}
};
// 清理任务
function clean() {
return del(['dist']);
}
// 编译 SCSS
function styles() {
return gulp.src(paths.scss.src)
.pipe(sass().on('error', sass.logError))
.pipe(cleanCSS())
.pipe(gulp.dest(paths.scss.dest))
.pipe(browserSync.stream());
}
// 处理 JavaScript
function scripts() {
return gulp.src([paths.bootstrap.js, paths.js.src])
.pipe(concat('main.min.js'))
.pipe(uglify())
.pipe(gulp.dest(paths.js.dest));
}
// 复制 HTML
function html() {
return gulp.src(paths.html.src)
.pipe(gulp.dest(paths.html.dest));
}
// 复制 Bootstrap CSS
function bootstrapCSS() {
return gulp.src(paths.bootstrap.css)
.pipe(gulp.dest(paths.scss.dest));
}
// 开发服务器
function serve() {
browserSync.init({
server: {
baseDir: './dist'
}
});
gulp.watch(paths.scss.src, styles);
gulp.watch(paths.js.src, scripts);
gulp.watch(paths.html.src, html).on('change', browserSync.reload);
}
// 监听任务
function watch() {
gulp.watch(paths.scss.src, styles);
gulp.watch(paths.js.src, scripts);
gulp.watch(paths.html.src, html);
}
// 构建任务
const build = gulp.series(clean, gulp.parallel(styles, scripts, html, bootstrapCSS));
const dev = gulp.series(build, serve);
// 导出任务
exports.clean = clean;
exports.styles = styles;
exports.scripts = scripts;
exports.html = html;
exports.watch = watch;
exports.serve = serve;
exports.build = build;
exports.dev = dev;
exports.default = build;
package.json 脚本
{
"name": "bootstrap-gulp-project",
"version": "1.0.0",
"scripts": {
"build": "gulp build",
"dev": "gulp dev",
"watch": "gulp watch",
"clean": "gulp clean"
},
"devDependencies": {
"gulp": "^4.0.2",
"gulp-sass": "^5.1.0",
"gulp-clean-css": "^4.3.0",
"gulp-uglify": "^3.0.2",
"gulp-concat": "^2.6.1",
"browser-sync": "^2.29.3",
"del": "^7.1.0",
"sass": "^1.69.5"
},
"dependencies": {
"bootstrap": "^5.3.2"
}
}
2. Parcel 集成
项目结构
my-parcel-app/
├── src/
│ ├── index.html
│ ├── index.js
│ └── styles.scss
├── package.json
└── .parcelrc
.parcelrc 配置
{
"extends": "@parcel/config-default",
"transformers": {
"*.{ts,tsx}": ["@parcel/transformer-typescript-tsc"]
}
}
package.json
{
"name": "bootstrap-parcel-app",
"version": "1.0.0",
"scripts": {
"start": "parcel src/index.html",
"build": "parcel build src/index.html",
"clean": "rm -rf dist .parcel-cache"
},
"devDependencies": {
"parcel": "^2.10.0",
"sass": "^1.69.5"
},
"dependencies": {
"bootstrap": "^5.3.2"
}
}
自定义配置
1. Sass 变量自定义
创建自定义变量文件
// custom-variables.scss
// 颜色自定义
$primary: #6f42c1;
$secondary: #fd7e14;
$success: #20c997;
$info: #0dcaf0;
$warning: #ffc107;
$danger: #e74c3c;
$light: #f8f9fa;
$dark: #212529;
// 字体自定义
$font-family-sans-serif: "Inter", "Helvetica Neue", Arial, sans-serif;
$font-family-monospace: "JetBrains Mono", "Fira Code", monospace;
// 字体大小
$font-size-base: 1rem;
$font-size-sm: $font-size-base * 0.875;
$font-size-lg: $font-size-base * 1.25;
// 间距
$spacer: 1rem;
$spacers: (
0: 0,
1: $spacer * 0.25,
2: $spacer * 0.5,
3: $spacer,
4: $spacer * 1.5,
5: $spacer * 3,
6: $spacer * 4,
7: $spacer * 5
);
// 边框半径
$border-radius: 0.5rem;
$border-radius-sm: 0.25rem;
$border-radius-lg: 0.75rem;
$border-radius-xl: 1rem;
// 断点自定义
$grid-breakpoints: (
xs: 0,
sm: 576px,
md: 768px,
lg: 992px,
xl: 1200px,
xxl: 1400px,
xxxl: 1600px // 添加超大断点
);
// 容器最大宽度
$container-max-widths: (
sm: 540px,
md: 720px,
lg: 960px,
xl: 1140px,
xxl: 1320px,
xxxl: 1500px
);
// 组件自定义
$navbar-padding-y: 1rem;
$navbar-padding-x: 1.5rem;
$card-border-radius: $border-radius-lg;
$card-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
$btn-border-radius: $border-radius;
$btn-border-radius-sm: $border-radius-sm;
$btn-border-radius-lg: $border-radius-lg;
主样式文件
// main.scss
// 1. 导入自定义变量
@import "custom-variables";
// 2. 导入 Bootstrap 函数
@import "bootstrap/scss/functions";
// 3. 导入 Bootstrap 变量(会使用我们的自定义变量)
@import "bootstrap/scss/variables";
// 4. 导入 Bootstrap mixins
@import "bootstrap/scss/mixins";
// 5. 导入 Bootstrap 组件(可选择性导入)
@import "bootstrap/scss/root";
@import "bootstrap/scss/reboot";
@import "bootstrap/scss/type";
@import "bootstrap/scss/images";
@import "bootstrap/scss/containers";
@import "bootstrap/scss/grid";
@import "bootstrap/scss/tables";
@import "bootstrap/scss/forms";
@import "bootstrap/scss/buttons";
@import "bootstrap/scss/transitions";
@import "bootstrap/scss/dropdown";
@import "bootstrap/scss/button-group";
@import "bootstrap/scss/nav";
@import "bootstrap/scss/navbar";
@import "bootstrap/scss/card";
@import "bootstrap/scss/accordion";
@import "bootstrap/scss/breadcrumb";
@import "bootstrap/scss/pagination";
@import "bootstrap/scss/badge";
@import "bootstrap/scss/alert";
@import "bootstrap/scss/progress";
@import "bootstrap/scss/list-group";
@import "bootstrap/scss/close";
@import "bootstrap/scss/toasts";
@import "bootstrap/scss/modal";
@import "bootstrap/scss/tooltip";
@import "bootstrap/scss/popover";
@import "bootstrap/scss/carousel";
@import "bootstrap/scss/spinners";
@import "bootstrap/scss/offcanvas";
@import "bootstrap/scss/placeholders";
@import "bootstrap/scss/helpers";
@import "bootstrap/scss/utilities/api";
// 6. 自定义样式
@import "custom-components";
自定义组件样式
// custom-components.scss
// 自定义按钮样式
.btn-gradient {
background: linear-gradient(45deg, $primary, $info);
border: none;
color: white;
&:hover {
background: linear-gradient(45deg, darken($primary, 10%), darken($info, 10%));
color: white;
}
}
// 自定义卡片样式
.card-hover {
transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out;
&:hover {
transform: translateY(-5px);
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
}
}
// 自定义导航栏
.navbar-custom {
background: linear-gradient(135deg, $primary, $secondary);
.navbar-brand,
.nav-link {
color: white !important;
&:hover {
color: rgba(255, 255, 255, 0.8) !important;
}
}
}
// 自定义表单
.form-floating-custom {
.form-control {
border-radius: $border-radius-lg;
border: 2px solid transparent;
background-color: $light;
&:focus {
border-color: $primary;
box-shadow: 0 0 0 0.2rem rgba($primary, 0.25);
}
}
label {
color: $secondary;
}
}
// 响应式工具类
@include media-breakpoint-up(xxxl) {
.container-xxxl {
max-width: map-get($container-max-widths, xxxl);
}
}
// 自定义动画
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.animate-fade-in-up {
animation: fadeInUp 0.6s ease-out;
}
// 暗色主题支持
@media (prefers-color-scheme: dark) {
:root {
--bs-body-bg: #{$dark};
--bs-body-color: #{$light};
}
.card {
background-color: lighten($dark, 10%);
border-color: lighten($dark, 20%);
}
}
2. JavaScript 模块化配置
按需导入 Bootstrap 组件
// bootstrap-modules.js
// 只导入需要的组件
import { Modal } from 'bootstrap/js/dist/modal';
import { Dropdown } from 'bootstrap/js/dist/dropdown';
import { Tooltip } from 'bootstrap/js/dist/tooltip';
import { Popover } from 'bootstrap/js/dist/popover';
import { Toast } from 'bootstrap/js/dist/toast';
import { Carousel } from 'bootstrap/js/dist/carousel';
import { Collapse } from 'bootstrap/js/dist/collapse';
import { Offcanvas } from 'bootstrap/js/dist/offcanvas';
// 创建 Bootstrap 管理器
class BootstrapManager {
constructor() {
this.components = {
Modal,
Dropdown,
Tooltip,
Popover,
Toast,
Carousel,
Collapse,
Offcanvas
};
this.instances = new Map();
}
// 初始化所有组件
init() {
this.initTooltips();
this.initPopovers();
this.initToasts();
this.initCarousels();
}
// 初始化工具提示
initTooltips() {
const tooltipTriggerList = [].slice.call(
document.querySelectorAll('[data-bs-toggle="tooltip"]')
);
tooltipTriggerList.forEach(tooltipTriggerEl => {
const tooltip = new Tooltip(tooltipTriggerEl);
this.instances.set(tooltipTriggerEl, tooltip);
});
}
// 初始化弹出框
initPopovers() {
const popoverTriggerList = [].slice.call(
document.querySelectorAll('[data-bs-toggle="popover"]')
);
popoverTriggerList.forEach(popoverTriggerEl => {
const popover = new Popover(popoverTriggerEl);
this.instances.set(popoverTriggerEl, popover);
});
}
// 初始化提示框
initToasts() {
const toastElList = [].slice.call(
document.querySelectorAll('.toast')
);
toastElList.forEach(toastEl => {
const toast = new Toast(toastEl);
this.instances.set(toastEl, toast);
});
}
// 初始化轮播图
initCarousels() {
const carouselElList = [].slice.call(
document.querySelectorAll('.carousel')
);
carouselElList.forEach(carouselEl => {
const carousel = new Carousel(carouselEl, {
interval: 5000,
wrap: true
});
this.instances.set(carouselEl, carousel);
});
}
// 创建模态框
createModal(element, options = {}) {
const modal = new Modal(element, options);
this.instances.set(element, modal);
return modal;
}
// 显示提示框
showToast(message, type = 'info') {
const toastHtml = `
<div class="toast align-items-center text-white bg-${type} border-0" role="alert">
<div class="d-flex">
<div class="toast-body">
${message}
</div>
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button>
</div>
</div>
`;
const toastContainer = document.querySelector('.toast-container') || this.createToastContainer();
toastContainer.insertAdjacentHTML('beforeend', toastHtml);
const toastElement = toastContainer.lastElementChild;
const toast = new Toast(toastElement);
toast.show();
// 自动清理
toastElement.addEventListener('hidden.bs.toast', () => {
toastElement.remove();
});
return toast;
}
// 创建提示框容器
createToastContainer() {
const container = document.createElement('div');
container.className = 'toast-container position-fixed bottom-0 end-0 p-3';
document.body.appendChild(container);
return container;
}
// 销毁组件实例
dispose(element) {
const instance = this.instances.get(element);
if (instance) {
instance.dispose();
this.instances.delete(element);
}
}
// 销毁所有实例
disposeAll() {
this.instances.forEach((instance, element) => {
instance.dispose();
});
this.instances.clear();
}
}
// 导出单例
export default new BootstrapManager();
使用示例
// main.js
import BootstrapManager from './bootstrap-modules.js';
// DOM 加载完成后初始化
document.addEventListener('DOMContentLoaded', () => {
// 初始化 Bootstrap 组件
BootstrapManager.init();
// 示例:显示欢迎提示
BootstrapManager.showToast('欢迎使用我们的网站!', 'success');
// 示例:创建动态模态框
const createModalBtn = document.getElementById('createModal');
if (createModalBtn) {
createModalBtn.addEventListener('click', () => {
const modalHtml = `
<div class="modal fade" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">动态模态框</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p>这是一个动态创建的模态框。</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
<button type="button" class="btn btn-primary">保存</button>
</div>
</div>
</div>
</div>
`;
document.body.insertAdjacentHTML('beforeend', modalHtml);
const modalElement = document.body.lastElementChild;
const modal = BootstrapManager.createModal(modalElement);
modal.show();
// 模态框隐藏后清理
modalElement.addEventListener('hidden.bs.modal', () => {
BootstrapManager.dispose(modalElement);
modalElement.remove();
});
});
}
});
// 页面卸载时清理
window.addEventListener('beforeunload', () => {
BootstrapManager.disposeAll();
});
开发工具配置
1. VS Code 配置
.vscode/settings.json
{
"emmet.includeLanguages": {
"javascript": "html"
},
"emmet.triggerExpansionOnTab": true,
"css.validate": false,
"scss.validate": false,
"less.validate": false,
"files.associations": {
"*.scss": "scss"
},
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": true
},
"liveServer.settings.port": 3000,
"liveServer.settings.root": "/dist"
}
推荐扩展
// .vscode/extensions.json
{
"recommendations": [
"ritwickdey.liveserver",
"bradlc.vscode-tailwindcss",
"syler.sass-indented",
"ms-vscode.vscode-typescript-next",
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"formulahendry.auto-rename-tag",
"christian-kohler.path-intellisense",
"zignd.html-css-class-completion"
]
}
2. 代码格式化配置
.prettierrc
{
"semi": true,
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"bracketSpacing": true,
"arrowParens": "avoid",
"endOfLine": "lf",
"htmlWhitespaceSensitivity": "css",
"overrides": [
{
"files": "*.scss",
"options": {
"singleQuote": false
}
}
]
}
.eslintrc.js
module.exports = {
env: {
browser: true,
es2021: true,
node: true
},
extends: [
'eslint:recommended'
],
parserOptions: {
ecmaVersion: 12,
sourceType: 'module'
},
rules: {
'indent': ['error', 2],
'linebreak-style': ['error', 'unix'],
'quotes': ['error', 'single'],
'semi': ['error', 'always'],
'no-unused-vars': 'warn',
'no-console': 'warn'
},
globals: {
'bootstrap': 'readonly'
}
};
3. Git 配置
.gitignore
# 依赖
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# 构建输出
dist/
build/
.parcel-cache/
# 环境变量
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
# IDE
.vscode/
.idea/
*.swp
*.swo
*~
# 操作系统
.DS_Store
Thumbs.db
# 日志
logs
*.log
# 临时文件
*.tmp
*.temp
# 缓存
.cache/
.sass-cache/
# 测试覆盖率
coverage/
.nyc_output/
性能优化
1. 按需加载
只加载需要的 CSS
// 只导入需要的 Bootstrap 组件
@import "bootstrap/scss/functions";
@import "bootstrap/scss/variables";
@import "bootstrap/scss/mixins";
// 基础样式
@import "bootstrap/scss/root";
@import "bootstrap/scss/reboot";
@import "bootstrap/scss/type";
@import "bootstrap/scss/containers";
@import "bootstrap/scss/grid";
// 只导入使用的组件
@import "bootstrap/scss/buttons";
@import "bootstrap/scss/nav";
@import "bootstrap/scss/navbar";
@import "bootstrap/scss/card";
@import "bootstrap/scss/modal";
// 工具类(可选)
@import "bootstrap/scss/utilities/api";
动态导入 JavaScript
// 动态导入组件
async function loadModal() {
const { Modal } = await import('bootstrap/js/dist/modal');
return Modal;
}
// 使用示例
document.getElementById('openModal').addEventListener('click', async () => {
const Modal = await loadModal();
const modal = new Modal(document.getElementById('myModal'));
modal.show();
});
2. CDN 优化
<!-- 使用 preload 预加载关键资源 -->
<link rel="preload" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css"></noscript>
<!-- 使用 defer 延迟加载 JavaScript -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" defer></script>
3. 构建优化
Webpack 优化配置
// webpack.config.js
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
module.exports = {
mode: 'production',
optimization: {
minimizer: [
new TerserPlugin({
terserOptions: {
compress: {
drop_console: true,
},
},
}),
new CssMinimizerPlugin(),
],
splitChunks: {
chunks: 'all',
cacheGroups: {
bootstrap: {
test: /[\\/]node_modules[\\/]bootstrap[\\/]/,
name: 'bootstrap',
chunks: 'all',
},
},
},
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].[contenthash].css',
}),
],
};
故障排除
1. 常见问题
样式不生效
<!-- 检查 CSS 引入顺序 -->
<link href="bootstrap.min.css" rel="stylesheet">
<link href="custom.css" rel="stylesheet"> <!-- 自定义样式应该在 Bootstrap 之后 -->
JavaScript 组件不工作
// 确保 DOM 加载完成
document.addEventListener('DOMContentLoaded', function() {
// 初始化 Bootstrap 组件
const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
const tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl);
});
});
响应式不工作
<!-- 确保包含 viewport meta 标签 -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
2. 调试技巧
使用浏览器开发工具
// 检查 Bootstrap 是否正确加载
console.log(typeof bootstrap !== 'undefined' ? 'Bootstrap 已加载' : 'Bootstrap 未加载');
// 检查组件实例
const modal = bootstrap.Modal.getInstance(document.getElementById('myModal'));
console.log(modal);
CSS 调试
/* 临时边框调试 */
* {
outline: 1px solid red !important;
}
/* 网格调试 */
.container,
.container-fluid {
outline: 2px solid blue;
}
.row {
outline: 2px solid green;
}
[class*="col-"] {
outline: 2px solid orange;
}
练习题
基础练习
CDN 集成
- 创建一个使用 CDN 的 Bootstrap 页面
- 包含导航栏、轮播图和卡片组件
- 确保所有交互功能正常工作
包管理器安装
- 使用 npm 创建一个新项目
- 安装 Bootstrap 和必要的构建工具
- 配置 Sass 编译
自定义主题
- 创建自定义的颜色方案
- 修改字体和间距
- 编译生成自定义的 Bootstrap CSS
进阶练习
Webpack 集成
- 配置 Webpack 构建流程
- 实现代码分割和懒加载
- 优化构建性能
组件按需加载
- 实现 JavaScript 组件的动态导入
- 创建组件管理器
- 优化页面加载性能
开发环境配置
- 配置热重载开发服务器
- 设置代码格式化和检查
- 创建自动化构建流程
本章总结
通过本章学习,我们掌握了:
多种安装方式:CDN、包管理器、源码下载等不同的集成方法
项目结构配置:从基础项目到现代前端工具链的完整配置
构建工具集成:Vite、Webpack、Gulp、Parcel 等工具的配置方法
自定义配置:Sass 变量自定义和 JavaScript 模块化配置
开发工具配置:IDE 配置、代码格式化、版本控制等开发环境优化
性能优化:按需加载、CDN 优化、构建优化等性能提升技巧
故障排除:常见问题的解决方法和调试技巧
正确的安装配置是使用 Bootstrap 的基础,选择合适的集成方式和配置开发环境将大大提高开发效率。在下一章中,我们将深入学习 Bootstrap 的网格系统和响应式布局。