平时我们要写的项目中如果需要tab选项卡这类的时候,我们不妨可以试试这一种方法,自己随便自定义写出一个tab选项卡,只要懂了,特别简单。下面开始讲解其步骤:分别有上下结构的和左右结构的,其实都差不多,只需更换样式css即可。

我这是在HBuilder上写的,VSCode应该也适用,因为都是vue;

上下结构:

第一步,先写出上面导航的整体布局,比如这样式的:

ios app h5切换 h5 tab切换_scss

 

上面部分的布局可以看成是一个盒子包着两个小盒子,两个小盒子里面的内容就是tab要切换的选项。

html代码如下:

ios app h5切换 h5 tab切换_ios app h5切换_02

 

这是整体布局,然后就是定义我们的样式了,css中定义代码如下:

ios app h5切换 h5 tab切换_ios app h5切换_03

我这是根据不同机型做的适配页面,所以宽度就用了百分比;

active是一个class,动态给标签添加之后就会实现切换到本标签时候显示的样式,所以动态就需要用到vue的数据共享了,js代码如下:

ios app h5切换 h5 tab切换_ios app h5切换_04

 

点击事件实现切换tab动态添加class实现切换的效果,active作为点第几个的标识;

第二步:到这里我们的页面效果就和开头那个动图的效果一样了,接下来我们开始写下面的部分,也是先实现整体布局,比如我这样式的:

ios app h5切换 h5 tab切换_ios app h5切换_05

 

这里是不用循环出结果的那种,大部分项目都是需要循环的,我先在这里示范不循环的。

下面的整体布局可以看成下面整体一个盒子,包着里面需要切换的东西,里面就自己看着写了,我的html代码如下:

ios app h5切换 h5 tab切换_微信小程序_06

使用v-if在搭配上active序号就可以实现点哪个导航栏显示哪个导航栏的内容;

css样式如下:

ios app h5切换 h5 tab切换_uni-app_07

样式基本就是自己按照自己的项目去写了,我这只做参考;

js内容不用动,还是那点就可以了;

这里附上我的全部代码:

 

<template>
<view class="container">
<view class="top">
<view :class="['top-item',active==1?'active':'']" @click="changeNav(1)">已使用</view>
<view :class="['top-item',active==2?'active':'']" @click="changeNav(2)">已失效</view>
</view>
<view class="bottom" v-if="active==1">
<view class="bottom-item">
<view class="bottom-item-kahao">
<view class="bottom-item-kahao-tit">卡号:</view>
<view class="bottom-item-kahao-le">1234567</view>
</view>
<view class="bottom-item-youhui">
<view class="bottom-item-youhui-da">优惠5元</view>
<view class="bottom-item-youhui-xiao">满20减5元</view>
</view>
<view class="bottom-item-status">已使用</view>
</view>
</view>
<view class="bottom" v-if="active==2">
<view class="bottom-item">
<view class="bottom-item-kahao">
<view class="bottom-item-kahao-tit">卡号:</view>
<view class="bottom-item-kahao-le">7654321</view>
</view>
<view class="bottom-item-youhui">
<view class="bottom-item-youhui-da">优惠20元</view>
<view class="bottom-item-youhui-xiao">满50减20元</view>
</view>
<view class="bottom-item-status">已失效</view>
</view>
</view>
</view>
</template>

<script>
export default {
data() {
return {
active:1
};
},
methods:{
changeNav(i){
this.active=i
}
}
}
</script>

<style lang="scss">
.container {
background-color: #fff;
.top {
width: 100%;
display: flex;
.top-item {
width: 50%;
text-align: center;
position: relative;
&.active {
font-size: 18px;
font-weight: 600;
&::before {
content: '';
width: 25%;
height: 2rpx;
background-color: red;
position: absolute;
top: 48rpx;
left: 37%;
}
}
}
}
.bottom{
width: 100%;
.bottom-item{
width: 100%;
border: 2rpx solid #d4d4d4;
background-color: red;
color: #fff;
box-sizing: border-box;
padding: 20rpx 40rpx;
border-radius: 30rpx;
margin-top: 40rpx;
.bottom-item-kahao{
width: 100%;
display: flex;
.bottom-item-kahao-tit{
font-size: 18px;
font-weight: 600;
}
.bottom-item-kahao-le{
font-size: 14px;
}
}
.bottom-item-youhui{
width: 100%;
display: flex;
justify-content: space-between;
margin-top: 30rpx;
.bottom-item-youhui-da{
font-size: 18px;
}
.bottom-item-youhui-xiao{
font-size: 12px;
}
}
.bottom-item-status{
margin-top: 30rpx;
text-align: end;
color: #d4d4d4;
}
}
}
}
</style>

 这个方法主要的思路就是先写出整体布局,然后导航部分通过判断动态添加class类名的方法,切换的内容部分如果不是循环的话就是用v-if判断动态active的序号来显示对应的内容实现切换效果;如果是循环出数据的话,那就简单了,只用写内容的一整个板块,然后通过循环就能直接变换内容实现切换了。

接下来演示左右结构的tab选项卡:

比如我这样式的:

ios app h5切换 h5 tab切换_ios app h5切换_08

首先第一步:

还是先实现左边导航的整体布局:

因为我的导航部分和内容部分都是循环出来的,所以代码较上一个简单了一些;

html代码如下:

ios app h5切换 h5 tab切换_ios app h5切换_09

部分代码看不懂没关系,你只需要知道你项目的导航部分的整体布局就可以了。然后写出来之后在去看动态添加的都需要写在哪里。

我的导航栏的数据都是从cateList数据中循环出来的,稍后我会展示js部分,先来看css样式部分:

ios app h5切换 h5 tab切换_scss_10

这是导航部分的样式,接下来看js部分:

ios app h5切换 h5 tab切换_ios app h5切换_11

data数据共享中的cateList就是我们导航部分的内容了,当然其中也有内容部分的,我们可以把内容部分的赋值到另外一个新的数组中去,让内容部分去循环那个新的数组就可以了。

这个时候就实现了下面这个效果:

ios app h5切换 h5 tab切换_scss_12

然后第二步写右面的内容部分:

html部分:

ios app h5切换 h5 tab切换_微信小程序_13

然后是css样式部分:

ios app h5切换 h5 tab切换_前端_14

js部分和上面一样,因为上面的js部分我截屏之前就是已经写好了的,这个时候我们就已经实现开始的完整tab切换效果了

下面附上代码:

<template>
<view class="container">
<view class="cate-container">
<scroll-view scroll-y :style="{height:h+'px'}" class="cate-left">
<block v-for="(cateItem,i) in cateList" :key="i">
<view :class="['cate-left-item',i===active?'active':'']" @click="changeNav(i)">{{cateItem.name}}
</view>
</block>
</scroll-view>
<scroll-view scroll-y :style="{height:h+'px'}" class="cate-right">
<view class="cate-right-box">
<view class="cate-right-item" v-for="(item,index) in childList" :key="index" @click="goxuan(item)">
<view style="margin: auto;width: 100rpx;margin-top: 40rpx;">
<image :src="item.pimg" mode="" class="tu"></image>
</view>
<view class="zi">{{item.pname}}</view>
</view>
</view>
</scroll-view>
</view>
</view>
</template>

<script>
export default {
data() {
return {
h: 0,
active:0,
cateList:[
{
name:'送礼对象',
children:[
{
pname:'女友',
pimg:'../../static/cate1.png'
},
{
pname:'男友',
pimg:'../../static/cate2.png'
},
{
pname:'朋友',
pimg:'../../static/cate3.png'
},
{
pname:'领导',
pimg:'../../static/cate4.png'
},
{
pname:'同事'
},
{
pname:'长辈'
},
{
pname:'老师'
},
{
pname:'儿童'
}
]
},
{
name:'送礼场景',
children:[
{
pname:'生日'
},
{
pname:'结婚'
},
{
pname:'纪念'
},
{
pname:'乔迁'
},
{
pname:'生子'
},
{
pname:'感谢'
},
{
pname:'圣诞节'
}
]
},
{
name:'送礼分类',
children:[
{
pname:'生鲜专场'
},
{
pname:'厨房用品'
},
{
pname:'美妆护肤'
},
{
pname:'家居家纺'
},
{
pname:'家用电器'
},
{
pname:'时尚箱包'
},
{
pname:'个护清洁'
},
{
pname:'手表配饰'
},
{
pname:'电子数码'
},
{
pname:'健康养生'
},
{
pname:'婴童玩具'
}
]
},
{
name:'送礼预算',
children:[
{
pname:'200-300'
},
{
pname:'300-500'
},
{
pname:'500-1000'
},
{
pname:'1000-2000'
},
{
pname:'2000-5000'
},
{
pname:'5000以上'
}
]
}
],
childList:[]
};
},
methods: {
// 切换导航的处理事件
changeNav: function(i) {
this.active = i
this.childList=this.cateList[i].children
},
goxuan(e){
uni.navigateTo({
url:"../xuanliwu/xuanliwu?name="+e.pname
})
}
},
onLoad() {
const systemInfo = uni.getSystemInfoSync(); //获取设备相关的信息
const systemHeight = systemInfo.windowHeight; //获取设备的页面高度
this.h = systemHeight
this.childList=this.cateList[0].children
}
}
</script>

<style lang="scss">
.container {
font-size: 16px;

.cate-container {
width: 100%;
height: 600rpx;
display: flex;

.cate-left {
width: 120px;

.cate-left-item {
height: 84rpx;
line-height: 84rpx;
padding-left: 12rpx;
background-color: #F7F7F7;
margin-top: 40rpx;

&.active {
background-color: #fff;
font-weight: 600;
font-size: 18px;
}
}
}

.cate-right {
flex: 1;
.cate-right-box{
width: 100%;
display: flex;
flex-wrap: wrap;
.cate-right-item{
width: 30%;
margin-left: 3%;
.tu{
width: 100rpx;
height: 100rpx;
border-radius: 50rpx;
}
.zi{
width: 100%;
text-align: center;
margin-top: 15rpx;
font-size: 14px;
}
}
}
}
}
}
</style>

 思路还是和上面说的一样,导航部分就是通过动态添加类名实现样式更换,通过active来实现点哪个导航,哪个导航的样式发生改变;然后内容部分就是通过循环实现的更换内容,因为cateList中包括着内容部分的数组数据,所以在切换导航时,在导航切换事件里,通过active的序号值判断把cateList的第几个数据的children赋值到新的数组中去。