这是我参与8月更文挑战的第20天,活动详情查看:8月更文挑战
一、tab切换
这里写的是tab页名字不一样,但是内容差不多,只是展示的切换后的标题栏状态不一样而已,内容还是同一个,如果每个内容都不一样,推荐用uniapp自带的,或者mui里的插件。
<view class="headNavBox flex">
<view class="headNavItem" v-for="item,index in navList" :key="index" @click="changeTab(index)">
<view class="headNavTitle">{{item.title}}</view>
<view :class="navIdx===index ? 'activeTab' : ''" :style="{'margin-left': item.marginLeftNavBottom + '%' }"></view>
</view>
</view>
<view class="dataItem" v-for="item,index in dataList" :key="index"> {{item.name}}
</view>
js:
data() {
return {
navIdx: 0,
navList: [
{
title: '全部的',
marginLeftNavBottom: 38,//这个是写死的,自己调样式看多大合适
state: ''
},{
title: '待处理',
marginLeftNavBottom: 38,
state: 2
},{
title: '处理中',
marginLeftNavBottom: 38,
state: 3
},{
title: '已结束',
marginLeftNavBottom: 38,
state: 4
}
],
dataList: [] }
},
methods: {
//切换tab页
changeTab(idx) {
this.navIdx = idx;
let state = this.navList[idx].state;
this.searchList(state);//state是状态调接口需要的
}
}
css:
.flex {
display: flex;
}
.headNavBox {
width: 100%;
height: 80rpx;
background: #FFFFFF;
}
.headNavItem {
width: 33%;
text-align: center;
line-height: 74rpx;
}
.headNavTitle {
font-size: 28rpx;
color: #222222;
}
.activeTab {
width: 46rpx;
height: 6rpx;
background-image: linear-gradient(to right, #1eaf7b , #c7e2ac);
background-size: 100% 100%;
background-repeat: no-repeat;
}
导航栏的tab里写死了marginLeftNavBottom是因为不太需要动态计算,因为是固定的,只要在开发的时候看哪个位置是居中的就可以了。
二、form表单使用
这里主要写的是单选和多选框的使用,当时看着文档写了半个小时也没写对,感觉有点难理解。。。我这里开发的是类似做题目的项目,所以这里记录一下难点:
单选框:
<view class="questionItem" v-for="item,index in questionList">
<radio-group @change="changeCheck" :data-idx='index'>
<label class="uni-list-cell uni-list-cell-pd flex" v-for="(temp,jdx) in item.surveyOptionList" :key="jdx">
<view>
<radio :value="temp.optionId" color='#19AD78' :checked="temp.optionId == item.checkVal" :disabled="flag==2" />
</view>
<view>{{temp.sorting}}.{{temp.optionName}}</view>
</label>
</radio-group>
</view>
js:
changeCheck: function(evt) {
let idx = evt.target.dataset.idx;
this.questionList[idx].checkVal = evt.detail.value;
}
这个组件当时以为要设置name一直才会实现单选,原来在里就会自动单选,不会影响其他的,但是这里的change事件只能拿到当前的,拿不到里面选择了第几个选项,这就挺鸡肋的,但是我后来也没因为这个问题写不下去,也用不到了。
在用了data-index,方便下面写change事件的时候赋值,看文档那种写法,不好给这种数组类型的赋值。
单选框和多选框都差不多,就把组件名称换下就好了,连change事件都可以用一样的
三、生成二维码
动态生成二维码,用的是uni-Cloud里开源的插件,找了好几个,发现这个最好用,uni-cloud里可以直接用Hbuilder X导入组件,一键导入真的太方便了,但是这个有点问题,小程序正常展示,但是H5上面要调用第二次才展示,不知道是不是就我遇到了这个问题。
<view class="qrImg">
<tki-qrcode
ref="qrcode"
:val="val"
:size="size"
:unit="unit"
:iconSize="iconsize"
:lv="lv"
:onval="onval"
:loadMake="loadMake"
:showLoading="showLoading"
:loadingText="loadingText" />
<view class="appointmentInfoSubTxt" @click="scanImg()">刷新二维码</view>
</view>
<script>
import tkiQrcode from "@/components/tki-qrcode/tki-qrcode.vue";
export default {
components: {
tkiQrcode,
},
data() {
return {
//下面是二维码用到的参数
qrCode:"",
val: '',
size: 200,
iconsize: 30,
lv: 3,
onval: true,
unit: 'rpx',
loadMake: true,
showLoading: true,
loadingText: '二维码生成中'
}
},
methods: {
//生成二维码
scanImg(flag='') {
let _this = this;
this.$utils.requestFun('/getCode',{
token: getApp().globalData.token
},'GET').then(res=> {
if(res.data.data && res.data.data != '') {
_this.val = res.data.data;
// #ifdef H5
if(flag == '') {
this.scanImg(1);//H5情况下要点两次才能出来二维码,很奇怪,所以多调用一次
}
// #endif
}
});
}
}
}
</script>
这里只要把Val赋值就可以了,然后因为只有H5的平台上出现要调用两次才会生成二维码的问题,我就加了一个变量并且判断是否在H5平台上,不然就调用一次即可。
四、定时器轮询
这个轮询就是在二维码的基础上进行开发的,需求是这个页面要一直调用接口,判断二维码是否被扫描过,一秒钟调用一次,如果扫描后就弹框提示,否则就一直调用接口,如果出页面就关闭定时器,所以在上面的代码加上一个searchTime: null的变量,然后在生成二维码接口的地方调用一个轮询的方法就行了,然后在生命周期里移除定时器:
searchTimer: null //轮询
methods: {
//轮询查询二维码是否打开
invertalSearch() {
let _this = this;
this.searchTimer = setInterval(()=> {
_this.searchState();//调用接口的方法,这里就不具体展示了
},1000)
}
},
//这两个方法的格式一定要这样写,不然在H5里没用!不知道为啥,解决了好久才知道是这个问题!
onHide: function() {
if(this.searchTimer) {
clearInterval(this.searchTimer);
this.searchTimer = null;
}
},
//页面卸载
onUnload: function() {
if(this.searchTimer) {
clearInterval(this.searchTimer);
this.searchTimer = null;
}
}