老板说商户端小程序的首页太丑了,排版布局需要重新设计,新的设计图是这样的:
先说下需求:首页直接按照设计图做出来,页头的产品验证、身份认证、店铺折扣、账户升级、下方的营销系统板块以及快捷管理中的9个功能块暂时在前端页面写死,不需要后台动态生成或者管理。因为该页面之前同事写过,现在需要重新修改,修改之前我看了看代码,感觉很凌乱。。。所以决定自己重新写一个。
看起来很简单的需求,直接在wxml文件中写就行了啊,每一块图不同、文字不同,复制粘贴改一下每部分不同的不就行了么?
越是简单的东西,做起来看似简单,但要做得好,还需要考虑很多东西~
我写这篇博文的目的是,在这种简单、重复的环境下,如何优雅地写出页面。
先从页头部分的四个功能进行分析:
四个功能,图片样式不同、标题文字不同,还有一处比较特殊的地方是,产品验证与店铺折扣这两块,点击后并不是跳转到某某页面,而是在当前页面出现一个新的遮罩层,在里面填写或者修改信息,那么这时候肯定会设计到js中点击事件,点击后让某个遮罩层显示出来,所以现在navigator标签作跳转,又有view绑定点击事件。
先说说传统写法:
<view class="mainFn">
<!-- item -->
<view class="mainFn-item" catchtap="mainFnOne">
<view class="mainFn-ico">
<image mode='aspectFit' src='1.jpg'></image>
</view>
<view class="mainFn-title">产品验证</view>
</view>
<!-- item -->
<navigator url='/2/index' class="mainFn-item">
<view class="mainFn-ico">
<image mode='aspectFit' src='2.jpg'></image>
</view>
<view class="mainFn-title">身份认证</view>
</navigator>
<!-- item -->
<view class="mainFn-item" catchtap="mainFnThree">
<view class="mainFn-ico">
<image mode='aspectFit' src='3.jpg'></image>
</view>
<view class="mainFn-title">店铺折扣</view>
</view>
<!-- item -->
<navigator url='/4/index' class="mainFn-item">
<view class="mainFn-ico">
<image mode='aspectFit' src='4.jpg'></image>
</view>
<view class="mainFn-title">账户升级</view>
</navigator>
</view>
乍一看没有什么问题,该用navigator的地方用navigator,该用view的地方用view并加上点击方法,但是如果item较多呢,有几十个呢?写出来会不会太多,wxml页面中的结构会不会太多?看起来会不会有种眼花缭乱的感觉?
所以该怎么优化?
1、虽然当前板块是静态的,但数量较多,可以将所有不同的地方,放在JS中;
2、navigator可以跳转,view可以点击,那么全部统一为 view标签,不论是跳转或点击,全部在js中完成;
3、所有view块都有点击事件,那么只用一个事件,事件内用参数判断;
先看js中data写的内容:
data: {
//产品验证、身份认证、店铺折扣、账户升级
mainFn: [{
src: '/static/images/newIndex/verify.png',
path: null,
title: '产品验证'
},
{
src: '/static/images/newIndex/card.png',
path: '/pages/shopset/index',
title: '身份认证'
},
{
src: '/static/images/newIndex/dis.png',
path: null,
title: '店铺折扣'
},
{
src: '/static/images/newIndex/up.png',
path: '/pages/upgrade/index',
title: '账户升级'
},
],
将每个item的src、path、title全部放在一个数组中,wxml中直接使用wx:for渲染就行:
<view class="mainFn">
<block wx:for="{{mainFn}}" wx:key='index'>
<view class="mainFn-item" data-path='{{item.path}}' data-index="{{index}}" catchtap="mainFn">
<view class="mainFn-ico">
<image mode='aspectFit' src='{{item.src}}'></image>
</view>
<view class="mainFn-title">{{item.title}}</view>
</view>
</block>
</view>
这样不论有多少个item,不论继续保持静态页面或是后期做成动态数据请求,都可以使用,大幅度减少页面冗杂结构,代码清晰规范,一目了然;
那么mainFn方法呢,其实就是拿到该点击方法的event,得到data-path与data-index:
mainFn: function (event) {
let index = event.currentTarget.dataset.index;
let path = event.currentTarget.dataset.path;
switch (index) {
case 0:
do something...
break;
case 1:
wx.navigatorTo({
url: path,
});
break;
case 2:
do something...
break;
case 3:
wx.navigatorTo({
url: path,
});
break;
}
},
当有多个点击事件时,建议用switch做判断,比较清晰明了,每种情况根据实际需求,做状态判断或者页面跳转。
包括下方的快捷管理板块,可以看出样式为九宫格分布:
可以看出,每行分布三个item,以第一行为例:第一个item有右边线、下边线,第二个item有右边线、下边线,第三个item没有右边线、有下边线……看设计图以此类推。那么在css中的写法,一般为 xxx:nth-child(1){…} xxx:nth-child(2){…} 感觉写法也太多太啰嗦,同样将边线的状态加在js的data中:
quick: [{
src: '/static/images/newIndex/shopSetting.png',
path: '/pages/shopset/index',
title: '店铺设置',
rightLine: true,
bottomLine: true
},
{
src: '/static/images/newIndex/goods.png',
path: '/',
title: '商品展示',
rightLine: true,
bottomLine: true
},
{
src: '/static/images/newIndex/bulk.png',
path: '/pages/group/productcontrol/index',
title: '团购产品',
rightLine: false,
bottomLine: true
},
{
src: '/static/images/newIndex/staf.png',
path: '/pages/staff/list/index',
title: '员工管理',
rightLine: true,
bottomLine: true
},
{
src: '/static/images/newIndex/vip.png',
path: '/pages/member/manage/index',
title: 'VIP管理',
rightLine: true,
bottomLine: true
},
{
src: '/static/images/newIndex/msg.png',
path: '/pages/message/msgManage/index',
title: '短信管理',
rightLine: false,
bottomLine: true
},
{
src: '/static/images/newIndex/commission.png',
path: '/pages/return/index',
title: '返比管理',
rightLine: true,
bottomLine: false
},
{
src: '/static/images/newIndex/data.png',
path: '/pages/businessdata/index',
title: '营业数据',
rightLine: true,
bottomLine: false
},
{
src: '/static/images/newIndex/order.png',
path: '/pages/order/index',
title: '订单管理',
rightLine: false,
bottomLine: false
},
],
边线状态为false时,代表无边线,状态为true时,代表存在边线,并且在CSS中提前定义好右边线样式和下边线样式:
.quick-r-line{
border-right: 1px solid #e0e0e0;
}
.quick-b-line{
border-bottom: 1px solid #e0e0e0;
}
那么在wxml中,用三元表达式判断,如果右边线状态为false,不显示,右边线状态为true,显示右边线;下边线同理:
<view class="quick-wrap">
<block wx:for='{{quick}}' wx:key='index'>
<navigator url='{{item.path}}' class="quick-item {{item.rightLine ? 'quick-r-line':''}} {{item.bottomLine ? 'quick-b-line':''}}">
<view class="quick-ico">
<image mode='aspectFit' src='{{item.src}}'></image>
</view>
<view class="quick-name">{{item.title}}</view>
</navigator>
</block>
</view>
即class="quick-item {{item.rightLine ? 'quick-r-line':''}} {{item.bottomLine ? 'quick-b-line':''}}"
完成,虽然是简单的页面布局,以最简化、明了的方法写出来,维护性可以大大提高~