微信小程序爬坑记之--下拉框实现

loading

前言

小程序原生是没有下拉框组件的,项目中需要用到下拉框的业务场景,没有找到就只能自己动手来写了,这里简单写下实现过程。


场景描述

废话不多说,先来看一下实现效果
loading...

分析

首先分析需求,点击按钮,下拉框展示,文字及图表的样式颜色变化,并且下拉框内的每一项均可点,点击有高亮显示。其中控制下拉框的展示和隐藏可以用 wx:if 或者 hidden 来做。

实现

定义分类的标签

这里的实现简单,代码如下

wxml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<view class="filter row-around align-center bg-white ph32">
<view class="condition row-between" bindtap="handleOpenOne">
<view class="text" style="color: {{ colorOne }}">行业领域</view>
<image class="condition-image" src="/images/icon/{{stateOne}}.png" />
</view>

<view class="interval">|</view>

<picker class="condition" mode="selector" range="{{ conditionList }}" range-key="name" value="{{ index }}" bindchange="handleConditionChoose" bindcancel="handleFalseChoose">
<view class="row-between" bindtap="handleOpenTwo">
<view class="text" style="color: {{ colorTwo }}">成熟度</view>
<image class="condition-image" src="/images/icon/{{stateTwo}}.png" />
</view>
</picker>

<view class="interval">|</view>

<picker class="condition" mode="selector" range="{{ cooperationList }}" range-key="name" value="{{ index }}" bindchange="handleCooperationList" bindcancel="handleFalseChoose">
<view class="row-between" bindtap="handleOpenThree">
<view class="text" style="color: {{ colorThree }}">合作标签</view>
<image class="condition-image" src="/images/icon/{{stateThree}}.png" />
</view>
</picker>

</view>

其中的样式,如 row-around align-center bg-white ph32 这里是做了封装,表示为

1
2
3
4
5
6
7
.filter {
display: flex;
justify-content: space-around;
align-items: center;
background-color: white;
padding: 0 32rpx;
}

由于分类标签的颜色及箭头的颜色样式是变化的,所以这里给样式写活,在data中定义参数。其中的 picker 组件也是个坑,这里使用普通的单列选择器,range表示需要显示的数据列表,可以是 Array / Object两种形式。 range-key 表示选择器显示内容,必填,不然没有数据展示。

设置标签默认状态

在js文件中的Page下的data中定义对应的参数,如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Page({
data: {
state: false, // 下拉框默认隐藏状态
colorOne: '#7B7B7B',
stateOne: 'down',
stateTwo: 'down',
stateThree: 'down',
applicationList: [], // 所属领域
applicationIndustryList: [], // 应用行业
conditionList: [], // 成熟度
cooperationList: [], // 合作标签
index: [0], // 默认选择
technologyList: [],
applicationDomainId: '',
applicationIndustryId: ''
},
}

这里定义了对应的参数及默认初始值。其中 applicationList applicationIndustryList conditionList cooperationList 这四个List的内容是从后端拿的,如果不想写接口,可以写假数据。

定义一个下拉框

这里只需要把布局实现一下,再加一个wx:if的判断,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<view class="spinner bg-white"  wx:if="{{ state }}" baindtap="handleOpenOne">
<view class="content">
<view class="title mv20">所属领域</view>

<view class="contentList row flex-wrap" >
<view class="item mv10" wx:for="{{ applicationList }}" wx:key="item.id" >
<view class="name ph20 mr20 {{item.isCheck ? 'select' : 'cancel'}}" data-id="{{ item.id }}" bind:tap="handleApplicationDomainChoose">{{ item.name }}</view>
</view>
</view>

<view class="title mv20">应用行业</view>

<view class="contentList row flex-wrap" >
<view class="item mv10" wx:for="{{ applicationIndustryList }}" wx:key="item.id" >
<view class="name ph20 mr20 {{item.isCheck ? 'select' : 'cancel'}}" data-id="{{ item.id }}" bind:tap="handleApplicationIndustryChoose">{{ item.name }}</view>
</view>
</view>
</view>

<!-- 确定 -->
<view class="button row-center">
<button class="enter" bindtap="handleEnterSearch">确定</button>
</view>
</view>

其中 wx:if="" 表示该 spinner 内容块的展示状态,如果 state 为true,则展示,相反隐藏。这个 state 已经在data中定义。样式同样的里面有一些封装的。 item.isCheck ? 'select' : 'cancel' 这里是对每一项的 isCheck做判断,用作高亮显示,下面有说。

条件选择时图标变化

做个简单判断处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
handleOpenOne: () => {
if(page.data.stateOne == 'down') {
page.setData({
stateOne: 'up',
colorOne: '#3E81FD',
state: true
})
} else {
page.setData({
stateOne: 'down',
colorOne: '#7B7B7B',
state: false
})
}
}

点击做事件监听,改变箭头变化

每一项点击高亮的逻辑

这个首先点击每一项,就必须要知道点击的是哪一个,所以每一项应该有一个唯一标识id,点击项会高亮显示,所以这里给每一项增加一个 isCheack 属性,用来判断该项是否被点击,如果为true,则高亮显示,否则不高亮。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 所属领域的选择
handleApplicationDomainChoose: (e) => {
const applicationDomainId = e.currentTarget.dataset.id;
const { applicationList } = page.data;
applicationList.map((item) => {
if (item.id === applicationDomainId) {
item.isCheck = true;
return;
}
item.isCheck = false;
});
page.setData({
applicationList,
applicationDomainId,
});
}

这里的逻辑是,拿点击项的id与所属领域列表的每一项做匹配,匹配到的说明是被点击的,所以把该项的 isCheck 作为true,样式就是 select,在wxss文件中定义select为选中的样式,这样就实现了高亮。是通过上面的三目表达式 item.isCheck ? 'select' : 'cancel' 对样式做的判断。

总结

样式都是使用Flex布局,也简单,就没贴样式代码,整体来说难点可能在选择类目点击高亮的逻辑,这里是判断点击项,动态匹配添加样式,其他的就没什么了,提供个思路,动手试试吧。

如果觉得文章不错,请我吃根辣条吧~~