- 微信小程序中使用bindtap绑定带参函数
原生小程序中无法直接使用bindtap="jumpLive(id)"
,需在view标签中写入自定义属性。
wxml:
<view bindtap="jumpLive" data-id="{{roomId}}"></view>
js:
jumpLive:function(event){
var roomId = event.currentTarget.dataset.id
}
-
微信小程序生命周期
①App() 必须在 app.js 中调用,必须调用且只能调用一次。
②onLaunch
:初始化小程序时触发,全局只触发一次;onShow
:小程序初始化完成或用户从后台切换到前台显示时触发;onHide
:用户从前台切换到后台隐藏时触发;onError
:小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息。 -
小程序页面的生命周期
①加载-显示-隐藏-卸载。
②onLoad
:监听页面加载,onReady
:监听页面初次渲染完成,onShow
:监听页面显示,onHide
:监听页面隐藏,onUnload
:监听页面卸载。 -
总结
①先执行小程序周期函数,后执行页面周期函数触发;但有时页面的onLoad
函数会比小程序app的onLaunch
生命周期函数先调用。
②解决上诉问题的方法:在Page页面定义回调函数。
App({
onLaunch:function(){
wx.request({
url: 'test.php',
succrss:(res)=>{
this.globalData.employId = res.employId;
//由于这里是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
if (this.employIdCallback){
this.employIdCallback(employId);
}
}
})
},
globalData: {
employId: ''
}
});
//获取应用实例
const app = getApp()
Page({
data:{},
onLoad:function(){
//判断是用户是否执行完了请求,绑定了信息
if (app.globalData.employId && app.globalData.employId != '') {
//执行操作
}else{
//由于请求是网络请求,可能会在Page.onLoad后才返回
//所以加入callback 防止这种情况
app.employIdCallback = employId =>{
if(employId!=''){
//执行操作。。
}
}
}
})
-
微信小程序wx:for属性
①wx:for
在组件上使用 wx:for 控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。
②默认数组的当前项的下标变量名默认为 index,数组当前项的变量名默认为 item。
③使用wx:for-item
可以指定数组当前元素的变量名,使用wx:for-index
可以指定数组当前下标的变量名。 -
自动排版属性
white-space: pre-line; -
微信原生底部弹窗
wxml:
<view class="m-modals {{isModalShow ? 'z-show' : ''}}">
<view class="mask" catchtap="hideModal"></view>
<view class="ct">
<view class="top">
<view class="title">开通会员</view>
<view class="icon-right iconfont iconguanbi" bindtap="hideModal"></view>
</view>
<view class="content">
<view class="item">
<view class="iconfont iconyonghu"></view>
<input class="txt" placeholder="请输入您的姓名" bindinput="changeName"></input>
</view>
<view class="item">
<view class="iconfont iconshoujihaoma"></view>
<input class="txt" placeholder="请输入手机号码" bindinput="changeMobile"></input>
</view>
<view class="contract"><text class="txt">会员有效期:</text><text class="num"> {{item.expire}}天</text></view>
<view class="contract"><text class="txt">合计支付:</text><text class="num"> {{item.price}}元</text></view>
<checkbox class="s-checkbox">已阅读并同意《<text class="agreement" bindtap="jumpAgreement">会员服务协议</text>》</checkbox>
<view class="btn" bindtap="paidMoney" data-id="{{item.mr_id}}">
<view class="txt">立即支付</view>
</view>
</view>
</view>
</view>
js:
data:{
isModalShow: false,
},
showModal: function() {
this.setData({
isModalShow: true,
})
},
hideModal: function() {
this.setData({
isModalShow: false,
})
},
css:
.m-modals {
position: fixed;
z-index: 5;
width: 100%;
height: 100%;
box-sizing: border-box;
top: 100%;
left: 0;
}
.m-modals>.mask {
position: absolute;
width: 100%;
height: 100%;
box-sizing: border-box;
background-color: rgba(0, 0, 0, 0.4);
}
.m-modals>.ct {
position: absolute;
bottom: -640rpx;
left: 0;
width: 100%;
box-sizing: border-box;
background-color: #fff;
height: 640rpx;
transition: all 0.4s ease;
border-radius: 20rpx 20rpx 0px 0px;
overflow: hidden;
padding: 36rpx 25rpx 33rpx 25rpx;
}
.m-modals.z-show {
top: 0;
}
.m-modals.z-show>.ct {
bottom: 0
}
- 微信支付
微信支付
xwml:
<view class="ct">
<view class="top">
<view class="title">开通会员</view>
<view class="icon-right iconfont iconguanbi" bindtap="hideModal"></view>
</view>
<view class="content">
<view class="item">
<view class="iconfont iconyonghu"></view>
<input class="txt" placeholder="请输入您的姓名" bindinput="changeName"></input>
</view>
<view class="item">
<view class="iconfont iconshoujihaoma"></view>
<input class="txt" placeholder="请输入手机号码" bindinput="changeMobile"></input>
</view>
<view class="contract"><text class="txt">会员有效期:</text><text class="num"> {{item.expire}}天</text></view>
<view class="contract"><text class="txt">合计支付:</text><text class="num"> {{item.price}}元</text></view>
<checkbox class="s-checkbox">已阅读并同意《<text class="agreement" bindtap="jumpAgreement">会员服务协议</text>》</checkbox>
<view class="btn" bindtap="paidMoney" data-id="{{item.mr_id}}">
<view class="txt">立即支付</view>
</view>
</view>
</view>
js:
const api = require('../../../utils/api.js');
const util = require('../../../utils/util.js');
const HOST = require('../../../utils/host.js');
const ajax = util.ajax;
Page({
data: {
HOST: HOST,
real_name: '',
mobile: '',
member_rank_id: '',
user_id: '',
loading: false,
},
paidMoney: function(e) {
var vm = this;
if (!vm.data.real_name && !vm.data.mobile) {
wx.showToast({
title: '请填写完整信息',
icon: 'none'
})
return false;
}else if (!vm.data.isCheck) {
wx.showToast({
title: '请阅读会员服务协议',
icon: 'none'
})
return false;
}
var paidData = {
user_id: vm.data.user_id,
member_rank_id: e.currentTarget.dataset.id,
real_name: vm.data.real_name,
mobile: vm.data.mobile,
};
vm.setData({
loading: true,
})
ajax({
url: api.paidMemberMoney,
data: paidData,
success: function(res) {
var receiveData = res.retval.wxPayData;
var obj = {
appId: receiveData.appId,
nonceStr: receiveData.nonceStr,
package: receiveData.package,
paySign: receiveData.paySign,
signType: receiveData.signType,
timeStamp: receiveData.timeStamp,
}
wx.requestPayment(obj);
},
complete: function() {
vm.setData({
loading: false,
})
wx.stopPullDownRefresh()
}
})
}
}
- 实现微信轮播图的点在图片外面
<view class="m-banner">
<swiper indicator-dots="{{true}}" indicator-color="#DBDBDB" autoplay="{{true}}" interval="3000" duration="2000">
<block wx:for="{{banner}}" wx:key="{{index}}" wx:if="{{banner.length}}">
<swiper-item>
<view class="wrap" data-url="" bindtap="urlOpenType">
<image class="image" src="{{item}}" mode="widthFix" lazy-load></image>
</view>
</swiper-item>
</block>
</swiper>
</view>
.m-banner {
position: relative;
margin-bottom: 30rpx;
width: 700rpx;
height: 350rpx;
border-radius: 10rpx;
margin: 29rpx auto 57rpx;
}
.m-banner swiper{
width: 700rpx;
height: 350rpx;
}
.m-banner .wrap {
position: relative;
width: 700rpx;
height: 300rpx;
background: #E3E3E3;
overflow: hidden;
}
.m-banner .wrap .image {
border-radius: 10rpx;
width: 700rpx;
height: 300rpx;
}
.m-banner .wx-swiper-dot {
width: 31rpx;
height: 13rpx;
border-radius: 0;
transform: skew(-30deg);
background: transparent;
}
.m-banner .wx-swiper-dot-active {
background: #CFA471;
}
- 按游览器设置某个盒子的高度/tabs案例
<scroll-view class="level-nav" scroll-x="{{true}}" show-scrollbar="{{false}}" scroll-into-view="{{scrollInto}}">
<view class="uni-tab-item" wx:for="{{levelList}}" wx:key="{{index}}" data-current="{{index}}" bindtap="ontabtap">
<text class="uni-tab-item-title {{status == index? 'uni-tab-item-title-active' : ''}}">{{ item.rank_name }}</text>
</view>
</scroll-view>
<swiper current="{{status}}" class="swiper-box" style="flex: 1;height:{{contentHeight}}rpx" duration="200" bindchange="ontabchange">
<scroll-view class="level-list" scroll-y="{{true}}" style="height:{{contentHeight}}rpx;">
</scroll-view>
</swiper>
onLoad: function() {
var vm = this;
var height = wx.getSystemInfoSync().windowHeight; //height为可用区域高 单位px
var windowHeight = height * (750 / wx.getSystemInfoSync().windowWidth); //将px转为rpx
this.setData({
//contentHeight = 总高度 - 除了swiper的其他内容的高度
//我这里是减去了除了swiper的其他三块内容的高度,算出了剩余多少高度
contentHeight: windowHeight - 480
});
},
- swiper组件tabs页中的底部弹窗只能遮罩当前tab页的解决方法:
把按钮和弹窗移到swiper外面,利用js设置需要的值,(接上)。
switchTab: function(index) {
var vm = this;
if (vm.data.status === index) {
return;
}
vm.setData({
status: index,
scrollInto: vm.data.levelList[index].id,
priceMessage:{
price: vm.data.levelList[index].price,
expire:vm.data.levelList[index].expire,
mr_id:vm.data.levelList[index].mr_id,
}
})
},
ontabchange: function(e) {
var index = e.target.current || e.detail.current;
this.switchTab(index);
},
getMemebrRankList: function() {
var vm = this;
ajax({
url: api.getMemebrRankList,
success: function(res) {
var isList = res.retval.member_rank_list;
vm.setData({
levelList: isList,
priceMessage: {
price: isList[0].price,
expire: isList[0].expire,
mr_id: isList[0].mr_id,
}
})
}
})
},
- 页面传参和获取参数 (双向显示例子)
A到B页面wxml代码:
A:
<navigator url="/pages/agency/publishForm/homeOwnerList/homeOwnerList?id={{selectAgency.user_id}}" hover-class="none" open-type="navigate">
</navigator>
B:
<radio-group bindchange="radioChang">
<radio value="{{item.user_name+','+item.user_id}}" checked="{{activeId==item.user_id}}">
</radio>
</radio-group>
A到B页面JS代码:
A:得到B页面存储在缓存的'userMsg'
data:{
selectAgency: {}, //选择房东
},
onShow: function () {
const vm = this
let _selectAgency = wx.getStorageSync('userMsg')
if (_selectAgency) {
vm.setData({
selectAgency: _selectAgency
})
}else{
vm.setData({
selectAgency:''
})
}
setTimeout(() => {
wx.removeStorageSync('userMsg')
}, 500);
},
B:获取A传来的id,且在选择后保存'userMsg'
data: {
activeId: "",// 获取上一个页面的id
},
onLoad: function (options) {
const vm = this
vm.setData({
activeId: options.id,//在onload里获取上一个页面的,options就相当于react的props.
})
},
radioChang: function (e) {
const vm = this
let _value = e.detail.value
var arr = _value.split(',')
var obj = {
user_name: arr[0],
user_id: arr[1]
}
wx.setStorageSync('userMsg', obj)//在缓存中存储userMsg
setTimeout(() => {
wx.navigateBack()
}, 400);
},
- checkbox样式修改
checkbox .wx-checkbox-input {
width: 30rpx !important;
height: 30rpx !important;
border: 2px solid #F8AD8F !important;
}
checkbox .wx-checkbox-input.wx-checkbox-input-checked {
color: #fff;
background: #F8AD8F;
}
- 微信轮播
<swiper>
之完美衔接
<swiper circular="{{true}}"><swiper>
- 两个box嵌套圆角上方显示脏颜色的解决方法
设置相对定位及绝对定位,向上走4rpx,下方的box也要设置绝对定位。
.m-card {
position: relative;
bottom: 66rpx;
left: 28rpx;
height: 362rpx;
width: 700rpx;
background-color: #0A76FC;
border-radius: 20rpx;
}
.m-card .g-top {
position: absolute;
top: -5rpx;
padding: 45rpx 35rpx 30rpx 30rpx;
box-sizing: border-box;
width: 700rpx;
height: 300rpx;
background: rgba(255, 255, 255, 1);
border-radius: 20rpx;
overflow: hidden;
}
.m-card .g-top .title {
font-size: 36rpx;
font-family: PingFang SC;
font-weight: bold;
color: rgba(10, 118, 252, 1);
}
.m-card .g-top .decs {
font-size: 24rpx;
font-family: PingFang SC;
font-weight: 500;
color: rgba(145, 145, 145, 1);
line-height: 40rpx;
margin-top: 48rpx;
}
.m-card .g-bottom {
position: absolute;
bottom: 0;
width: 100%;
display: flex;
justify-content: space-between;
box-sizing: border-box;
padding: 15rpx 27rpx 17rpx 30rpx;
}
.m-card .g-bottom .price {
font-size: 28rpx;
font-family: PingFang SC;
font-weight: 500;
color: rgba(255, 255, 255, 1);
}
.m-card .g-bottom .g-right {
font-size: 26rpx;
font-family: PingFang SC;
font-weight: 500;
color: rgba(255, 255, 255, 1);
}
.m-card .g-bottom .g-right image {
width: 26rpx;
height: 26rpx;
}
- 不适用scroll-view的纯手写tabs页
★此处case-list中加入overflow:hidden会出现特别有趣的脏颜色。
<view class="m-tabs">
<view class="item {{current == 0?'selected':''}}" data-index="0" bindtap="changeTabs">
<view>全部</view>
<view class="num">50</view>
</view>
<view class="item {{current == 1?'selected':''}}" data-index="1" bindtap="changeTabs">
<view>APP</view>
<view class="num">50</view>
</view>
<view class="item {{current == 2?'selected':''}}" data-index="2" bindtap="changeTabs">
<view>小程序</view>
<view class="num">50</view>
</view>
<view class="item {{current == 3?'selected':''}}" data-index="3" bindtap="changeTabs">
<view>软件系统</view>
<view class="num">50</view>
</view>
<view class="item {{current == 4?'selected':''}}" data-index="4" bindtap="changeTabs">
<view>微官网</view>
<view class="num">50</view>
</view>
<view wx:if="{{iconList}}" class="iconfont iconliebiao1 icon-size" bindtap="changeList"></view>
<view wx:else class="iconfont iconliebiao icon-size" bindtap="changeList"></view>
</view>
<view class="m-case" wx:if="{{iconList}}">
<view class="list-box">
<view class="case-list">
<view class="g-top"></view>
<view class="g-bottom">
<view class="title">买买社区团购商城</view>
<view class="praise">
<image src="../../images/love_grey.png"></image><text>100</text>
</view>
</view>
</view>
<view class="case-list">
<view class="g-top"></view>
<view class="g-bottom">
<view class="title">买买社区团购商城</view>
<view class="praise">
<image src="../../images/love_grey.png"></image><text>100</text>
</view>
</view>
</view>
<view class="case-list">
<view class="g-top"></view>
<view class="g-bottom">
<view class="title">买买社区团购商城</view>
<view class="praise">
<image src="../../images/love_grey.png"></image><text>100</text>
</view>
</view>
</view>
<view class="case-list">
<view class="g-top"></view>
<view class="g-bottom">
<view class="title">买买社区团购商城</view>
<view class="praise">
<image src="../../images/love_grey.png"></image><text>100</text>
</view>
</view>
</view>
</view>
</view>
<view wx:else>
</view>
.m-tabs {
display: flex;
margin: 0 0 26rpx 0;
}
.m-tabs .item {
display: flex;
justify-content: center;
align-items: center;
flex-flow: column nowrap;
min-width: 18%;
text-align: center;
font-size: 26rpx;
font-family: PingFang SC;
font-weight: 500;
color: rgba(169, 224, 255, 1);
}
.m-tabs .num {
text-align: center;
line-height: 30rpx;
width: 60rpx;
height: 30rpx;
background: rgba(14, 105, 218, 1);
border-radius: 15rpx;
margin-top: 10rpx;
}
.m-tabs .icon-size {
position: relative;
top: 20rpx;
right: -10rpx;
color: #fff;
font-size: 36rpx;
}
.m-tabs .selected {
font-size: 30rpx;
font-family: PingFang SC;
font-weight: 500;
color: rgba(255, 254, 254, 1);
}
.m-tabs .selected .num {
text-align: center;
line-height: 30rpx;
width: 60rpx;
height: 30rpx;
border: 2rpx solid rgba(255, 255, 255, 1);
border-radius: 15rpx;
margin-top: 10rpx;
}
.m-case {
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
margin-bottom: 200rpx;
}
.m-case .list-box {
display: flex;
flex-flow: row wrap;
align-items: center;
justify-content: center;
}
.m-case .case-list {
position: relative;
margin-left: 18rpx;
margin-bottom: 19rpx;
min-width: 40%;
width: 340rpx;
height: 584rpx;
background: #fff;
border-radius: 20rpx;
}
.m-case .case-list .g-top {
position: absolute;
top: -4rpx;
width: 340rpx;
height: 460rpx;
background: rgba(223, 223, 223, 1);
border-radius: 20rpx;
}
.m-case .case-list .g-bottom {
position: absolute;
bottom: 0;
width: 100%;
margin: 23rpx 0 25rpx 0;
text-align: center;
}
.m-case .case-list .g-bottom .title {
font-size: 28rpx;
font-family: PingFang SC;
font-weight: 500;
color: #0A76FC;
margin-bottom: 0;
}
.m-case .case-list .g-bottom .praise {
display: flex;
align-items: center;
justify-content: center;
margin-top: 15rpx;
font-size: 26rpx;
font-family: PingFang SC;
font-weight: 500;
color: rgba(208, 208, 208, 1);
}
.m-case .case-list .g-bottom .praise image {
width: 26rpx;
height: 26rpx;
margin-right: 11rpx;
}
data: {
current: 0,
iconList: true
},
/**
* 组件的方法列表
*/
methods: {
changeTabs: function(e) {
var _current = e.currentTarget.dataset.index;
this.setData({
current: _current
})
},
changeList: function() {
this.setData({
iconList: !this.data.iconList,
})
},
}
- scroll-view的scroll-top无法起作用时第二种便利滚动
wx.pageScrollTo({
scrollTop: 0,
duration: 0
});
- 上传图片九图显示
<view class="m-show">
<view wx:if="{{tempFilePaths.length}}" wx:for="{{tempFilePaths}}" key="{{index}}" class="m-add">
<image src="{{item}}"></image>
</view>
<view class="m-add" bindtap="addImage" wx:if="{{tempFilePaths.length < 9}}">
<view class="add-icon"></view>
</view>
</view>
.m-show{
margin-top: 138rpx;
display: flex;
flex-flow: row wrap;
}
.m-add{
width: 30%;
position: relative;
display: flex;
justify-content: center;
align-items: center;
margin-left: 45rpx;
margin-bottom: 20rpx;
width:194rpx;
height:194rpx;
background:rgba(248,248,248,1);
}
.m-add image{
width:100%;
height:100%;
}
.m-add .add-icon {
width:100rpx;
height:100rpx;
}
.m-add .add-icon::before {
content: '';
position: absolute;
left: 50%;
top: 50%;
width: 52rpx;
transform: translate(-50%, -50%);
border-top: 5rpx solid #CBCBCB;
}
.m-add .add-icon::after {
content: '';
position: absolute;
left: 50%;
top: 50%;
height: 52rpx;
transform: translate(-50%, -50%);
border-left: 5rpx solid #CBCBCB;
}
data: {
tempFilePaths: [],
allLimit: 9, //限制图片数量
nowLimit: 0, //已上传图片数量
},
addImage: function() {
var vm = this;
wx.chooseImage({
count: vm.data.allLimit - vm.data.nowLimit,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success(res) {
// 限制上传图片大小 不大于 2MB
if (res.tempFiles[0].size > 2 * 1024 * 1024) {
wx.showToast({
title: '上传图片不能大于 2MB',
icon: 'none',
});
return false;
}
/* // 显示上传中
res.tempFilePaths.forEach(element => {
let images = {
status: 1, // 状态:1上传中、2成功、3失败
statusText: '上传中', // 状态
original: element, // 本地临时图片
remote: '', // 上传成功后的远程图片
};
_this.data.images = _this.data.images.concat(images);
}); */
const tempFilePaths = res.tempFilePaths
vm.setData({
tempFilePaths: vm.data.tempFilePaths.concat(tempFilePaths),
nowLimit: vm.data.nowLimit + tempFilePaths.length,
})
console.log(vm.data.nowLimit, 'aaaikmg')
}
})
}