popup-dict.vue 3.22 KB
<template>
  <tui-bottom-popup :show="visible" @close="onClose">
    <view class="popup-dict">
      <view class="popup-dict__content">
        <picker-view class="picker-view" indicator-class="popup-dict__indicator" :value="pickerValue" @change="onPickerChange">
          <picker-view-column class="popup-dict__column">
            <template v-for="(item, index) in options">
              <view class="popup-dict__item" :key="index">
                <slot v-if="$slots.default || $slots.$default" :item="item"></slot>
                <text v-else>{{ item[labelKey] }}</text>
              </view>
            </template>
          </picker-view-column>
        </picker-view>
      </view>
      <view class="popup-dict__footer">
        <zui-button block @click="onCancel">取消</zui-button>
        <zui-button block type="primary" @click="onSubmit">确定</zui-button>
      </view>
    </view>
  </tui-bottom-popup>
</template>

<script>
import { mapGetters } from 'vuex';

export default {
  name: 'popup-dict',
  props: {
    value: Boolean,
    dict: String,
    list: Array,
    labelKey: {
      type: String,
      default: 'valueName'
    },
    valueKey: {
      type: String,
      default: 'valueCode'
    },
    custom: Boolean
  },
  data: function() {
    return {
      pickerValue: [0],
      visible: this.value,
    };
  },
  computed: {
    ...mapGetters(['dictList', 'dictValue']),
    options: function() {
      if (this.list && this.list.length > 0) {
        return this.list;
      } else {
        return this.dict ? this.dictList(this.dict) : [];
      }
    }
  },
  watch: {
    value: function(val) {
      if (this.options.length === 0) {
        if (val) {
          uni.showToast({
            title: '没有可选值',
            icon: 'none'
          });
          this.$emit('input', false);
        }
      } else if (this.options.length > 0 && this.options.length <= 6 && !this.custom) {
        if (val) {
          uni.showActionSheet({
            cancelButtonText: '取消',
            itemList: this.options.map(i => i[this.labelKey]),
            success: (res) => {
              this.$emit('confirm', this.options[res.tapIndex]);
            },
            complete: () => {
              this.$emit('input', false);
            }
          });
        }
      } else {
        this.visible = !!val;
      }
    }
  },
  methods: {
    onPickerChange: function (e) {
      this.pickerValue = e.detail.value;
    },
    onClose: function() {
      this.$emit('visible', false);
    },
    onSubmit: function() {
      const index = this.pickerValue[0];
      this.$emit('confirm', this.options[index]);
    },
    onCancel: function() {
      this.$emit('input', false);
    }
  }
};
</script>

<style lang="scss">
.popup-dict {
  background: #fff;
  padding-bottom: $padding-md;
  &__content {
    display: flex;
    justify-content: space-between;
    .picker-view {
      width: 100%;
    }
  }
  &__column {
    height: 400upx;
  }
  &__item {
    display: flex;
    align-items: center;
    justify-content: center;
  }
  &__footer {
    padding: $padding-md;
    display: flex;
    flex: auto;
    align-items: center;
    justify-content: center;
    .zui-button:first-child {
      margin-right: $padding-md;
    }
  }
}
</style>