知识点: 布局flex 单选框
获取验证码倒计时: setInterval (第二个例子)
单选: 当前点击的index与该项的index相同则选中;点击多次会有取消的思路是当前点击的index与赋值的不相同,赋值点击index选中;当前点击的index与赋值的相同则取消
多选: 把选中项的selected取反
单选多选若没有对应图片则不现实图片 图片预览
效果图如下:
<!-- wxml -->
<view class="form_wrap">
<form catchsubmit="formSubmit">
<view class="form_item">
<view class="item_left">
<text class="xin">*</text>
<text class="title">姓名</text>
<input class="ipt" placeholder="请输入姓名"></input>
</view>
<view class="right">
</view>
</view>
<view class="form_item">
<view class="item_left">
<text class="xin">*</text>
<text class="title"手机号</text>
<input class="ipt" placeholder="请输入手机号"></input>
</view>
<view class="item_right">
<text class="btn">一键获取</text>
</view>
</view>
<view class="form_item">
<view class="item_left">
<text class="xin">*</text>
<text class="title">验证码</text>
<input class="ipt" placeholder="请输入验证码"></input>
</view>
<view class="item_right">
<text class="btn">获取验证码</text>
</view>
</view>
<!-- 单选 -->
<view class="form_item form_dis">
<view class="item_left">
<text class="xin">*</text>
<text class="title">单选框(单选)</text>
</view>
<view class="item_select">
<view class="select_wrap {{currentIndex === index ? 'active select' : ''}}" wx:for="{{radios}}" wx:key="index" data-index="{{index}}" bindtap="selectRadio">
<image wx:if="{{item.imgurl}}" class="select_img" src="{{item.imgurl}}" mode="widthFix" style="width: 220rpx"></image>
<view wx:if="{{item.imgurl}}" class="select_btn">{{item.title}}</view>
<image wx:if="{{item.imgurl}}" class="zoom" src="../../imgs/zoom.png" data-imgurl="{{item.imgurl}}" bindtap="imgPre"></image>
<view class="noimg" wx:if="{{!item.imgurl}}">{{item.title}}</view>
</view>
</view>
</view>
<!-- 多选 -->
<view class="form_item form_dis">
<view class="item_left">
<text class="xin">*</text>
<text class="title">多选框(多选)</text>
</view>
<view class="item_select">
<view class="select_wrap {{item.selected? 'active select': ''}}" wx:for="{{radioInfo}}" wx:key="index" data-index="{{index}}" data-value="{{item.title}}" bindtap="selectCheck">
<image class="select_img" src="{{item.imgurl}}" mode="widthFix" style="width: 220rpx"></image>
<view class="select_btn">{{item.title}}</view>
<image class="zoom" src="../../imgs/zoom.png"></image>
</view>
</view>
</view>
<!-- 单图上传 -->
<view class="form_item form_dis">
<view class="item_left">
<text class="xin">*</text>
<text class="title">单图上传</text>
</view>
<view wx:if="{{uploadImg[0]}}" class="item_upload">
<image src="{{uploadImg[0]}}" style="width: 220rpx; height:220rpx"></image>
</view>
<view wx:if="{{!uploadImg[0]}}" class="item_upload" bindtap="unploadImg" data-type="1">
<view>+</view>
<view>上传</view>
</view>
</view>
<view class="form_item">
<view class="item_left">
<text class="xin">*</text>
<text class="title">备注</text>
<input class="ipt" placeholder="请输入内容"></input>
</view>
<view class="right">
</view>
</view>
<!-- 底部 -->
<view class="sub_wrap">
<button>提交</button>
</view>
</form>
</view>
/* wxss */
.form_wrap {
padding: 0 24rpx 200rpx 24rpx;
font-size: 28rpx;
color: #333;
box-sizing: border-box;
}
.form_item {
box-sizing: border-box;
height: 96rpx;
padding: 14rpx 0;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid #eaeaea;
}
.form_item .item_left {
display: flex;
}
.form_item .item_left .xin {
color: #f00;
padding-right: 15rpx;
}
.form_item .item_left .title {
font-weight: bold;
width: 200rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.form_item .item_right .btn{
border-radius: 6px;
display: inline-block;
background-color: #2d59df;
width: 160rpx;
height: 60rpx;
text-align: center;
line-height: 60rpx;
font-size: 24rpx;
padding: 0 10rpx;
box-sizing: border-box;
color: #fff;
}
.form_dis {
height: auto;
display: block;
border-bottom: none;
}
.form_dis .item_select {
display: flex;
flex-wrap: wrap;
}
.form_dis .select_btn {
width: 220rpx;
text-align: center;
padding: 11rpx;
background-color: #F3F3F3;
border: 1px solid #F3F3F3;
border-radius: 12rpx;
margin-bottom: 10rpx;
margin-right: 10rpx;
color: #000000;
font-size: 28rpx;
box-sizing: border-box;
display: inline-block;
}
.select_wrap {
border: 1px solid #fff;
position: relative;
margin-top: 20rpx;
display: flex;
flex-direction: column;
}
.select_wrap .select_img{
width: 220rpx;
border-radius: 12rpx;
margin-bottom: 5rpx;
}
.select_wrap .zoom {
width: 50rpx;
height: 50rpx;
position: absolute;
top: 10rpx;
right: 10rpx;
}
.item_upload {
margin-top: 20rpx;
width: 220rpx;
height: 220rpx;
text-align: center;
border-radius: 8rpx;
position: relative;
border: 1px dashed #707070;
}
.item_upload view:nth-child(1) {
margin-top: 55rpx;
display: inline-block;
background-color: #AEC0F5;
border-radius: 50%;
width: 64rpx;
height: 64rpx;
text-align: center;
line-height: 64rpx;
color: #fff;
}
.item_upload view:nth-child(2), .item_upload view:nth-child(3){
font-size: 24rpx;
margin-top: 20rpx;
}
.item_upload view:nth-child(3) {
margin-top: 0;
}
.sub_wrap {
box-shadow: 0 0 5rpx rgba(0, 0, 0, .45);
box-sizing: border-box;
position: fixed;
bottom: 0;
left: 0;
width: 100%;
padding: 20rpx;
background-color: #fff;
z-index: 9;
}
.sub_wrap button {
display: flex;
align-items: center;
justify-content: center;
width: 100%!important;
height: 88rpx;
background-color: #2d59df !important;
color: #fff;
font-size: 28rpx;
border-radius: 50rpx
}
.active {
border: 1px solid #2d59df;
border-radius: 8rpx;
}
.select {
background-color: #F2F5FF;
color: #2D59DF;
z-index: 99;
}
.noimg {
border-radius: 12rpx;
font-size: 28rpx;
background-color: #F3F3F3;
padding: 20rpx 28rpx;
box-sizing: border-box;
display: inline-block;
}
// pages/subscribe/subscribe.js
Page({
/**
* 页面的初始数据
*/
data: {
radioInfo: [
{
imgurl: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201902%2F02%2F20190202155433_rwbcn.thumb.700_0.jpg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1629944542&t=d82e31e005168c3a1fba28f7791a90a5',
title: '选项一',
selected: false
},
{
imgurl: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201902%2F02%2F20190202155433_rwbcn.thumb.700_0.jpg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1629944542&t=d82e31e005168c3a1fba28f7791a90a5',
title: '选项二',
selected: false
},
{
imgurl: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201902%2F02%2F20190202155433_rwbcn.thumb.700_0.jpg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1629944542&t=d82e31e005168c3a1fba28f7791a90a5',
title: '选项三',
selected: false
},
{
imgurl: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201902%2F02%2F20190202155433_rwbcn.thumb.700_0.jpg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1629944542&t=d82e31e005168c3a1fba28f7791a90a5',
title: '选项四',
selected: false
},
{
imgurl: 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201902%2F02%2F20190202155433_rwbcn.thumb.700_0.jpg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1629944542&t=d82e31e005168c3a1fba28f7791a90a5',
title: '选项五',
selected: false
},
],
radios: [
{title: '选项一', selected: false},
{title: '选项二', selected: false},
{title: '选项三', selected: false},
{title: '选项四', selected: false},
{title: '选项五', selected: false},
],
currentIndex: '',
curIndex: '',
currentIndexs: [],
uploadImg: []
},
// 上传图片
unploadImg(e) {
let that = this
if (e.currentTarget.dataset.type == 1) {
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success(res) {
wx.uploadFile({
url: "https://res.liketon.cn/api/Img?type=image&group=fingertip",
filePath: res.tempFilePaths[0],
name: 'file',
success: (res) =>{
let uploadImg = JSON.parse(res.data).data[0];
that.setData({
'uploadImg[0]': uploadImg
})
},
fail(err) {
console.log(err)
}
})
},
fail(error) {
console.log(error)
}
})
} else {
wx.chooseImage({
count: 9,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success(res) {
tips.loading('上传中...');
let tempFilePaths = res.tempFilePaths
for (var i = 0; i < tempFilePaths.length; i++) {
wx.uploadFile({
url: apiUrl.uploadImgUrl,
filePath: tempFilePaths[i],
name: 'file',
success(res) {
that.data.map[e.currentTarget.dataset.id].content.push(JSON.parse(res.data).data[0])
that.setData({
map: that.data.map
})
tips.unloading();
wx.showToast({
title: '成功',
icon: 'success',
duration: 2000
})
}
})
}
}
})
}
},
// 单选
selectRadio(e) {
let {index} = e.currentTarget.dataset
let {currentIndex} = this.data
if(index !== currentIndex) {
this.setData({
currentIndex: index
})
} else {
this.setData({
currentIndex: ''
})
}
},
// 多选
selectCheck(e) {
let {radioInfo} = this.data
console.log(radioInfo)
let {index} = e.currentTarget.dataset
radioInfo[index].selected = !radioInfo[index].selected
this.setData({radioInfo})
},
// 预览
imgPre(e) {
let {imgurl} = e.currentTarget.dataset
let urls = this.data.radioInfo.map(ele => ele.imgurl)
wx.previewImage({
current: imgurl, // 当前显示图片的http链接
urls // 需要预览的图片http链接列表
})
}
})
验证码倒计时
效果图如下
<view class="wrap">
<view class="wrap_item">
<input type="text" placeholder="请输入手机号" bindinput="getInputValue"></input>
<button bindtap="getPhone" size="mini">一键获取</button>
</view>
<view class="wrap_item">
<input class="verif" type="text" placeholder="请输入验证码"></input>
<button disabled="{{disabled}}" bindtap="getVerification" size="mini">{{codemsg}}</button>
</view>
</view>
.wrap_item {
width: 100%;
display: flex;
margin-bottom: 10rpx;
}
.wrap_item button{
width: 210rpx!important;
background-color: #2d59df;
color: #fff;
font-weight: normal;
font-size: 24rpx;
}
// pages/get/get.js
Page({
data: {
phone: '',
code: '',
codemsg: '获取验证码',
disabled: false,
countDown: 10
},
getInputValue(e) {
let phone = e.detail.value
this.setData({phone})
},
validate(phone) {
let res = /^(13[0-9]|14[014-9]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/
if (!res.test(phone)) {
return {result:false,msg:'手机号格式不正确'}
}
return {result:true,msg:''}
},
showToast({title}) {
return new Promise((resolve, reject) => {
wx.showToast({
title,
icon: 'none'
})
})
},
getVerification() {
let {phone} = this.data
let resData = this.validate(phone)
// console.log(resData)
if(!phone) {
this.showToast({title: '手机号为空'})
}
if(!resData.result) {
this.showToast({title: resData.msg})
}
if(resData.result) {
let timer = setInterval(()=> {
this.setData({
disabled: true,
codemsg: this.data.countDown + 's' ,
countDown: --this.data.countDown
})
if(this.data.countDown <= 0) {
clearInterval(timer)
this.setData({
countDown: 10,
codemsg: '获取验证码',
disabled: false
})
}
}, 1000)
}
}
})