select-dict.vue 2.22 KB
<template>
  <view class="select-dict">
    <u-cell :title="title" is-link :required="required" @click="openPicker">
      <template #value>
        <render-dict v-if="value" :dict="dict" :value="value" />
        <text v-else class="placeholder">{{ placeholder }}</text>
      </template>
    </u-cell>
    <u-picker ref="picker" :show="visible" :columns="columns" @confirm="onConfirm" @cancel="onClose" :default-index="defaultIndex" immediate-change />
  </view>
</template>

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

export default {
  name: 'SelectDict',
  props: {
    title: String,
    dict: String,
    value: [String, Number, Boolean],
    required: Boolean,
    options: {
      type: Array,
      default: () => [],
    },
    excludes: Array,
    disabled: Boolean,
    placeholder: {
      type: String,
      default: '请选择'
    }
  },
  data() {
    return {
      visible: false,
    };
  },
  computed: {
    ...mapGetters(['dictList']),
    list({ dict, dictList, excludes = [], options = [] }) {
      let hash = {};
      const matchDictList = dictList(dict) || [];
      return [...matchDictList, ...options]
        .reduce((result, item) => {
          if (!hash[`${item.valueCode}`]) {
            hash[`${item.valueCode}`] = true;
            if (`${item.valueCode || ''}` && `${item.valueName || ''}` && !excludes.includes(item.valueCode)) {
              result.push(item);
            }
          }
          return result; // 返回结果数组
        }, [])
        .sort((a, b) => a.sort - b.sort);
    },
    columns({ list }) {
    	return [list.map(item => item.valueName)];
    },
    defaultIndex() {
      const matchIndex = this.list.findIndex(item => item.valueCode === this.value);
      return [matchIndex > -1 ? matchIndex : 0];
    }
  },
  methods: {
    openPicker() {
      if (!this.disabled) {
        this.visible = true;
      }
    },
    onConfirm({ indexs = [] }) {
      const index = indexs[0];
      const item = this.list[index] || {};
      this.visible = false;
      this.$emit('input', item.valueCode);
    },
    onClose() {
      this.visible = false;
    }
  },
};
</script>

<style lang="scss">
.select-dict {
  .placeholder {
    color: $color-text-placeholder;
    font-weight: normal;
  }
}
</style>