以BootStrap Tab为例写一个前端组件
发布时间 - 2026-01-11 02:30:12 点击率:次介绍

本文以Bootstrap标签页组件为例,介绍如何编写或者封装一个前端组件,以下是实现效果:
原生的Bootstrap-tab组件主要有html,css组成,开发者使用时,需要写很多代码,不易于使用,对bootstrap-tab封装后,可以更方便地使用,同时提供关闭、增加tab页、指定当前选中页、即使加载等功能,这样组件可以适配更多的场景。
原生bootstrap-tab组件使用可参考https://www.runoob.com/bootstrap/bootstrap-tab-plugin.html
其中官网一段实例代码是:
<ul id="myTab" class="nav nav-tabs">
<li class="active"><a href="#home" rel="external nofollow" data-toggle="tab">
菜鸟教程</a>
</li>
<li><a href="#ios" rel="external nofollow" data-toggle="tab">iOS</a></li>
<li class="dropdown">
<a href="#" rel="external nofollow" id="myTabDrop1" class="dropdown-toggle"
data-toggle="dropdown">Java <b class="caret"></b>
</a>
<ul class="dropdown-menu" role="menu" aria-labelledby="myTabDrop1">
<li><a href="#jmeter" rel="external nofollow" tabindex="-1" data-toggle="tab">
jmeter</a>
</li>
<li><a href="#ejb" rel="external nofollow" tabindex="-1" data-toggle="tab">
ejb</a>
</li>
</ul>
</li>
</ul>
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade in active" id="home">
<p>菜鸟教程是一个提供最新的web技术站点,本站免费提供了建站相关的技术文档,帮助广大web技术爱好者快速入门并建立自己的网站。菜鸟先飞早入行——学的不仅是技术,更是梦想。</p>
</div>
<div class="tab-pane fade" id="ios">
<p>iOS 是一个由苹果公司开发和发布的手机操作系统。最初是于 2007 年首次发布 iPhone、iPod Touch 和 Apple
TV。iOS 派生自 OS X,它们共享 Darwin 基础。OS X 操作系统是用在苹果电脑上,iOS 是苹果的移动版本。</p>
</div>
<div class="tab-pane fade" id="jmeter">
<p>jMeter 是一款开源的测试软件。它是 100% 纯 Java 应用程序,用于负载和性能测试。</p>
</div>
<div class="tab-pane fade" id="ejb">
<p>Enterprise Java Beans(EJB)是一个创建高度可扩展性和强大企业级应用程序的开发架构,部署在兼容应用程序服务器(比如 JBOSS、Web Logic 等)的 J2EE 上。
</p>
</div>
</div>
<script>
$(function () {
$('#myTab li:eq(1) a').tab('show');
});
</script>
那么如何封装或者开发一个组件呢?
组件开发步骤
Step1:结构化静态代码,梳理核心的问题
在组件开发流程中,可能拿到前端设计的静态代码(html+css的组合),这时候要拆解代码结构,使得结构能够模板化。其次梳理核心问题,bootstrap-tab组件化之后,应该能够动态加载tab内容,这个可以通过jquery.load方法解决,这样可以做到主页面和子页面解耦。
读懂了静态代码,理解了结构和核心问题就可以写代码了,首先搭建组件的架子。
Step2:组件骨架
/**
* Bootstrap tab组件封装
* @author billjiang qq:475572229
* @created 2017/7/24
*
*/
(function ($, window, document, undefined) {
'use strict';
var pluginName = 'tabs';
//入口方法
$.fn[pluginName] = function (options) {
var self = $(this);
if (this == null)
return null;
var data = this.data(pluginName);
if (!data) {
data = new BaseTab(this, options);
self.data(pluginName, data);
}
return data;
};
var BaseTab = function (element, options) {
this.$element = $(element);
this.options = $.extend(true, {}, this.default, options);
this.init();
}
//默认配置
BaseTab.prototype.default = {
}
//结构模板
BaseTab.prototype.template = {
}
//初始化
BaseTab.prototype.init = function () {
}
})(jQuery, window, document)
搭建了以上组件的骨架,并对组件命名为tabs,这样就可以通过$("#tab-container").data("tabs")获取组价的方法和属性。在入口方法中,会将初始化后的对象缓存到页面html中,这样可以避免重复创建对象。一些经典的开源前端组件都是这样写法,比如Bootstrap-treeview,大家有时间可以看看它的源码。
以上的写法使用原型链的写法。定义了默认配置,结构模板,初始化入口。
编写代码
在组件的代码骨架里,填充模板代码,这里使用占位符{0},{1}等表示外部传入的变量,然后在init方法中校验外部传入数据的合法性,然后构建组件,并且绑定关闭事件、点击事件。
在开发前端组件的时候,往往不知道默认参数应该有什么,可以在开发的时候,用到就加上去,这里加了两个默认参数,一个showIndex是默认显示的tab页索引,一个loadAlltab是否一次性把所有的页面数据加载完。
具体的逻辑请看下面的代码:
//默认配置
BaseTab.prototype.default = {
showIndex: 0, //默认显示页索引
loadAll: true,//true=一次全部加在页面,false=只加在showIndex指定的页面,其他点击时加载,提高响应速度
}
//结构模板
BaseTab.prototype.template = {
ul_nav: '<ul class="nav nav-tabs"></ul>',
ul_li: '<li><a href="#{0}" rel="external nofollow" data-toggle="tab"><span>{1}</span></a></li>',
ul_li_close: '<i class="fa fa-remove closeable" title="关闭"></i>',
div_content: '<div class="tab-content"></div>',
div_content_panel: '<div class="tab-pane fade" id="{0}"></div>'
}
//初始化
BaseTab.prototype.init = function () {
if (!this.options.data || this.options.data.length == 0) {
console.error("请指定tab页数据");
return;
}
//当前显示的显示的页面是否超出索引
if (this.options.showIndex < 0 || this.options.showIndex > this.options.data.length - 1) {
console.error("showIndex超出了范围");
//指定为默认值
this.options.showIndex = this.default.showIndex;
}
//清除原来的tab页
this.$element.html("");
this.builder(this.options.data);
}
//使用模板搭建页面结构
BaseTab.prototype.builder = function (data) {
var ul_nav = $(this.template.ul_nav);
var div_content = $(this.template.div_content);
for (var i = 0; i < data.length; i++) {
//nav-tab
var ul_li = $(this.template.ul_li.format(data[i].id, data[i].text));
//如果可关闭,插入关闭图标,并绑定关闭事件
if (data[i].closeable) {
var ul_li_close = $(this.template.ul_li_close);
ul_li.find("a").append(ul_li_close);
ul_li.find("a").append(" ");
}
ul_nav.append(ul_li);
//div-content
var div_content_panel = $(this.template.div_content_panel.format(data[i].id));
div_content.append(div_content_panel);
}
this.$element.append(ul_nav);
this.$element.append(div_content);
this.loadData();
this.$element.find(".nav-tabs li:eq(" + this.options.showIndex + ") a").tab("show");
}
BaseTab.prototype.loadData = function () {
var self = this;
//tab点击即加载事件
//设置一个值,记录每个tab页是否加载过
this.stateObj = {};
var data = this.options.data;
//如果是当前页或者配置了一次性全部加载,否则点击tab页时加载
for (var i = 0; i < data.length; i++) {
if (this.options.loadAll || this.options.showIndex == i) {
if (data[i].url) {
$("#" + data[i].id).load(data[i].url);
this.stateObj[data[i].id] = true;
} else {
console.error("id=" + data[i].id + "的tab页未指定url");
this.stateObj[data[i].id] = false;
}
} else {
this.stateObj[data[i].id] = false;
(function (id, url) {
self.$element.find(".nav-tabs a[href='#" + id + "']").on('show.bs.tab', function () {
if (!self.stateObj[id]) {
$("#" + id).load(url);
self.stateObj[id] = true;
}
});
}(data[i].id, data[i].url))
}
}
//关闭tab事件
this.$element.find(".nav-tabs li a i.closeable").each(function (index, item) {
$(item).click(function () {
var href = $(this).parents("a").attr("href").substr(1);
$(this).parents("li").remove();
$("#" + href).parent().remove();
})
});
}
测试
编写一个前端界面,测试组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tab组件</title>
</head>
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css" rel="external nofollow" >
<link rel="stylesheet" href="font-awesome/css/font-awesome.min.css" rel="external nofollow" >
<link rel="stylesheet" href="../css/bootstrap-tab.css" rel="external nofollow" >
<body>
<div id="tabContainer"></div>
</body>
<script src="jquery/jquery-1.8.3.min.js"></script>
<script src="bootstrap/js/bootstrap.min.js"></script>
<script src="../js/bootstrap-tab.js"></script>
<script>
$("#tabContainer").tabs({
data: [{
id: 'home',
text: '百度一下',
url: "tab_first.html",
closeable:true
}, {
id: 'admineap',
text: 'AdminEAP',
url: "tab_second.html"
}, {
id: 'edit',
text: '编辑人员',
url: "tab_content.html",
closeable:true
}],
showIndex:1,
loadAll:false
})
</script>
</html>
通过配置各种参数,看看组件是否满足了预期的要求。
组件在使用的过程中还会遇到各种问题,或者各种需求,比如新增一个tab页面,比如获取当前tab的ID或index,这是可以在代码中按需扩展。
//新增一个tab页
BaseTab.prototype.addTab=function (obj) {
//nav-tab
var ul_li = $(this.template.ul_li.format(obj.id, obj.text));
//如果可关闭,插入关闭图标,并绑定关闭事件
if (obj.closeable) {
var ul_li_close = $(this.template.ul_li_close);
ul_li.find("a").append(ul_li_close);
ul_li.find("a").append(" ");
}
this.$element.find(".nav-tabs").append(ul_li);
//div-content
var div_content_panel = $(this.template.div_content_panel.format(obj.id));
this.$element.find(".tab-content").append(div_content_panel);
$("#" + obj.id).load(obj.url);
this.stateObj[obj.id] = true;
if(obj.closeable){
this.$element.find(".nav-tabs li a[href='#" + obj.id + "'] i.closeable").click(function () {
var href = $(this).parents("a").attr("href").substr(1);
$(this).parents("li").remove();
$("#" + href).parent().remove();
})
}
this.$element.find(".nav-tabs a[href='#" + obj.id + "']").tab("show");
}
//根据id设置活动tab页
BaseTab.prototype.showTab=function (tabId) {
this.$element.find(".nav-tabs li a[href='#" + tabId + "']").tab("show");
}
//获取当前活动tab页的ID
BaseTab.prototype.getCurrentTabId=function () {
var href=this.$element.find(".nav-tabs li.active a").attr("href");
href=href.substring(1);
return href;
}
更完善的bootrap-tab版本已经开源,详见我的Github地址:
bootstrap-tab:https://github.com/bill1012/bootstrap-tab
总结
以上所述是小编给大家介绍的以BootStrap Tab为例写一个前端组件,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
# bootstrap
# tab
# 前端组件
# JS组件Bootstrap Table使用实例分享
# JS组件Bootstrap Table布局详解
# JS表格组件神器bootstrap table详解(强化版)
# JS组件系列之Bootstrap table表格组件神器【二、父子表和行列调序】
# JS组件系列之Bootstrap table表格组件神器【终结篇】
# JS组件Bootstrap Table使用方法详解
# JS表格组件神器bootstrap table详解(基础版)
# JS组件Bootstrap Table表格多行拖拽效果实现代码
# JS组件Bootstrap Table表格行拖拽效果实现代码
# 加载
# 是一个
# 菜鸟
# 绑定
# 开源
# 应用程序
# 苹果公司
# 为例
# 小编
# 加在
# 就可以
# 自己的
# 都是
# 这是
# 有什么
# 操作系统
# 首次
# 在此
# 还会
# 它是
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel Eloquent关联是什么_Laravel模型一对一与一对多关系精讲
桂林网站制作公司有哪些,桂林马拉松怎么报名?
Laravel如何安装使用Debugbar工具栏_Laravel性能调试与SQL监控插件【步骤】
Laravel Eloquent访问器与修改器是什么_Laravel Accessors & Mutators数据处理技巧
Laravel怎么实现支付功能_Laravel集成支付宝微信支付
如何批量查询域名的建站时间记录?
Laravel请求验证怎么写_Laravel Validator自定义表单验证规则教程
Laravel如何使用Collections进行数据处理?(实用方法示例)
php在windows下怎么调试_phpwindows环境调试操作说明【操作】
深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?
Python高阶函数应用_函数作为参数说明【指导】
Laravel的Blade指令怎么自定义_创建你自己的Laravel Blade Directives
如何正确下载安装西数主机建站助手?
EditPlus 正则表达式 实战(3)
Laravel怎么进行数据库事务处理_Laravel DB Facade事务操作确保数据一致性
简单实现Android文件上传
Laravel如何构建RESTful API_Laravel标准化API接口开发指南
高端网站建设与定制开发一站式解决方案 中企动力
如何在阿里云香港服务器快速搭建网站?
Laravel怎么实现验证码功能_Laravel集成验证码库防止机器人注册
极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?
Google浏览器为什么这么卡 Google浏览器提速优化设置步骤【方法】
Laravel如何发送系统通知_Laravel Notifications实现多渠道消息通知
如何选择可靠的免备案建站服务器?
Laravel怎么配置.env环境变量_Laravel生产环境敏感数据保护与读取【方法】
如何在橙子建站上传落地页?操作指南详解
高端智能建站公司优选:品牌定制与SEO优化一站式服务
Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】
如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南
详解ASP.NET 生成二维码实例(采用ThoughtWorks.QRCode和QrCode.Net两种方式)
微信小程序 闭包写法详细介绍
Midjourney怎样加参数调细节_Midjourney参数调整技巧【指南】
Laravel Vite是做什么的_Laravel前端资源打包工具Vite配置与使用
智能起名网站制作软件有哪些,制作logo的软件?
如何在景安服务器上快速搭建个人网站?
零基础网站服务器架设实战:轻量应用与域名解析配置指南
iOS中将个别页面强制横屏其他页面竖屏
Laravel Blade组件怎么用_Laravel可复用视图组件的创建与使用
iOS UIView常见属性方法小结
Laravel数据库迁移怎么用_Laravel Migration管理数据库结构的正确姿势
Laravel如何使用Seeder填充数据_Laravel模型工厂Factory批量生成测试数据【方法】
Windows驱动无法加载错误解决方法_驱动签名验证失败处理步骤
HTML5空格和margin有啥区别_空格与外边距的使用场景【说明】
Laravel项目结构怎么组织_大型Laravel应用的最佳目录结构实践
微博html5版本怎么弄发超话_超话进入入口及发帖格式要求【教程】
PHP正则匹配日期和时间(时间戳转换)的实例代码
logo在线制作免费网站在线制作好吗,DW网页制作时,如何在网页标题前加上logo?
如何为不同团队 ID 动态生成多个独立按钮
活动邀请函制作网站有哪些,活动邀请函文案?
夸克浏览器网页跳转延迟怎么办 夸克浏览器跳转优化

