WXL
3 天以前 2cc85c64f1c64a2dbaeae276a3e2ca8420de76b7
node_modules/uview-plus/components/u-select/u-select.vue
@@ -1,6 +1,6 @@
<template>
   <view class="u-select">
      <view class="u-select__content">
      <view :class="['u-select__content', disabled && 'disabled']">
         <view class="u-select__label" @click="openSelect">
            <slot name="text" :currentLabel="currentLabel">
               <text class="u-select__text" v-if="showOptionsLabel">
@@ -14,26 +14,16 @@
               <up-icon name="arrow-down" :size="iconSize" :color="iconColor"></up-icon>
            </slot>
         </view>
         <u-overlay
            :show="isOpen"
            @click="overlayClick"
            v-if="overlay"
            :zIndex="zIndex"
            :duration="duration + 50"
            :customStyle="overlayStyle"
            :opacity="overlayOpacity"
            @touchmove.stop.prevent="noop"
         ></u-overlay>
         <u-overlay :show="isOpen" @click="overlayClick" v-if="overlay" :zIndex="zIndex" :duration="duration + 50"
            :customStyle="overlayStyle" :opacity="overlayOpacity" @touchmove.stop.prevent="noop"></u-overlay>
         <view class="u-select__options__wrap"
            :style="{ overflowY: 'auto', zIndex: zIndex + 1, left: optionsWrapLeft, right: optionsWrapRight, maxHeight: maxHeight}">
            <view class="u-select__options" v-if="isOpen">
               <slot name="options">
                  <view class="u-select__options_item"
                     :class="current == item[keyName] ? 'active': ''"
                     :key="index" v-for="(item, index) in options"
                     @click="selectItem(item)">
                  <view class="u-select__options_item" :class="current == item[keyName] ? 'active': ''"
                     :key="index" v-for="(item, index) in options" @click="selectItem(item)">
                     <slot name="optionItem" :item="item">
                        <text class="u-select__item_text" :style="{color: itemColor}">
                        <text class="u-select__item_text" :style="{color: itemColor}">
                           {{item[labelName]}}
                        </text>
                     </slot>
@@ -46,173 +36,206 @@
</template>
<script>
import { getWindowInfo } from '../../libs/function/index';
export default {
   name:"up-select",
   emits: ['update:current', 'select'],
   props: {
      maxHeight: {
         type: String,
         default: '90vh'
      },
      overlay: {
         type: Boolean,
         default: true
      },
      overlayOpacity: {
         type: Number,
         default: 0.01
      },
      overlayStyle: {
         type: Object,
         default: () => {
            return {}
         }
      },
      duration: {
         type: Number,
         default: 300
      },
      label: {
         type: String,
         default: '选项'
      },
      options: {
         type: Array,
         default: () => {
            return []
         }
      },
      keyName: {
         type: String,
         default: 'id'
      },
      labelName: {
         type: String,
         default: 'name'
      },
      showOptionsLabel: {
         type: Boolean,
         default: false
      },
      current: {
         type: [String, Number],
         default: ''
      },
      zIndex: {
         type: Number,
         default: 11000
      },
      itemColor: {
         type: String,
         default: '#333333'
      },
      iconColor: {
         type: String,
         default: ''
      },
      iconSize: {
         type: [String],
         default: '13px'
      }
   },
   data() {
      return {
         isOpen: false,
         optionsWrapLeft: 'auto',
         optionsWrapRight: 'auto'
      }
   },
   computed: {
      currentLabel() {
         let name = '';
         this.options.forEach((ele) => {
            if (ele[this.keyName] === this.current) {
               name = ele[this.labelName];
   import {
      mpMixin
   } from '../../libs/mixin/mpMixin';
   import {
      mixin
   } from '../../libs/mixin/mixin';
   import {
      getWindowInfo
   } from '../../libs/function/index';
   export default {
      name: "up-select",
      mixins: [mpMixin, mixin],
      emits: ['update:current', 'select'],
      props: {
         maxHeight: {
            type: String,
            default: '90vh'
         },
         overlay: {
            type: Boolean,
            default: true
         },
         overlayOpacity: {
            type: Number,
            default: 0.01
         },
         overlayStyle: {
            type: Object,
            default: () => {
               return {}
            }
         });
         return name;
         },
         duration: {
            type: Number,
            default: 300
         },
         label: {
            type: String,
            default: '选项'
         },
         options: {
            type: Array,
            default: () => {
               return []
            }
         },
         keyName: {
            type: String,
            default: 'id'
         },
         labelName: {
            type: String,
            default: 'name'
         },
         showOptionsLabel: {
            type: Boolean,
            default: false
         },
         current: {
            type: [String, Number],
            default: ''
         },
         zIndex: {
            type: Number,
            default: 11000
         },
         itemColor: {
            type: String,
            default: '#333333'
         },
         iconColor: {
            type: String,
            default: ''
         },
         iconSize: {
            type: [String],
            default: '13px'
         },
         // 是否禁用
         disabled: {
            type: Boolean,
            default: false
         }
      },
      data() {
         return {
            isOpen: false,
            optionsWrapLeft: 'auto',
            optionsWrapRight: 'auto'
         }
      },
      computed: {
         currentLabel() {
            let name = '';
            this.options.forEach((ele) => {
               if (ele[this.keyName] === this.current) {
                  name = ele[this.labelName];
               }
            });
            return name;
         }
      },
      methods: {
         openSelect() {
            if (this.disabled) return;
            this.isOpen = true;
            this.$nextTick(() => {
               if (this.isOpen) {
                  this.adjustOptionsWrapPosition();
               }
            });
         },
         closeSelect() {
            this.isOpen = false;
         },
         overlayClick() {
            this.isOpen = false;
         },
         selectItem(item) {
            this.isOpen = false;
            this.$emit('update:current', item[this.keyName]);
            this.$emit('select', item);
         },
         adjustOptionsWrapPosition() {
            let wi = getWindowInfo();
            let windowWidth = wi.windowWidth;
            this.$uGetRect('.u-select__options__wrap').then(rect => {
               if (rect.left + rect.width > windowWidth) {
                  // 如果右侧被遮挡,则调整到左侧
                  this.optionsWrapLeft = 'auto';
                  this.optionsWrapRight = `0px`;
               }
            });
         }
      }
    },
    methods: {
      openSelect() {
        this.isOpen = true;
      this.$nextTick(() => {
         if (this.isOpen) {
            this.adjustOptionsWrapPosition();
         }
      });
      },
     overlayClick() {
        this.isOpen = false;
     },
      selectItem(item) {
        this.isOpen = false;
        this.$emit('update:current', item[this.keyName]);
        this.$emit('select', item);
      },
     adjustOptionsWrapPosition() {
      let wi = getWindowInfo();
      let windowWidth = wi.windowWidth;
      this.$uGetRect('.u-select__options__wrap').then(rect => {
         console.log(rect)
         if (rect.left + rect.width > windowWidth) {
            // 如果右侧被遮挡,则调整到左侧
            this.optionsWrapLeft = 'auto';
            this.optionsWrapRight = `0px`;
         }
      });
     }
    }
}
   }
</script>
<style lang="scss" scoped>
  .u-select__content {
    position: relative;
    .u-select__label {
      display: flex;
     justify-content: space-between;
      /* #ifdef H5 */
      &:hover {
        cursor: pointer;
      }
      /* #endif */
    }
    .u-select__text {
      margin-right: 2px;
    }
   .u-select__options__wrap {
      margin-bottom: 46px;
      position: absolute;
      top: 20px;
      left: 0;
   .u-select__content {
      position: relative;
      .u-select__label {
         display: flex;
         justify-content: space-between;
         /* #ifdef H5 */
         &:hover {
            cursor: pointer;
         }
         /* #endif */
      }
      .u-select__text {
         margin-right: 2px;
      }
      &.disabled {
         opacity: 0.6;
         pointer-events: none;
      }
      .u-select__options__wrap {
         margin-bottom: 46px;
         position: absolute;
         top: 20px;
         left: 0;
      }
      .u-select__options {
         min-width: 100px;
         box-sizing: border-box;
         border-radius: 4px;
         border: 1px solid #f1f1f1;
         background-color: #fff;
         .u-select__options_item {
            padding: 10px 12px;
            box-sizing: border-box;
            width: 100%;
            height: 100%;
            &:hover {
               background-color: #f7f7f7;
            }
            /* #ifdef H5 */
            &:hover {
               cursor: pointer;
            }
            .u-select__item_text {
               &:hover {
                  cursor: pointer;
               }
            }
            /* #endif */
         }
      }
   }
    .u-select__options {
      min-width: 100px;
     box-sizing: border-box;
      border-radius: 4px;
      border: 1px solid #f1f1f1;
      background-color: #fff;
      .u-select__options_item {
        padding: 10px 12px;
      box-sizing: border-box;
        width: 100%;
        height: 100%;
        &:hover {
          background-color: #f7f7f7;
        }
        /* #ifdef H5 */
        &:hover {
          cursor: pointer;
        }
        .u-select__item_text {
          &:hover {
            cursor: pointer;
          }
        }
        /* #endif */
      }
    }
  }
</style>