bruceli 2017-02-07
一:编写tabBar模板
众所周知,微信小程序的tabBar都是新开页面的,而微信文档上又表明了最多只能打开5层页面。这样就很容易导致出问题啦,假如我的tabBar有5个呢?下面是微信原话:
一个应用同时只能打开5个页面,当已经打开了5个页面之后,wx.navigateTo不能正常打开新页面。请避免多层级的交互方式,或者使用wx.redirectTo
因此这几天想着根据微信tabBar数组来自定义模板供页面调用。不过我在list里面每个对象都增加了一个selectedColor和active属性,方便对每个tabBar当前页做样式,如果不传直接使用设置的selectedColor。因此这串数据只能设定在各个页面下,不能设定在公用的app.js配置文件下,稍微有点代码冗余,下次研究下怎么直接配置到app.js完善下。
只要新建一个tarBar.wxml模板页,然后引用模板的页面传入数据即可,代码如下:
<templatename="tabBar">
<viewclass="flex-hflex-hsbtab-bar"style="color:{{tabBar.color}};background:{{tarBar.backgroundColor}};{{tabBar.position=='top'?'top:0':'bottom:0'}};{{tabBar.borderStyle?(tabBar.position=='top'?'border-bottom:solid1px'+tabBar.borderStyle+';':'border-top:solid1px'+tabBar.borderStyle+';'):''}}">
<blockwx:for="{{tabBar.list}}"wx:key="pagePath">
<navigatorurl="{{item.pagePath}}"open-type="redirect"class="menu-item"style="{{item.active?'color:'+(item.selectedColor?item.selectedColor:tabBar.selectedColor):''}}">
<imagesrc="{{item.selectedIconPath}}"wx:if="{{item.active}}"></image>
<imagesrc="{{item.iconPath}}"wx:if="{{!item.active}}"></image>
<text>{{item.text}}</text>
</navigator>
</block>
</view>
</template>
复制代码
接下来进行测试,首先是index.js的配置对象:
//配置tabBar
tabBar:{
"color":"#9E9E9E",
"selectedColor":"#f00",
"backgroundColor":"#fff",
"borderStyle":"#ccc",
"list":[
{
"pagePath":"/pages/index/index",
"text":"主页",
"iconPath":"../../img/tabBar_home.png",
"selectedIconPath":"../../img/tabBar_home_cur.png",
//"selectedColor":"#4EDF80",
active:true
},
{
"pagePath":"/pages/village/city/city",
"text":"目的地",
"iconPath":"../../img/tabBar_village.png",
"selectedIconPath":"../../img/tabBar_village_cur.png",
"selectedColor":"#4EDF80",
active:false
},
{
"pagePath":"/pages/mine/mine",
"text":"我的",
"iconPath":"../../img/tabBar_mine.png",
"selectedIconPath":"../../img/tabBar_mine_cur.png",
"selectedColor":"#4EDF80",
active:false
}
],
"position":"bottom"
}
复制代码
index.wxml引入模板:
<importsrc="../../template/tabBar.wxml"/>
<templateis="tabBar"data="{{tabBar:tabBar}}"/>
复制代码
接下来是mine.js文件引入配置对象:
//配置tabBar
tabBar:{
"color":"#9E9E9E",
"selectedColor":"#f00",
"backgroundColor":"#fff",
"borderStyle":"#ccc",
"list":[
{
"pagePath":"/pages/index/index",
"text":"主页",
"iconPath":"../../img/tabBar_home.png",
"selectedIconPath":"../../img/tabBar_home_cur.png",
//"selectedColor":"#4EDF80",
active:false
},
{
"pagePath":"/pages/village/city/city",
"text":"目的地",
"iconPath":"../../../img/tabBar_village.png",
"selectedIconPath":"../../../img/tabBar_village_cur.png",
"selectedColor":"#4EDF80",
active:false
},
{
"pagePath":"/pages/mine/mine",
"text":"我的",
"iconPath":"../../img/tabBar_mine.png",
"selectedIconPath":"../../img/tabBar_mine_cur.png",
"selectedColor":"#4EDF80",
active:true
}
],
"position":"bottom"
}
复制代码
mine.wxml引入模板:
<importsrc="../../template/tabBar.wxml"/>
<templateis="tabBar"data="{{tabBar:tabBar}}"/>
复制代码
最后演示如下:
1.gif
方案二
我把配置数据统一放在app.js文件,通过点击跳转页面后在把数据添加到当前页面实例上,具体做法如下:
1、app.js文件配置:
//app.js
varnet=require('common/net');
vara_l,a_d={},a_cbSucc,a_cbSuccFail,a_cbFail,a_cbCom,a_h,a_m;
App({
onLaunch:function(){
varthat=this;
},
//修改tabBar的active值
editTabBar:function(){
var_curPageArr=getCurrentPages();
var_curPage=_curPageArr[_curPageArr.length-1];<spanstyle="font-family:Arial,Helvetica,sans-serif;">//相当于Page({})里面的this对象</span>
var_pagePath=_curPage.__route__;
if(_pagePath.indexOf('/')!=0){
_pagePath='/'+_pagePath;
}
vartabBar=this.globalData.tabBar;
for(vari=0;i<tabBar.list.length;i++){
tabBar.list.active=false;
if(tabBar.list.pagePath==_pagePath){
tabBar.list.active=true;//根据页面地址设置当前页面状态
}
}
_curPage.setData({
tabBar:tabBar
});
},
globalData:{
userInfo:null,
//配置tabBar
tabBar:{
"color":"#9E9E9E",
"selectedColor":"#f00",
"backgroundColor":"#fff",
"borderStyle":"#ccc",
"list":[
{
"pagePath":"/pages/index/index",
"text":"主页",
"iconPath":"/pages/templateImg/tabBar_home.png",
"selectedIconPath":"/pages/templateImg/tabBar_home_cur.png",
"selectedColor":"#4EDF80",
active:false
},
{
"pagePath":"/pages/village/city/city",
"text":"目的地",
"iconPath":"/pages/templateImg/tabBar_village.png",
"selectedIconPath":"/pages/templateImg/tabBar_village_cur.png",
"selectedColor":"#4EDF80",
active:false
},
{
"pagePath":"/pages/mine/mine",
"text":"我的",
"iconPath":"/pages/templateImg/tabBar_mine.png",
"selectedIconPath":"/pages/templateImg/tabBar_mine_cur.png",
"selectedColor":"#4EDF80",
active:false
}
],
"position":"bottom"
}
}
})
复制代码
2、index.js+mine.js+city.js页面使用:
varApp=getApp();
Page({
data:{
detail:{},
},
onLoad:function(options){
App.editTabBar();//添加tabBar数据
varthat=this;
}
})
复制代码
最终演示和上图一致!
二:map组件markers属性动态初始化
今天在写小程序详情页时候遇到一个问题,map组件的markers属性是通过异步请求到数据后设置的,结果就导致了微信底层渲染出错。但是如果我先在data初始化markers变量,每次小程序都不能正常渲染都是初始化的北京的数据。然后写了如下测试:
test.js:
Page({
data:{
map:{
lat:0,
lng:0,
markers:[],
hasMarkers:false//解决方案
}
},
onLoad:function(options){
varthat=this;
wx.getLocation({
type:'wgs84',//默认为wgs84返回gps坐标,gcj02返回可用于wx.openLocation的坐标
success:function(res){
//success
wx.request({
url:'https://xxx.com/detail.htm?vid=3&latlng='+res.latitude+','+res.longitude,
data:{},
method:'GET',//OPTIONS,GET,HEAD,POST,PUT,DELETE,TRACE,CONNECT
//header:{},//设置请求的header
success:function(res){
//success
that.setData({
'map.lat':res.data.data.lat,
'map.lng':res.data.data.lng,
'map.markers':[{
latitude:res.data.data.lat,
longitude:res.data.data.lng,
name:res.data.data.title,
desc:res.data.data.address
}],
'map.hasMarkers':true//解决方案
});
console.log(that.data.map.markers);
}
})
}
})
}
});
复制代码
test.wxml:
<viewstyle="height:100rpx;">
{{map.lat}}--{{map.lng}}--{{map.markers[0].name}}--{{map.markers[0].desc}}
</view>
<maplatitude="{{map.lat}}"longitude="{{map.lng}}"markers="{{map.markers}}"></map>
复制代码
测试一:data里面没有初始化map变量
2.jpg
测试二:初始化map变量,并在wxml把map数据都打印出来
3.jpg
为什么会这样呢??各种测试,最后发现只要不是经过远程请求在来设置map值就不会出问题。
后来经大神网友提点,由于异步设置值的过程,组件已经渲染。但是map变量没有预定义是undefined状态,map初始化拿不到数据直接报错了,而异步过来又变成动态更新导致了wxml需要重新渲染map组件的情况导致的。因为官方文档有提到:
地图组件的经纬度必填,如果不填经纬度则默认值是北京的经纬度。标记点markers只能在初始化的时候设置,不支持动态更新。
只能初始化一次,因此导致每次都是显示的初始化信息。
然后,网友给出的解决方案完美解决了这个问题:
wx:if会渲染一下组件,那我们按照这个思路给他加个if就行了
<mapmarkers="{{markers}}"style="width:375px;height:200px;"wx:if="{{map}}"></map>
复制代码
默认map是false,就是加载时不渲染map组件,等ajax回来后把map设置为true,这样就动态渲染成你要的地址了
原文链接:http://bbs.jointforce.com/topic/25439