ButtonSelect.vue 2.77 KB
<template>
  <div class="button-select">
    <div class="selected">
      <span class="select-val" @click="handleSelect">
        {{ selectedVal }}
      </span>
      <van-icon name="clear" v-show="selectedVal" @click="handleClear" />
      <van-icon name="arrow" @click="handleSelect" />
    </div>
    <van-action-sheet
      v-model="show"
      :actions="actionList"
      cancel-text="取消"
      close-on-click-action
      :close-on-click-overlay="false"
      class="bottom-action"
      @select="onSelect"
      @cancel="onCancel"
    />
  </div>
</template>

<script>
  export default {
    name: 'ButtonSelect',
    props: {
      value: {
        type: String,
        default: '',
      },
      bindKey: {
        type: String,
        default: 'id',
      },
      actions: {
        type: Array,
        default: () => [],
      },
      props: {
        type: Object,
        default: () => {
          return {
            key: 'key',
            name: 'name',
          }
        },
      },
    },
    data() {
      return {
        show: false,
        selectedVal: '',
      }
    },
    computed: {
      actionList() {
        return this.actions.map((item) => {
          return {
            key: item[this.props.key],
            name: item[this.props.name],
          }
        })
      },
    },
    watch: {
      value: {
        handler(val) {
          if (val) {
            this.selectedVal = this.actionList.find(
              (item) => item.key === val
            )?.name
          }
        },
        immediate: true,
      },
    },
    methods: {
      onCancel() {
        this.show = false
      },
      handleSelect() {
        this.show = true
      },
      onSelect(val) {
        this.selectedVal = val.name
        this.$emit('input', val.key)
      },
      handleClear() {
        this.selectedVal = ''
        this.$emit('input', '')
      },
    },
  }
</script>

<style lang="scss" scoped>
  .button-select {
    width: 100%;
    .selected {
      width: 100%;
      justify-content: flex-end;
      display: flex;
      align-items: center;
      .select-val {
        display: inline-flex;
        justify-content: flex-end;
        color: $base-text-color;
        flex: 1;
        height: 20px;
        line-height: 20px;
      }
      .van-icon-clear {
        color: $base-gray-disabled-text-color;
        font-size: $base-font-size-big;
        padding-left: 8px;
        margin-top: 1px;
      }
      .van-icon-arrow {
        padding-left: 4px;
        margin-top: 2px;
        font-size: $base-font-size-bigger;
        color: $base-gray-text-color;
      }
    }
  }
  .button-select .bottom-action {
    min-height: 35vh;
    .van-action-sheet__content {
      overflow-y: scroll;
    }
  }
  .reject-method .bottom-action {
    min-height: 26vh;
  }
</style>