Vue 组件封装之 Tab 切换
Vue 组件封装之 tab 切换
- 一、Tab 切换组件
- 二、使用案例
- 三、API 使用指南
- 四、源代码
- 五、总结
一、Tab 切换组件
组件说明:
实现 tab 切换。
效果展示:
实现 tab 切换,改变激活样式,切换到对应的页面
以上 tab 切换功能在前端开发中司空见惯。各种现存的组件也随手拈来。在 Vue 中,有配套的 element-ui 组件,也有 vue-ant-design。
element-ui 中 el-tabs 效果如下:
vue-ant-design 中 a-tabs 效果如下:
但是使用现存组件面临的问题如下
- element-ui 中 el-tabs 使用问题
tab 标签文本没有居中,整体靠左,通过复写样式也不行,因为下面的高亮下划线是通过 JS 动态控制。 - vue-ant-design 中 a-tabs 使用问题
tab 标签文本间的距离太大。
- 基于以上问题,所以打算自己封装一个 tab 组件。
二、使用案例
该组件有两种使用方式。
- 只有一个主页面,切换时更新数据源即可,用法如下。
<template><el-tab defaultKey="1" @on-click="changeTab"><el-tab-panes actKey="1" label="全部"></el-tab-panes><el-tab-panes actKey="2" label="推荐"></el-tab-panes><el-tab-panes actKey="3" label="最新"></el-tab-panes></el-tab><div>只有我一个页面,更新数据源即可</div>
</template>
<script>export default{data(){return{}},methods:{changeTab(item,index){//调数据}}
}
</script>
- 有几个tab,就有几个主页面,切换时切换到不同的页面,用法如下。
<template><el-tab defaultKey="1" @on-click="changeTab"><el-tab-panes actKey="1" label="全部"><div>页面1</div></el-tab-panes><el-tab-panes actKey="2" label="推荐"><div>页面2</div></el-tab-panes><el-tab-panes actKey="3" label="最新"><div>页面3</div></el-tab-panes></el-tab>
</template>
<script>export default{data(){return{}},methods:{changeTab(item,index){//调数据}}
}
</script>
三、API 使用指南
属性 | 说明 | 类型 | 默认值 |
---|---|---|---|
defaultKey | 默认选中的tab | String | 1 |
actKey | 每个tab的唯一key | String | 无 |
label | 每个tab的标题 | String | 无 |
on-click | tab 被选中时触发 | 点击按钮的回调函数 | (e: Object): void |
四、源代码
实现思路
(1) tab 标签文本样式高亮;
(2) tab 下面的下划线调整到相应位置;
(3) tab 对应的内容切换。
- tabs 组件
<template><div><div class="tabs"><div ref="line" class="tab-line"></div><div :class="[activeKey == item.actKey? 'active-tab' : 'tab']" @click="changeTab($event,item,index)" v-for="(item,index) in childList">{{item.label}}</div></div><slot></slot></div>
</template>
<script>let self;export default {name: "ElTab",data(){return {childList:[],activeKey:this.defaultKey,//将初始化tab赋值给activeKeyslideWidth:0}},//获取子组件传过来的激活tabprops:{defaultKey:{type: String,default: "1"}},created(){self = this;},mounted(){//循环tab标签this.childList = this.$children;//设置滑动距离。平分设备宽度this.slideWidth = window.innerWidth/this.childList.length;//设置状态线初始化滑动位置this.$refs.line.style.width = this.slideWidth+"px";},methods:{//切换tab触发事件changeTab:(event,item,index)=>{self.activeKey = item.actKey;self.$refs.line.style.transform = "translateX("+self.slideWidth*index+"px)";self.$refs.line.style.transition = "transform .3s";self.$emit('on-click',item,index);//将切换tab的事件暴露给父组件},//初始化时tab状态设置与相应内容显示updateNav:()=>{self.$children.map((item,index)=>{if(item.actKey == self.activeKey){item.show = true;self.$nextTick(function() {self.$refs.line.style.transform = "translateX("+self.slideWidth*index+"px)";self.$refs.line.style.transition = "transform 0s";});}else {item.show = false;}})}},watch: {//监听当前tab,显示相应内容activeKey() {self.$children.map((item)=>{if(item.actKey == self.activeKey){item.show = true;}else {item.show = false;}})}}}
</script>
<style>.active-tab{color:#158ef3;height: 50px;font-weight: bold;line-height: 50px;font-size: 16px;}.tab{color:#333;height: 50px;line-height: 50px;font-size: 16px;}.tabs{display: flex;justify-content: space-around;align-items: center;height: 50px;border-bottom: 1px solid #f6f6f6;}.tab-line{position: absolute;left: 0;border-bottom: 2px solid #158ef3;height: 50px;}
</style>
- tab-pane 组件
<template><div v-if="show"><slot></slot></div>
</template>
<script>export default {name: "ElTabPanes",data(){return {show: false //初始时将所有内容隐藏}},props:{actKey:{type: String,default: "1"}, label:{type: String,default: ""},},mounted(){this.$parent.updateNav();},}
</script>
五、总结
最后总结一下封装一个 tabs 的核心思路和方法。
1. 设置初始化 tab 标签
在 tab-pane 子组件中将所有的内容隐藏(show 属性设置为 false),在 tabs 父组件内接收由开发者自定义的 activeKey,定义一个方法,将 activeKey与子组件的 actKey 比较,如果相同,则该 tab 为初始化时激活的 tab 标签,将相应 tab 的 show 属性设置为 true,并修改 tab 样式。该方法在 tab-pane 子组件中调用。
将 tab-pane 子组件中所有的开发者添加的内容隐藏:
tabs 父组件提供的方法:
tab-pane 子组件调用:
- tabs 组件内部循环 tab-pane 子组件的标签。接收 activeKey,点击时将 tab-pane 子组件的 actKey 赋值给 activeKey。然后每个 tab 的样式通过当前 activeKey 与 actKey 比较,判断是否是当前 tab 标签。如果是,则样式设置为激活样式。
<div :class="[activeKey == item.actKey? 'active-tab' : 'tab']" @click="changeTab($event,item.actKey,index)" v-for="(item,index) in childList">{{item.label}}</div>changeTab:(event,tab,index)=>{self.activeKey = tab;self.$refs.line.style.transform = "translateX("+self.slideWidth*index+"px)";self.$refs.line.style.transition = "transform .3s";self.$emit('on-click',event,tab)},
- 在 tab-pane 上方添加状态线,状态线的样式需要注意一下。
<div ref="line" class="tab-line"></div>.tab-line{height: 2px;background: #409eff;position: absolute;left: 0;margin-top: 20px;}
- 切换 tab 时,改变相应的内容。
这一步最关键,需要在 tabs 组件中使用 watch 监听当前状态,如果子组件中的 actKey 等于当前状态,则显示相应的内容。
activeKey() {self.$children.map((item)=>{if(item.actKey == self.activeKey){item.show = true;}else {item.show = false;}})}
Vue 组件封装之 Tab 切换相关推荐
- 本篇文章使用vue结合element-ui开发tab切换vue的不同组件,每一个tab切换的都是一个新的组件。
本篇文章使用vue结合element-ui开发tab切换vue的不同组件,每一个tab切换的都是一个新的组件. 1.vue如何使用element-ui 上一篇文章已经分享了如何在vue中使用eleme ...
- Vue组件封装,(面试回答)
在我用vue开发项目的时候,一般我都会用到组件封装,采用组件化的思想进行项目开发,我在搭建一个项目的时候,就会创建一个views目录和一个commen目录和一个feature目录,views目录中放页 ...
- Vue组件封装 (面试必问)
先说一下vue组件封装的优点 组件(Component)是Vue.js最强大的功能之一 组件可以扩展HTML元素, 封装可重用代码 组件是可复用的Vue 实例 组件可以提升整个项目的开发效率.能够把页 ...
- vue组件封装技巧,如何对vue模块进行功能封装
如何对vue模块进行功能封装,vue组件封装技巧 当业务不断累加,导致原本干净整洁的代码越来越冗余,各种变量和注释已经让他人望而却步,往往又苦于重构带来的成本,导致诞生很多巨石应用.与其让自己或他人面 ...
- Vue 组件封装之 ScrollView 上拉加载更多
Vue 组件封装之 ScrollView 上拉加载更多 一.ScrollView 上拉加载更多 二.使用案例 三.API 使用指南 四.源代码 一.ScrollView 上拉加载更多 组件说明: 实现 ...
- Vue 组件封装之 Questionnaire 问卷调查
Vue 组件封装之 Questionnaire 问卷调查 前言 一.Questionnaire 组件 二.使用案例 三.API 使用指南 四.源代码 前言 问卷调查表也是目前前端比较常见的开发项目,目 ...
- Vue 组件封装之 Content 列表(处理多行输入框 textarea)
Vue 组件封装之 Content 列表 一.Content 列表 二.使用案例 三.API 使用指南 四.源代码 一.Content 列表 组件说明: 实现 Content 列表布局排版. 效果展示 ...
- Vue 组件封装之 List 列表
Vue 组件封装之 List 列表 一.List 列表 二.使用案例 三.API 使用指南 四.源代码 一.List 列表 组件说明: 实现 List 列表布局排版. 效果展示: 实现的功能: 在一个 ...
- Vue 组件封装之 Search 搜索
Vue 组件封装之 Search 搜索 一.Search 组件 二.使用案例 三.API 使用指南 四.源代码 一.Search 组件 组件说明: 实现搜索功能. 效果展示: input 输入框背景铺 ...
最新文章
- 谈一谈我对AI项目落地的看法
- TensorFlow的基础概念03
- java book打印机_Java调用打印机进行打印
- SQLserver分页 高效率
- 使用sortable插件实现列表中表项的拖曳排序操作8-3
- 奥巴马经济顾问:哪怕丢了“饭碗”,也必须加大投资AI!
- python仿真智能驾驶_基于Python的3R机器人运动仿真
- 《走遍中国》珍藏版(九)
- Java 8日期时间API教程:LocalDateTime
- Android开发日记(六)
- 在线编辑ewebeditor
- Foxmail配置IMAP账号
- 【影视APP】分享一个影视APP源码
- WIN11映射NAS网络驱动器提示 用户名和密码错误
- SAP跨公司销售经典场景
- opencv 打开摄像头
- KMP(字符串匹配)+字符串哈希
- 关于数据恢复,记一次修复SD卡 RAW 之后的修复过程
- 数据结构基本英语词汇
- 视频通话和直播技术webRTC和RTMP探究