123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- <template>
- <view class="u-select">
- <view class="u-select__content">
- <view class="u-select__label" @click="openSelect">
- <slot name="text">
- <text class="u-select__text" v-if="showOptionsLabel">
- {{ currentLabel }}
- </text>
- <text class="u-select__text" v-else>
- {{ label }}
- </text>
- </slot>
- <slot name="icon">
- <u-icon name="arrow-down" :size="iconSize" :color="iconColor"></u-icon>
- </slot>
- </view>
- <u-overlay
- :show="isOpen"
- @click="overlayClick"
- v-if="overlay"
- :zIndex="zIndex"
- :duration="duration + 50"
- :customStyle="overlayStyle"
- :opacity="overlayOpacity"
- ></u-overlay>
- <view class="u-select__options__wrap"
- :style="{ zIndex: zIndex + 1, left: optionsWrapLeft, right: optionsWrapRight }">
- <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)">
- <slot name="optionItem" :item="item">
- <text class="u-select__item_text" :style="{color: itemColor}">
- {{item[labelName]}}
- </text>
- </slot>
- </view>
- </slot>
- </view>
- </view>
- </view>
- </view>
- </template>
- <script>
- import { getWindowInfo } from '../../libs/function/index';
- export default {
- name:"up-select",
- emits: ['update:current', 'select'],
- props: {
- 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];
- }
- });
- return name;
- }
- },
- 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__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>
|