123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- <template>
- <view class="form-select">
- <view class="uni_select">
- <view class="uni_select_input_box" @click="toggleSelector">
- <view v-if="!current" class="uni_select_input_text_tips" :class="disabled?'_disabled':''">{{placeholder}}</view>
- <view v-if="current" class="uni_select_input_text" :class="disabled?'_disabled':''">{{current}}</view>
- <view v-if="icon" class="iconfont" :class="showSelector ? 'icon-to-up'+(disabled?' _disabled':'') : 'icon-to-down'+(disabled?' _disabled':'')"></view>
- </view>
- <view class="uni_select_mask" v-if="showSelector" @click="toggleSelector" />
- <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="localdata.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.userId == selectedId ? '_selected' : (item.disabled?'_disabled':'')" v-for="(item,index) in localdata"
- :key="index" @click="change(item)">
- <view class="select-text" style="word-break: break-all;">{{item.nickName}}</view>
- <view v-if="item.icon" :class="item.icon" :style="item.color?'color:'+item.color:''"></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} icon 是否显示下拉图标
- * @property {Boolean} disabled 是否禁止选择
- * @property {String, Number} tag 标签,对于一个页面同时使用多次该组件时,并且选择后的回调为相同的函数时,可使用该标签进行区分
- * @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: '没有更多选项了'
- },
- icon: {
- type: Boolean,
- default: false
- },
- disabled:{
- type: Boolean,
- default: false
- },
- tag: {
- type: [String, Number],
- default: ''
- },
- },
- data() {
- return {
- current:'',
- showSelector:false,
- selectStyle:'',
- maxHeight:288,
- };
- },
- mounted(){
- this.update();
- this.$nextTick(() => {
- this.setPosition();
- });
- },
- methods:{
- setPosition() {
- let that = this;
- if(this.$props.localdata.length < 8){
- if(this.$props.localdata.length > 0){
- this.maxHeight = (this.$props.localdata.length*36)+10;
- }
- }
- 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){
- 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();
- },
- update(){
- this.$data.current = '';
- if(this.$props.selectedId !== ''){
- for(var i in this.$props.localdata){
- if(this.$props.localdata[i].userId == this.$props.selectedId){
- this.$data.current = this.$props.localdata[i].nickName;
- }
- }
- }
- },
- toggleSelector() {
- if(!this.disabled){
- let that = this;
- this.setPosition();
- setTimeout(function(){
- that.showSelector = !that.showSelector
- },20);
- }
- },
- change(item){
- if(!item.disabled){
- this.$data.current = item.nickName;
- item.tag = this.$props.tag;
- 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;
- }
- .uni_select_mask {
- position: fixed;
- top: 0;
- bottom: 0;
- right: 0;
- left: 0;
- }
- .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: 2;
- 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;
- }
- </style>
|