1.前言

  • 官方的picker组件不能禁用某个下拉项,所以就有了这个下拉组件
  • 组件只适配了宽屏模式,效果参照element-ui的select组件
  • demo地址:lianlizhou / ep-select

2.封装思路

  • 此组件使用了字体图标,素材来源于iconfont
  • 组件分为3个部分:输入框容器,下拉容器,蒙版容器
  • 输入框容器:展示已选中的选项,点击则展示下拉容器和蒙版容器
  • 下拉容器:使用绝对定位,展示备选下拉项,以及相应的点击事件
  • 蒙版容器:使用fixed定位,全屏覆盖,点击隐藏下拉容器和自身

3.基本用法

  • 父组件调用方法
<template>
<view class="content">
<view style="display: flex;justify-content: center;padding:10px;">
<ep-select :disabled="false" v-model="select" :options="options" @change="change"></ep-select>
</view>
</view>
</template> <script>
export default {
data() {
return {
select: '',
options:[
{value:"1",label:"上海"},{value:"2",label:"深圳"},{value:"3",label:"广州",disabled:true}
]
}
},
onLoad() { },
methods: {
change(e){
console.log('select = ',this.select)
}
}
}
</script>
  • 效果

4.参数说明

  • 参数说明
参数 类型 默认值 说明
value String,Number '' 当前选中项的支持v-model
options Array [] 下拉选项列表,disabled属性代表当前项禁用
value_key String value 指定 Object 中 key 的值作为选择器选中内容,以此同步给value属性
label_key String label 指定 Object 中 key 的值作为选择器展示内容
  • 事件说明
参数 类型 默认值 说明
change EventHandle - 下拉选择切换事件

5.完整代码

<template>
<view class="ep-picker-box">
<!-- 蒙版区域 开始 -->
<view class="ep-mask-box" v-show="show" @click="show=false"></view>
<!-- 蒙版区域 开始 --> <!-- 输入框区域 开始 -->
<view class="ep-input-box" @click="openOptions" :class="{'disabled':disabled}">
<view style="display: flex;align-items: center;min-height: 36px;">{{showLabel}}</view>
<text v-if="!show" class="iconfont icon-xiala"></text>
<text v-else class="iconfont icon-xialashang"></text>
</view>
<!-- 输入框区域 结束 --> <!-- 弹出的下拉区域 开始 -->
<view v-show="show" class="ep-picker-content-wrap">
<scroll-view class="ep-picker-content" :scroll-y="true">
<!-- 展示下拉项列表 开始 -->
<view v-for="item in options" :key="item[value_key]"
:class="{'disabled':item.disabled,'active':value==item[value_key]}"
class="option-item"
@click="itemClick(item)"
>{{item[label_key]}}</view>
<!-- 展示下拉项列表 结束 --> <!-- 下拉列表为空 开始 -->
<view v-if="options.length==0" class="option-no-data">无数据</view>
<!-- 下拉列表为空 结束 -->
</scroll-view>
<text class="triangle"></text>
</view>
<!-- 弹出的下拉区域 结束 -->
</view>
</template> <script>
export default{
data(){
return {
show: false,
left: 0, }
},
props:{
value:{
type:[String,Number],
default:""
},
options:{
type: Array,
default: function(){
return []
}
},
value_key:{
type:String,
default:"value"
},
label_key:{
type:String,
default:"label"
},
disabled:{
type:Boolean,
default:false
}
},
model:{
prop:'value',
event:"valChange"
},
methods:{
//点击选中选项
itemClick(item){
if(item.disabled) return //关闭
this.show = false
//修改v-model的值
this.$emit('valChange',item[this.value_key])
//将事件通知父组件
this.$emit('change',item[this.value_key])
},
//展开选项
openOptions(){
if(!this.disabled){
this.show = true
}
}
},
computed:{
showLabel(){
var index = this.options.findIndex(item=>{
return item[this.value_key] == this.value
})
if(index != -1){
return this.options[index][this.label_key]
}else if(!this.value){
return "请选择"
}else{
return this.value
}
}
}
}
</script> <style scoped>
/* 引入字体图标 */
@import './iconfont.css'; .ep-picker-box{
width:100%;
box-sizing: border-box;
position: relative;
font-size: 14px;
color: #333;
max-width: 300px;
}
.ep-mask-box{
position: fixed;
z-index: 999;
top: 0;
right: 0;
left: 0;
bottom: 0;
background:none;
}
.ep-input-box{
border: 1px solid rgb(229, 229, 229);
border-radius: 4px;
padding-left:10px;
position: relative;
cursor: pointer;
}
/* 整个下拉组件禁用样式 */
.ep-input-box.disabled{
cursor:not-allowed;
background-color: #f5f7fa;
color: #999;
}
/* 展开收起箭头样式 */
.ep-input-box .iconfont{
position: absolute;
top: 50%;
right: 5px;
font-size: 20px;
transform: translateY(-50%);
color:#B8B8B8;
}
/* 下拉容器样式 外层 */
.ep-picker-content-wrap{
width: 100%;
position: absolute;
top: 45px;
left: 0;
z-index: 9999;
padding-top:6px;
}
/* 下拉容器样式 内层 */
.ep-picker-content-wrap .ep-picker-content{
background-color: #fff;
padding:3px 0;
box-shadow: 0 0 20px 5px rgb(0 0 0 / 30%);
border-radius: 5px;
max-height:181px;
}
/* 下拉项通用样式 */
.ep-picker-content-wrap .ep-picker-content .option-item{
padding: 8px 18px;
cursor: pointer;
}
/* 无下拉项数据时样式 */
.ep-picker-content-wrap .ep-picker-content .option-no-data{
padding: 8px 18px;
cursor: text;
color:#999;
text-align: center;
}
/* 鼠标移入下拉项样式 */
.ep-picker-content-wrap .ep-picker-content .option-item:hover{
background-color: #f5f7fa;
}
/* 已选中的下拉项样式 */
.ep-picker-content-wrap .ep-picker-content .option-item.active{
color:#007AFF;
}
/* 禁用的下拉项样式 */
.ep-picker-content-wrap .ep-picker-content .option-item.disabled{
color:#c0c4cc;
}
.ep-picker-content-wrap .ep-picker-content .option-item.disabled:hover{
cursor:not-allowed;
} /* 下拉容器指示箭头样式 */
.ep-picker-content-wrap .triangle{
width: 0;
height: 0;
border-top: 6px solid rgba(0,0,0,0);
border-right: 6px solid rgba(0,0,0,0);
border-bottom: 6px solid #fff;
border-left: 6px solid rgba(0,0,0,0);
position: absolute;
top:-6px;
left:50%;
transform: translateX(-50%);
box-sizing: content-box;
} </style>

uniapp select组件的更多相关文章

  1. 改变select组件的option选中状态的快捷方法

    以前我都是在<option>标签处通过判断value是否与其中一个相同然后输出selected="selected"来处理的,今天发现可以直接能过Js改变<sel ...

  2. select组件2

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...

  3. select组件

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...

  4. 如何实现select组件的选择输入过滤作用

    实现select组件的选择输入过滤作用的js代码如下: /** *其中//******之间的部分显示的是在没有选择输入过滤功能的代码上加入的功能代码 ** / (function ( $ ) { $. ...

  5. freemarker写select组件(一)

    freemarker写select组件 1.宏定义 <#macro select id datas> <select id="${id}" name=" ...

  6. freemarker写select组件报错总结(一)

    1.具体错误如下 六月 25, 2014 11:26:29 下午 freemarker.log.JDK14LoggerFactory$JDK14Logger error 严重: Template pr ...

  7. freemarker写select组件(五)

    freemarker写select组件 1.宏定义 <#macro select id datas value="" key="" text=" ...

  8. freemarker写select组件(四)

    freemarker写select组件 1.宏定义 <#macro select id datas value="" key="" text=" ...

  9. freemarker写select组件(三)

    freemarker写select组件 1.宏定义 <#macro select id datas value="" key="" text=" ...

  10. freemarker写select组件(二)

    freemarker写select组件 1.宏定义 <#macro select id datas value=""> <select id="${id ...

随机推荐

  1. Java怎么把多个对象的list的数据合并

    1.示例一:创建几个包含Person对象的List,并将它们合并成一个新的List 在Java中,将多个对象的List合并通常涉及到遍历这些List并将它们的元素添加到一个新的List中.这里,我将给 ...

  2. 工具 – Cypress

    介绍 Cypress 是一款 e2e 测试工具.每当我们写好一个组件或者一个页面之后,我们会想对整体做一个测试. 在不使用工具的情况下,我们会开启 browser,然后做一系列点击.滚动.填 form ...

  3. TypeScript – tsconfig

    前言 上一篇 TypeScript – Get Started 使用了命令 tsc index.ts --module es2015 很少人会在命令时给写 config, 更正规的做法是创建一个 ts ...

  4. Python 潮流周刊#70:微软 Excel 中的 Python 正式发布!(摘要)

    本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...

  5. mac M1,M2,M3芯片踩坑 nodejs ruby brew

    问题&解决方法 先说解决方法, 感兴趣的可以了解事情的经过, 也许我描述的问题不专业, 但确实解决了当下的问题, 欢迎留言讨论 这里主要是两个问题, 一个是启用rosetta模式失败, 一个是 ...

  6. [TK] Tourist Attractions

    题目描述 给出一张有 \(n\) 个点 \(m\) 条边的无向图,每条边有边权. 你需要找一条从 \(1\) 到 \(n\) 的最短路径,并且这条路径在满足给出的 \(g\) 个限制的情况下可以在所有 ...

  7. 三,MyBatis-Plus 的各种查询的“超详细说明”,比如(等值查询,范围查询,模糊查询...)

    三,MyBatis-Plus 的各种查询的"超详细说明",比如(等值查询,范围查询,模糊查询...) @ 目录 三,MyBatis-Plus 的各种查询的"超详细说明&q ...

  8. 2.2.2 PyTorch 2.0 GPU NVIDIA运行库的安装 ——CUDA+cuDNN安装教程

    参考文章: https://blog.csdn.net/mbdong/article/details/121769951 CUDA download: https://developer.nvidia ...

  9. 打开word报错“内存或磁盘空间不足,无法显示所请求的字体”

    起因: 有一个部门同学在打开服务器上的某个word文档时报错,但是打开本地word文档正常,经过网上查询资料后发现有可能是以下几种原因造成. 可能造成此报错的原因: 1. 文档被锁定 解决办法: 鼠标 ...

  10. 搜广推算法校招面试:BOSS直聘 推荐搜索系统工程师

      本文介绍2024届秋招中,BOSS直聘的推荐/搜索系统工程师岗位一面的面试基本情况.提问问题等.   2023年12月,赶在秋招的末尾,投递了BOSS直聘的推荐/搜索系统工程师岗位,并不清楚所在的 ...