uniapp入门级最佳实践(三) | 8月更文挑战

469 阅读3分钟

这是我参与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;
	}
}