赞
踩
我们在做微信小程序的时候,往往需要做导航栏,效果是:点击导航栏的子元素,显示对应的Tab页,并且要修改点击的子元素样式用来提示用户当前位置。效果是这样:
底部导航不用说,直接在app.json中定义跳转地址和选中样式即可。关键是自定义导航,需要我们自己定义。
相信看过小程序API的人都知道导航栏怎么写:在wxml中列出每个导航栏,指定每个导航栏的url和点击样式就可以了。不清楚的童鞋可以查看API:微信小程序导航栏API
就像这样:
- <!-- sample.wxml -->
- <view class="btn-area">
- <navigator url="/page/navigate/navigate?title=navigate" hover-class="navigator-hover">跳转到新页面</navigator>
- <navigator url="../../redirect/redirect/redirect?title=redirect" open-type="redirect" hover-class="other-navigator-hover">在当前页打开</navigator>
- <navigator url="/page/index/index" open-type="switchTab" hover-class="other-navigator-hover">切换 Tab</navigator>
- </view>
好的做法是动态请求JSON数据,循环渲染出整个导航栏。如果需要修改导航栏,通过后台修改数据库中导航栏的数据即可,后台返回JSON数据给展示页面,展示页面调用this.setData({})方法即可绘制出新的导航栏。
JSON数据存储了导航栏各个子元素信息,其中goodsName对应上图的名称,goodsId用于标识每个元素,goodsClass用来定义图片路径,如下:
- [{
- "goodsName":"油烟机",
- "goodsId":"1",
- "goodsClass":"yanji"
- },{
- "goodsName":"热水器",
- "goodsId":"2",
- "goodsClass":"reshuiqi"
- },{
- "goodsName":"灶具",
- "goodsId":"3",
- "goodsClass":"zao"
- },{
- "goodsName":"浴室柜",
- "goodsId":"4",
- "goodsClass":"yushigui"
- },{
- "goodsName":"花洒",
- "goodsId":"5",
- "goodsClass":"huasa"
- },{
- "goodsName":"马桶",
- "goodsId":"6",
- "goodsClass":"matong"
- }]
wxml页面这样写即可循环渲染每一个导航栏,其中用到了wx:for="{{navList}}"来遍历页面data数据中的navList值,而这个navList就是我们请求的JSON。wx:for内层结构中的{{item.goodsId}}对应每个导航栏子元素的goodsId属性值,其他如{{item.goodsName}}以此类推。到这儿,你的页面应该能够渲染出整个导航栏了,但是还没有点击修改样式的功能。
- <view class="container clearfloat">
- <view class="leftNav">
- <block wx:for="{{navList}}" wx:key="goodsId">
- <view style="color:{{item.goodsId==currentItemId?'#e98f36':'#000'}}" data-num="{{item.goodsId}}" class="goodsTitle" bindtap="clickTap">
- <image src="/images/{{item.goodsClass}}{{item.goodsId==currentItemId?2:1}}.png"></image>
- <!--<image src="{{item.goodsImg}}"></image>-->
- <span>{{item.goodsName}}</span>
- </view>
- </block>
- </view>
- </view>
我们可以给每个子元素添加点击事件:上面代码中的bindtap="clickTap"就是给每个元素添加点击事件,这个点击事件处理函数在js文件中定义。下面我直接贴出这个页面的完整js文件:
- Page({
- data: {
- currentItemId:"1"
- },
- onLoad: function (options) {
- // 页面初始化 options为页面跳转所带来的参数
- var that = this //这一句不可少,能够调用Page对象的setData({})方法
- wx.request({
- url: 'https://www.****(你请求的域名).com/json/navList.json', //小程序要求请求的协议必须是https,所以你的服务器后台网站必须https化,而且TLS版本在1.2 以上,过程不难,后续我会写一篇如何部署服务器以及https化和TLS升级的博文
- header: {
- 'content-type': 'application/json'
- },
- success: function (res) {
- that.setData({
- navList: res.data
- })
- }
- })
-
- },
- clickTap:function(e){
- this.setData({
- currentItemId:e.currentTarget.dataset.num
- })
- },
- onReady: function () {
- // 页面渲染完成
- },
- onShow: function () {
- // 页面显示
- },
- onHide: function () {
- // 页面隐藏
- },
- onUnload: function () {
- // 页面关闭
- }
- })
wxml页面通过三目运算,判断每一个子元素的样式是否需要修改
style="color:{{item.goodsId==currentItemId?'#e98f36':'#000'}}" 这一句通过运算,判断每个子元素是否需要修改,如果它的goodsId等于被点击的元素的id(即currentItemId),就让颜色是#e98f36,否则就是黑色。
<image src="images/{{item.goodsClass}}{{item.goodsId==currentItemId?2:1}}.png"></image>这一句更绝,通过判断每个子元素是不是当前被点击的,直接修改图片的路径来显示不同的图片,达到已点击的样式效果。
这里贴出样式文件wxss,需要看效果的童鞋,复制对应的代码到对应的小程序文件中就行。
- .leftNav {
- float: left;
- width: 160rpx;
- }
-
- .goodsList {
- float: right;
- }
-
- .goodsTitle {
- min-width: 120rpx;
- text-align: center;
- line-height: 40rpx;
- float: left;
- font-size: 30rpx;
- padding: 20rpx 20rpx;
- background-color: #fafafa;
- border-bottom: 2rpx solid lightgray;
- border-right: 2rpx solid lightgray;
- }
-
- .goodsTitle>image {
- width: 64rpx;
- height: 64rpx;
- }
- .goodsTitle>span{
- display: block;
- }
- .goodsTitle>first-child{
- border-top: 2rpx solid lightgray;
- }
- .goodsImgView{
- margin: 0 auto 10rpx;
- width: 64rpx;
- height: 64rpx;
- background-repeat: no-repeat;
- }
实现的逻辑有点绕:首先通过JSON数据循环渲染导航栏,然后给每个导航栏一个统一的点击事件函数clickTap,通过这个函数修改当前页面的全局数据currentItemId为被点击元素的goodsId,最后在视图文件中判断当前元素的goodsId是否等于这个值来修改被点击元素的样式。
不得不这样做的根本原因:小程序不能像javascript或者jquery一样获取DOM元素或JQ对象来修改样式,而是通过setData({})方法刷新全局数据,然后回调渲染方法来重绘DOM(懂ReactJS的童鞋应该很熟悉)。全局数据是修改样式的唯一依据,它由点击事件函数修改,但是不像静态wxml每个导航元素都可以定义一个点击事件函数,通过循环遍历的元素只能是调用同一个事件函数(我们定义的clickTap)修改全局数据,所以我们需要获取每个元素的唯一标识(我们定义在JSON中的goodsId)来修改全局数据,最后每个元素根据这个全局数据来修改样式。
-over-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。