内容简介:低下头看了看自己的手环。距离自己的flag已经跳票3天了。。。不为什么,因为我懒#滑稽 #滑稽#滑稽
低下头看了看自己的手环。距离自己的flag已经跳票3天了。。。
不为什么,因为我懒#滑稽 #滑稽#滑稽
咳咳,咱们今天进入正题---Tab组件的编写
首先还是先看Tab预览图:
Tab预览图
很简单的功能,很简洁的UI。
首先还是献上Tab html代码和css代码(我css基础不好 各位可以忽略#滑稽)
为了自由度高一点,我们采用 Tab+TabPanel 的方式制作。这种制作方式也是 大部分UI框架的制作方式
Tab-HTML代码
<template> <div class="tab-wrapper"> <div class="tab__header"> <div class="tab__header__item"> <div style="width: 100%;"> <div class="tab__item"> <span>验证码登录</span> </div> <div class="tab__item"> <span>密码登录</span> </div> </div> </div> </div> <div class="tab__content"> <slot></slot> </div> </div> </template>复制代码
Tab- CSS代码
<style scoped> .iconfont { font-size: 1.5rem; } .tab__header { display: flex; } .tab__header__item { margin: 0; } .tab__header__item > div { display: flex; flex-direction: row; white-space: nowrap; transition: transform .3s; } .tab__item { font-size: 1.3rem; cursor: pointer; margin-right: 1rem; flex: 1; text-align: center; } .tab--active > span { border-bottom: 2px solid #1890FF; color: #1890FF; padding-bottom: .5rem; } .tab__header__btn--left { margin-right: .5rem; cursor: pointer; } .tab__header__btn--right { margin-left: .5rem; cursor: pointer; } .tab--panel-wrapper { display: none; } .tab--panel-wrapper--active { display: block !important; } </style> 复制代码
TabPanel代码:
<template> <div class="tab--panel-wrapper" :name="name"> <div class="tab--panel-content"> <slot></slot> </div> </div> </template> <script> export default { name: "ZbTabPanel", props: { name: { //Tab模块名 required: true } } } </script> <style scoped> </style> 复制代码
先开始制作基础功能:Tab切换
Tab切换功能的制作
首先一上来就会出现理解性的问题:
以往我们写Tab 头部写头部的东西,内容写内容的东西。两者分开来写。便于理解
但如果是这种组件套组件的方式,看起来用法简单了不少。但是增加了编写难度
还有一点 ,父组件怎么去控制子组件的显示隐藏情况?
那就一步步来呗。
为了方便便于编写起来好理解。我选择内容插入,头部遍历的方式去制作
<template> <div class="tab-wrapper"> <div class="tab__header" ref="tabHeaderItem"> <div class="tab__header__item"> <div style="width: 100%;"> <div class="tab__item" @click="tabItemClick(item.name,key)" //tab的点击事件 @touchstart="tabItemClick(item.name,key)" //tab的移动端点击事件 v-for="(item,key) in tabList" //循环list :class="{'tab--active':activeTab.index===key}"> //如果当前tabtitle的下标 =已激活的tabtitle下标 <span>{{item.name}}</span> </div> </div> </div> </div> <div class="tab__content" ref="content"> <slot></slot> </div> </div> </template> 复制代码
js方面:
data() { return { tabList: [], //tab标题列表 activeTab: { //已激活的tab信息 index: 0, //下标 name: '' //名称 } } }复制代码
既然是插槽slot,那我们就用点插槽该做的事情 #嘿嘿嘿
于是我在 mounted 函数内,看一下$slot的内容
结果还真的有
不过出现了一个空插槽值。。。但是无关紧要,我们可以加一层空值判断嘛~~
let self = this; //外层新建变量引用this this.$slots.default.forEach((components) => { //循环default内的内容 if (components.tag && components.componentOptions) { //如果子元素tag键&&componentOptions有内容。 self.tabList.push(components.componentOptions.propsData) // 在components.componentOptions这个键内 有propsDate这个属性。我们可以通过这个属性拿到子组件的props值 } }); this.$nextTick(() => { //避免data未更新 this.activeTab = { //给activeTab赋初始值 index: 0, //默认选中第一个 name: this.tabList[0].name //寻找tabList第一个元素 还有他的名字 }; });复制代码
这样切换头部功能实现了。但是底部主体内容无动于衷
所以我们在watch函数内,监听一下activeTab变量的数据变化:
watch: { activeTab(newValue, oldValue) { this.$refs.content.children[oldValue.index].className = "tab--panel-wrapper"; this.$refs.content.children[newValue.index].className = "tab--panel-wrapper--active"; } }复制代码
这样基础内容就大功告成了。
用法参考
<zb-tab> <zb-tab-panel name="验证码登录"> <!--这是验证码登录的内容--> </zb-tab-panel> <zb-tab-panel name="密码登录"> <!--这是密码登录的内容--> </zb-tab-panel> </zb-tab>复制代码
因为name属性不能少 所以是必填
这样一来遇到个问题,我们的tab是用flex编写的。但是如果tab多了横向滚动怎么办?
这里安利一个滴滴出行@ustbhuangyi 开发的滚动组件: better-scroll
首先我们先安装他:
npm install better-scroll --save复制代码
接着在vue组件内引入:
import BScroll from 'better-scroll'复制代码
这里不做过多介绍。所以我们简单使用。详细使用请看文档
_initScroll: function () { new BScroll(this.$refs.tabHeaderItem, { scrollX: true, //是否支持X滚动 bounce: true //是否开启回弹动画 }); }复制代码
挂载函数内
setTimeout(() => { this.$nextTick(() => { //避免data未更新 this._initScroll(); } ) }, 20)复制代码
如果看到行内样式有css动画。说明就挂载成功了
这样遇到了一个小bug。挂载成功是可以。但是无法滚动。如图
经查:是因为他挂载的那个元素,我们写个width:100%。导致他丢失了实际长度。无法挂载。
但是去掉width:100%后,元素始终不会平铺开。会左浮动一样的排列
所以我们为了两种都要,加个props外部控制吧~~
props: { floatLeft: { //是否开启左浮动模式 default: false } }复制代码
html:
<div class="tab__header__item" :style="floatLeft? '': 'width:100%'">复制代码
这样一个不算很完美的tab就完成了。希望制作思想可以帮到大家
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 前端VUE:开发环境搭建
- 【手牵手】搭建前端组件库(一)
- 你的前端知识框架,该如何搭建?
- 前端项目框架搭建随笔---Webpack踩坑记
- 从0搭建前端项目架构-webpack配置
- 【单页面博客从前端到后端】环境搭建
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。