微信小程序编写tabBar模板,map组件markers属性动态初始化

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

相关推荐