做一个点击标签切换的功能,效果如下:
一、已预设的内容:
HTML:
<ul class="tab">
<li @click="index=0" :class="{active:index==0}">平面评选</li>
<li @click="index=1" :class="{active:index==1}">视频评选</li>
<li @click="index=2" :class="{active:index==2}">音频评选</li>
</ul>
<div class="tabContent">
<div v-show="index==0">平面评选内容</div>
<div v-show="index==1">视频评选内容</div>
<div v-show="index==2">音频评选内容</div>
</div>
JS:
data(){
return{
index:0,//默认选中第一个tab标签
}
},
当然也可以酱紫写:
HTML:
<ul class="tab">
<li v-for="(tabs,index) in tabData" @click="current=index" :class="{active:current==index}">{{tabs.name}}</li>
</ul>
<div class="tabContent">
<div v-for="(content,index) in TabContent" v-show="current==index">{{content.content}}{{content.title}}</div>
</div>
JS:
data(){
return{
current:0,//默认选中第一个tab
tabData:[
{id:0,name:"平面评选"},
{id:1,name:"视频评选"},
{id:2,name:"音频评选"}
],
TabContent:[
{id:0,content:"平面评选内容",title:"平面组"},
{id:1,content:"视频评选内容",title:"视频组"},
{id:2,content:"音频评选内容",title:"音频组"},
],
}
},
二、点击标签加载相应标签的内容:
HTML:
<!--导航部分-->
<ul class="nav">
<li v-for="(list,index) in navData" :key="index" @click="navChange(index,list.title)" :class="{hover:active==index}"><b>{{list.name}}</b></li>
</ul>
<!--音频和平面视频的样式不一样,通过v-if来控制显示或隐藏-->
<!--平面和视频内容-->
<ul class="List" v-if="PlaneVideoShow">
<li v-for="(list,id) in listData" :key="id" @click="ToContent(list.orderid)">
<span>编号:{{list.orderid}}</span>
<img :src="list.thumb">
<h6>{{list.tpname}}</h6>
<p>票数:{{list.num}}</p>
<button class="bt01">查看详情</button>
</li>
</ul>
<!--音频内容-->
<ul class="audioList" v-if="AudioShow">
<li v-for="(list,id) in listData" :key="id" @click="ToContent(list.orderid)">
{{list.tpname}}
<p>编号:{{list.orderid}}</p>
</li>
</ul>
<!--下拉加载更多文字-->
<div class="checkmore" v-show="checkmoreInfo">
<div class="" v-if="page < lastPage"><span>向下滑动加载更多</span></div>
<div class="" v-else><span>没有更多了</span></div>
</div>
CSS:
.nav{display:flex;justify-content:space-around;}
.nav li{font-size:1.6rem;line-height:3.6rem;background:#3d349f;color:#fff;position:relative;}
.nav li.hover{background:#7160e7;}
.nav li b{display:block;padding:0 2rem;}
.nav li:before,.nav li:after,.nav li.hover:before,.nav li.hover:after{content:"";display:block;position:absolute;height:100%;width:1rem;top:0;}
.nav li:before{background:url(images/tagLeft.png) no-repeat left top;background-size:100% 100%;left:-1rem;}
.nav li:after{background:url(images/tagRight.png) no-repeat left top;background-size:100% 100%;right:-1rem;}
.nav li.hover:before{background:url(images/tagHoverLeft.png) no-repeat left top;background-size:100% 100%;left:-1rem;}
.nav li.hover:after{background:url(images/tagHoverRight.png) no-repeat left top;background-size:100% 100%;right:-1rem;}
.checkmore{padding:3rem 0;text-align:center;font-size:1.4rem;}
JS:
data(){
return{
loading:true,//加载中(防止ios惯性加载的判断)
active:0,//默认选中第一个tab
group:"图片组",//分组参数默认获取数据
PlaneVideoShow:true,//是否显示视频图片列表
AudioShow:false,//是否显示音频列表
navData:[
{id:0,name:"平面评选",title:"图片组"},
{id:1,name:"视频评选",title:"视频组"},
{id:2,name:"音频评选",title:"音频组"}
],
listData:[],//列表数据
checkmoreInfo:true,//是否显示下滑加载更多文字
page:1,//当前页码
lastPage:"",//列表最后一页
listNum:8,//每页显示数量
}
},
created(){
this.getList(); //获取列表数据
},
mounted(){
//监听页面滚动
window.addEventListener('scroll',this.windowScroll);
},
methods:{
//滚动加载更多
windowScroll(){
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
let clientHeight = document.documentElement.clientHeight || document.body.clientHeight;
let scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
if(scrollTop + clientHeight >= scrollHeight && this.page <= this.lastPage && this.loading == false){
this.loading = true;//ios下拉加载会有惯性请求多次数据,这里通过loading的值来防止多次申请
this.getList();//申请数据
}
},
//获取列表
getList(eventName){
if(eventName != undefined){
this.group = eventName; //设置group参数为当前点击标签页
}
.......参数提交向后端请求数据........
if (response.data.status==1) {
this.listData = this.listData.concat(response.data.data.data);
this.page = response.data.data.current_page + 1;
this.lastPage = response.data.data.last_page;
//console.log("当前页:" + this.page + "最后一页:" + this.lastPage)
if(eventName == "图片组" || eventName == "视频组"){
this.PlaneVideoShow = true;
this.AudioShow = false
}
if(eventName == "音频组"){
this.PlaneVideoShow = false;
this.AudioShow = true
}
.......此段可用于下拉加载更多数据.......
},
//标签切换
navChange(event,eventName){
this.active = event;//设置当前标签
this.page = 1;//重置当前页码
this.lastPage = "";//清空总页码
this.listData = [];//清空数据表
this.getList(eventName);//重新申请当前标签数据
},
},
watch:{
listData(){ //监听listData有数据后执行this.$nextTick(() => {})
var that = this;
this.$nextTick(() => {
that.loading = false; 数据变化时由true改为false,隐藏加载动画,预防ios下滑惯性
})
}
},
//离开时注销监听
beforeDestroy () {
window.removeEventListener('scroll',this.windowScroll);
},
三、三状态切换:
一般用于可选/不可选/选中三种情况:
HTML:
<!--UniApp对应HTML-->
<view class="artiflcerTime mt10">
<text
v-for="(time,index) in timeData"
:key="index"
:class="[time.status?'':'active',{actived:isSelect == index}]" @click="getHourTime(index,time.time,time.status)"
>
{{time.time}}
</text>
</view>
<!--Vue对应HTML-->
<div class="artiflcerTime mt10">
<span
v-for="(time,index) in timeData"
:key="index"
:class="[time.status?'':'active',{actived:isSelect == index}]" @click="getHourTime(index,time.time,time.status)"
>
{{time.time}}
</span>
</div>
Css:
/*view和text标签*/
.artiflcerTime text{display:inline-block;background:#fff;box-shadow:0 0 0.5rem #fdd3c6;width:21.7%;text-align:center;margin:0 0 2% 2.5%;padding:0.5rem 0;border-radius:0.5rem;}
.artiflcerTime text.active{background:#f3f3f3;border:0.1rem solid #f3f3f3;color:#969696;}
.artiflcerTime text.actived{background:#fe7831;color:#fff;border:0.1rem solid #fe7831;}
/*div和span标签*/
.artiflcerTime span{display:inline-block;background:#fff;box-shadow:0 0 0.5rem #fdd3c6;width:21.7%;text-align:center;margin:0 0 2% 2.5%;padding:0.5rem 0;border-radius:0.5rem;}
.artiflcerTime span.active{background:#f3f3f3;border:0.1rem solid #f3f3f3;color:#969696;}
.artiflcerTime span.actived{background:#fe7831;color:#fff;border:0.1rem solid #fe7831;}
JS:
<script>
export default {
data() {
return {
isSelect:"none",//时间段选中
//时间时分数据
timeData:[
{id:0,time:"12:00",status:false},
{id:1,time:"11:00",status:false},
{id:2,time:"12:00",status:true},
{id:3,time:"12:00",status:false},
{id:4,time:"13:00",status:true},
{id:5,time:"12:00",status:true},
{id:6,time:"12:00",status:false},
{id:7,time:"12:00",status:true},
{id:8,time:"12:30",status:true},
{id:9,time:"12:10",status:false},
{id:10,time:"12:00",status:true},
{id:11,time:"8:00",status:true},
{id:12,time:"12:00",status:false},
{id:13,time:"5:30",status:true},
{id:14,time:"12:00",status:false},
{id:15,time:"7:10",status:false},
{id:16,time:"12:00",status:true},
],
}
},
methods: {
//获取时间段
getHourTime(index,time,status){
if(status == true){
this.isSelect = index;
//提交相关数据到服务器
}else{
alert("这个时间段不能选!");
}
},
},
}
</script>
四、更多状态结合:
HTML:
<view class="shadow" v-for="(item,index) in couponItemData" :key="index"
:class="[
{couponYellow:item.category =='A' && item.status ==0},
{couponGreen:item.category =='B' && item.status ==0},
{couponRed:item.category =='C' && item.status ==0},
{couponGray:item.category != 0}
]"
@click="couponUsed(item.id)">
<view class="couInfo">
<view class="couInfoMoney"><text>{{item.money}}</text>元</view>
<text class="cffc5aa">{{item.info}}</text>
<text class="couArea">{{item.area}}</text>
</view>
<view class="couTime">
<view class="couHt">{{item.title}}</view>
<view>有效期:{{item.time}}</view>
</view>
<text class="overdue" v-if="item.status == -1">已过期</text>
<text class="noUsed" v-if="item.status == 0">立即使用</text>
<text class="used iconfont" v-if="item.status == 1">已使用</text>
</view>
CSS:
.couponGray{background:#fff;margin:2rem 0;position:relative;padding:1rem 3rem 1rem 11rem;height:6rem;border-radius:0 0.5rem 0.5rem 0;}
.couInfo{position:absolute;left:0;top:-0.5rem;bottom:-0.5rem;background:#dcdcdc;width:10rem;text-align:center;color:#fff;padding:1rem 0;border-radius:0.5rem;}
.couInfo text{display:block;}
.couInfoMoney text{display:inline-block;font-size:3rem;margin-right:0.3rem;font-weight:bold;}
.cffc5aa{color:#ffc5aa;margin:0.3rem 0;}
.couArea{color:#f1f1f1;}
.couTime{display:flex;flex-wrap:wrap;align-content:space-between;height:100%;color:#969696;}
.couHt{font-size:1.5rem;color:#333;}
.noUsed,.overdue,.used{position:absolute;right:0;top:0;bottom:0;width:1rem;display:flex;align-items:center;border-left:0.1rem dotted #969696;padding:0 1rem;color:#ff7832;font-size:1.3rem;}
.overdue{color:#969696;}
.couponRed .couInfo{background:linear-gradient(to right,#ff8379,#f1383c);}
.couponGreen .couInfo{background:linear-gradient(to right,#14d727,#019e41);}
.couponYellow .couInfo{background:linear-gradient(to right,#ffc044,#ff7832);}
.couponRed .couArea{color:#da0a0a;}
.couponGreen .couArea{color:#086d03;}
.couponYellow .couArea{color:#da510a;}
JS:
data() {
return {
//优惠劵数据
couponItemData:[
{id:0,money:15,area:"【仅限烟台区域】",title:"【7月会员回馈活动】",time:"2021.7.31",info:"下单直接抵扣",status:0,category:"A"},
{id:1,money:5,area:"【仅限烟台区域】",title:"【7月会员回馈活动】",time:"2021.7.31",info:"下单直接抵扣",status:1,category:"B"},
{id:2,money:25,area:"【仅限烟台区域】",title:"【7月会员回馈活动】",time:"2021.7.31",info:"下单直接抵扣",status:-1,category:"C"},
{id:3,money:10,area:"【仅限烟台区域】",title:"【7月会员回馈活动回馈活动回馈活动回馈活动】",time:"2021.7.31",info:"下单直接抵扣",status:0,category:"A"},
{id:4,money:5,area:"【仅限烟台区域】",title:"【7月会员回馈活动】",time:"2021.7.31",info:"下单直接抵扣",status:0,category:"B"},
{id:5,money:25,area:"【仅限烟台区域】",title:"【7月会员回馈活动】",time:"2021.7.31",info:"下单直接抵扣",status:0,category:"C"},
],
}
},
methods:{
//优惠券使用
couponUsed(id){
console.log("当前点击id " + id)
}
}
附::class的使用(官方文档)
1、:class="变量名",一般是直接绑定一个类名
2、:class = "{ 类名:布尔值 }",类名是否存在或者是否赋值取决于布尔值是true还是false。例如:
<div :class="{hover:isActive}">
我是否显示取决于isActive是true还是false
</div>
<li v-for="(list,index) in navData"
:key="index"
@click="navChange(index,list.title)"
:class="{hover:active==index}">
<b>{{list.name}}</b>
</li>
我是否显示取决于active是否与index的值相等
</li>
<!--
:class="{hover:active==index}
一般都会在data中设置active的值为0与index下标开始值一样
通过navChange方法动态更改active的值与index下标一致
-->
3、:class="[isActive?className:otherName,'defaultName']",默认始终将添加defaultName样式(defaultName需要加引号),可以将defaultName去掉,也可以设置className或otherName其中一个未空,className或otherName取值取决于isActive为true或者false。
<div :class="[isActive ? activeClass : '', 'errorClass']">
默认样式errorClass,但是只有在isActive是true时才添加activeClass
</div>
4、:class="[{hover:isActive},isHover?className:otherName,'defaultName']",在数组语法中也可以使用对象语法
<div :class="[{hover:isActive},isHover?className:otherName,'defaultName']">
hover的样式取决于isActive是否为true
isHover如果是true为className如果是false则为otherName
defaultName为默认存在样式,也可以为空或者不写(defaultName需要加引号)
</div>
5、:class="[{hover:isActive},'defaultName']",也可以去去掉三元运算。
<div :class="[{hover:isActive},'defaultName']">
hover的样式取决于isActive是否为true
defaultName为默认存在样式,也可以为空或者不写(defaultName需要加引号)
</div>