小程序原生是没有下拉框组件的,项目中需要用到下拉框的业务场景,没有找到就只能自己动手来写了,这里简单写下实现过程。
提示:点击阅读原文,浏览效果更佳窝。
先看一下效果

首先分析需求,点击按钮,下拉框展示,文字及图表的样式颜色变化,并且下拉框内的每一项均可点,点击有高亮显示。其中控制下拉框的展示和隐藏可以用
wx:if
或者
hidden
来做。
这里的实现简单,代码如下
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
这里是做了封装,表示为
.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中定义对应的参数,如下
applicationList</code> `applicationIndustryList``conditionList` `cooperationList` 这四个List的内容是从后端拿的,如果不想写接口,可以写假数据。
</p>
<p>
</p>
<section class="_135editor" style="border-width: 0px;border-style: none;border-color: initial;box-sizing: border-box;">
<section style="clear: both;padding: 0px;border-width: 0px;border-style: none;border-color: initial;margin: 5px 0px;box-sizing: border-box;">
<section style="border-top-width: 2.5px;border-top-style: solid;border-color: #ef7060;font-size: 1em;font-weight: inherit;text-decoration: inherit;color: #fefefe;box-sizing: border-box;">
<section style="border-width: 0px;border-style: initial;border-color: rgb(239, 112, 96);margin: 2px 0px 0px;overflow: hidden;padding: 0px;color: inherit;box-sizing: border-box;">
<section style="display: inline-block;font-size: 1em;font-family: inherit;font-weight: inherit;text-align: inherit;text-decoration: inherit;color: inherit;border-color: rgb(239, 112, 96);background-color: transparent;box-sizing: border-box;">
<section class="135brush" style="display: inline-block;line-height: 1.4em;padding: 5px 10px;height: 32px;vertical-align: top;font-size: 16px;font-family: inherit;font-weight: bold;float: left;color: inherit;border-color: #d42b15;box-sizing: border-box !important;background: #ef7060;">定义一个下拉框</section>
<section style="display: inline-block;vertical-align: top;font-size: 16px;width: 0px;height: 0px;border-top-width: 32px;border-top-style: solid;border-top-color: #ef7060;border-right-width: 32px;border-right-style: solid;border-right-color: transparent;border-top-right-radius: 4px;border-bottom-left-radius: 2px;color: inherit;box-sizing: border-box !important;"></section>
</section>
</section>
</section>
</section>
</section>
这里只需要把布局实现一下,再加一个`wx:if`的判断,代码如下
<section class="output_wrapper" style='color: #3e3e3e;line-height: 1.6;letter-spacing: 0px;font-family: "Helvetica Neue", Helvetica, "Hiragino Sans GB", "Microsoft YaHei", Arial, sans-serif;'>
<pre style="font-size: inherit;color: inherit;line-height: inherit;"><code class="html language-html hljs xml" style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: #a9b7c6;background: #282b2e;padding: 0.5em;display: block !important;white-space: pre !important;overflow-wrap: normal !important;word-break: normal !important;overflow: auto !important;">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
做判断,用作高亮显示,下面有说。
做个简单判断处理
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,则高亮显示,否则不高亮。
// 所属领域的选择
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布局,也简单,就没贴样式代码,整体来说难点可能在选择类目点击高亮的逻辑,这里是判断点击项,动态匹配添加样式,其他的就没什么了。

原文始发于微信公众号(枪在手):