<template>
|
<view class="form-select">
|
<view class="uni_select">
|
<view class="uni_select_mask" v-if="showSelector" @click="toggleSelector" />
|
<view class="uni_select_input_box">
|
<input class="input font-size-15" placeholder-style="font-size: 15px;" :class="disabled?'_disabled':''" :disabled="(!search || disabled)"
|
:focus="showSelector" :placeholder="placeholder" @input="setListAsKeyword" v-model="keyword"
|
@click="toggleSelector" />
|
<template v-if="search && !disabled">
|
<view v-if="keyword && !showSelector" class="iconfont icon-clear" @click="clear"></view>
|
</template>
|
<template v-else>
|
<view v-if="showSelector" class="iconfont icon-to-up" :class="disabled ? '_disabled' : ''"
|
@click="toggleSelector"></view>
|
<view v-if="!showSelector" class="iconfont icon-to-down" :class="disabled ? '_disabled' : ''"
|
@click="toggleSelector"></view>
|
</template>
|
</view>
|
<view class="uni_select_selector" v-if="showSelector" :style="selectStyle">
|
<scroll-view scroll-y="true" class="uni_select_selector_scroll">
|
<view style="height: 4px;"></view>
|
<view class="uni_select_selector_empty" v-if="list.length === 0">
|
<view class="select-text" style="word-break: break-all;font-size:12px;">{{emptyTips}}</view>
|
</view>
|
<view v-else class="uni_select_selector_item" :class="item.id == selectedId ? '_selected' : ''"
|
v-for="(item,index) in list" :key="index" @click="change(item)">
|
<view class="select-text" style="word-break: break-all;">{{item.title}}</view>
|
</view>
|
<view style="height: 4px;"></view>
|
</scroll-view>
|
</view>
|
</view>
|
</view>
|
</template>
|
|
<script>
|
/**
|
* DataChecklist 数据选择器
|
* @description 通过数据渲染的下拉框组件
|
* @property {Array} localdata 本地数据 ,格式 [{id:'',title:''}]
|
* @property {String, Number} selectedId 默认选项id
|
* @property {String} placeholder 表单placeholder
|
* @property {String} emptyText 没有数据时显示的文字 ,本地数据无效
|
* @property {Boolean} disabled 是否禁止选择
|
* @property {Boolean} search 是否开启关键词检索,争对选项很多的情况可根据关键词进行检索
|
* @event {Function} change 选中发生变化触发
|
*/
|
export default {
|
name: "formSelect",
|
props: {
|
localdata: {
|
type: Array,
|
default () {
|
return []
|
}
|
},
|
selectedId: {
|
type: [String, Number],
|
default: ''
|
},
|
placeholder: {
|
type: String,
|
default: '请选择'
|
},
|
emptyTips: {
|
type: String,
|
default: '没有更多选项了'
|
},
|
disabled: {
|
type: Boolean,
|
default: false
|
},
|
search: {
|
type: Boolean,
|
default: false
|
},
|
localdata:{
|
type:Array,
|
default:[]
|
},
|
value: {
|
type: [String, Number],
|
default: ''
|
},
|
},
|
watch: {
|
'localdata': {
|
immediate: true,
|
deep: true,
|
handler(news) {
|
if(news){
|
this.list = news
|
}
|
}
|
},
|
},
|
data() {
|
return {
|
showSelector: false,
|
selectStyle: '',
|
maxHeight: 288,
|
keyword: '',
|
list: [],
|
};
|
},
|
mounted() {
|
this.update();
|
this.$nextTick(() => {
|
this.setPosition();
|
});
|
},
|
methods: {
|
setPosition() {
|
let that = this;
|
if (this.list.length < 8) {
|
if (this.list.length > 0) {
|
this.maxHeight = (this.list.length * 36) + 10;
|
}
|
} else {
|
this.maxHeight = 288;
|
}
|
const query = uni.createSelectorQuery().in(this);
|
query.select('.uni_select_input_box').boundingClientRect(data => {
|
if (data) {
|
// 获取当前窗口的高度
|
const windowHeight = uni.getSystemInfoSync().windowHeight;
|
// 元素顶部到窗口顶部的距离
|
const elementTop = data.top;
|
// 元素的高度
|
const elementHeight = data.height;
|
// 元素距离底部的位置 = 窗口高度 - 元素顶部距离窗口顶部距离 - 元素高度
|
const bottomPosition = windowHeight - elementTop - elementHeight;
|
if (bottomPosition < that.maxHeight && bottomPosition >= 200) {
|
that.maxHeight = bottomPosition - 20;
|
}
|
if (bottomPosition < that.maxHeight) {
|
that.selectStyle = "bottom:" + (elementHeight + 4) + "px;top:auto;max-height:" + that
|
.maxHeight + "px;";
|
} else {
|
that.selectStyle = "bottom:auto;top:calc(100% + 4px);max-height:" + that.maxHeight +
|
"px;";
|
}
|
}
|
}).exec();
|
},
|
clear() {
|
this.keyword = '';
|
this.setListAsKeyword();
|
this.$emit('clear', {});
|
},
|
setListAsKeyword() {
|
if (!this.keyword) {
|
this.list = this.$props.localdata;
|
} else {
|
var lst = [];
|
for (var i in this.$props.localdata) {
|
if (this.$props.localdata[i].title.indexOf(this.keyword) >= 0) {
|
lst.push(this.$props.localdata[i]);
|
}
|
}
|
let obj = this.$props.localdata.find(ite => ite.title == this.keyword)
|
this.$emit('change', obj ? obj : this.keyword)
|
this.list = lst;
|
}
|
this.setPosition();
|
},
|
update() {
|
this.keyword = '';
|
this.list = this.$props.localdata;
|
if(this.value){
|
return this.keyword = this.value
|
}
|
if (this.$props.selectedId !== '') {
|
for (var i in this.list) {
|
if (this.list[i].id == this.$props.selectedId) {
|
this.keyword = this.list[i].title;
|
}
|
}
|
}
|
},
|
toggleSelector() {
|
if (!this.$props.disabled) {
|
let that = this;
|
this.setPosition();
|
setTimeout(function() {
|
that.showSelector = !that.showSelector
|
}, 20);
|
}
|
},
|
change(item) {
|
if (!this.$props.disabled) {
|
this.$data.keyword = item.title;
|
this.$emit('change', item);
|
this.showSelector = false;
|
}
|
}
|
}
|
}
|
</script>
|
|
<style>
|
/* @import "./iconfont/iconfont.css"; */
|
.form-select {
|
display: flex;
|
justify-content: flex-end;
|
align-items: center;
|
width: 100%;
|
cursor: pointer;
|
}
|
|
.uni_select {
|
font-size: 14px;
|
box-sizing: border-box;
|
position: relative;
|
/* #ifndef APP-NVUE */
|
display: flex;
|
user-select: none;
|
/* #endif */
|
flex-direction: row;
|
align-items: center;
|
justify-content: space-between;
|
width: 100%;
|
/* padding:0 12px; */
|
}
|
|
.uni_select_input_box {
|
width: 100%;
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
/* height: 40px; */
|
}
|
|
.uni_select_mask {
|
position: fixed;
|
top: 0;
|
bottom: 0;
|
right: 0;
|
left: 0;
|
z-index: 2;
|
}
|
|
.uni_select_selector {
|
/* #ifndef APP-NVUE */
|
box-sizing: border-box;
|
/* #endif */
|
position: absolute;
|
left: 0;
|
width: 100%;
|
background-color: #FFFFFF;
|
border: 0.5px solid #DFE7E1;
|
border-radius: 4px;
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
z-index: 3;
|
overflow: hidden;
|
}
|
|
.uni_select_input_text_tips {
|
overflow: hidden;
|
height: 40px;
|
line-height: 40px;
|
color: #7d7a7a;
|
}
|
|
.uni_select_input_text {
|
height: 40px;
|
line-height: 40px;
|
overflow: hidden;
|
color: black;
|
}
|
|
.uni_select_selector_scroll {
|
/* #ifndef APP-NVUE */
|
max-height: 288px;
|
box-sizing: border-box;
|
/* #endif */
|
}
|
|
.uni_select_selector_empty,
|
.uni_select_selector_item {
|
/* #ifndef APP-NVUE */
|
display: flex;
|
cursor: pointer;
|
/* #endif */
|
line-height: 36px;
|
|
font-size: 14px;
|
text-align: center;
|
/* border-bottom: solid 1px #DDDDDD; */
|
padding: 0px 10px;
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
}
|
|
.select-text {
|
line-height: 36px;
|
height: 36px;
|
word-break: break-all;
|
overflow: hidden;
|
}
|
|
.uni_select_selector_item_this {
|
background-color: rgb(21, 197, 206);
|
}
|
|
.uni_select_selector_empty:last-child,
|
.uni_select_selector_item:last-child {
|
/* #ifndef APP-NVUE */
|
border-bottom: none;
|
/* #endif */
|
}
|
|
._selected {
|
background-color: #e6e6e6;
|
}
|
|
._disabled {
|
color: #c7c4c4;
|
}
|
|
.uni-input-placeholder {
|
color: #bababc;
|
font-size: 13px;
|
}
|
|
.input {
|
caret-color: #2b948d;
|
font-size: 13px;
|
width: calc(100% - 16px);
|
}
|
</style>
|