keyboard-waybill.vue 4.42 KB
<template>
  <tui-bottom-popup :show="visible" @close="onClose">
    <view class="keyboard-waybill">
      <view class="keyboard-waybill__keyboard">
        <view v-for="word in wordText" :key="word" class="key" hover-class="active" hover-start-time="20" hover-stay-time="70" @click="onInput(word)">{{ word }}</view>
        <view v-for="number in numberText" :key="number" class="key" hover-class="active" hover-start-time="20" hover-stay-time="70" @click="onInput(number)">{{ number }}</view>
      </view>
      <view class="keyboard-waybill__footer">
        <view class="left">
          <view class="btn delete" hover-class="active" hover-start-time="20" hover-stay-time="70" @click="onDelete">删除</view>
          <view class="btn paste" hover-class="active" hover-start-time="20" hover-stay-time="70" @click="onPaste">粘贴</view>
        </view>
        <view class="btn confirm" hover-class="active" hover-start-time="20" hover-stay-time="70" @click="onConfirm">{{ confirmText }}</view>
      </view>
    </view>
  </tui-bottom-popup>
</template>

<script>
export default {
  name: 'keyboard-waybill',
  props: {
    value: String,
    visible: Boolean,
    confirmText: {
      type: String,
      default: '确定'
    },
  },
  data: function() {
    return {
      model: [],
      numberText: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'],
      wordText: ['Y', 'P'],
    };
  },
  computed: {
    modelText: function() {
      return this.model.join('');
    }
  },
  watch: {
    value: function(val) {
      this.model = `${val || ''}`.split('') || [];
    },
  },
  methods: {
    onClose: function() {
      this.$emit('visible', false);
    },
    onInput: function(key) {
      this.model.push(key);
      this.$emit('input', this.modelText);
    },
    onDelete: function() {
      this.model.pop();
      this.$emit('input', this.modelText);
    },
    onPaste: function() {
      uni.getClipboardData({
        success: (res) => {
          this.$emit('input', res.data);
        }
      });
    },
    onConfirm: function() {
      this.$emit('confirm', this.modelText);
    }
  }
};
</script>

<style lang="scss">
.keyboard-waybill {
  background-color: $color-white;
  &__keyboard {
    padding: 10upx 10upx 0;
    box-sizing: border-box;
    transition: all .3s;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    background-color: $color-field;
    .key {
      width: 175upx;
      height: 175upx;
      border-radius: 10upx;
      display: flex;
      align-items: center;
      justify-content: center;
      color: $color-black;
      position: relative;
      margin-bottom: $padding-xs;
      background-color: $color-white;
      font-size: $font-lg;
      &.delete, &.confirm {
        width: 160upx;
      }
      &.confirm {
        background-color: $color-primary;
        color: $color-white;
      }
      &.active {
        background-color: darken($color-white, 15%);
      }
      &::after {
        padding: 0;
        margin: 0;
        border: none;
        content: "";
        pointer-events: none; /* 防止点击触发 */
        box-sizing: border-box;
        position: absolute;
        width: 200%;
        height: 200%;
        left: 0;
        top: 0;
        border: 1upx solid $color-border;
        border-radius: 20upx;
        transform: scale(0.5);
        transform-origin: 0 0;
      }
    }
  }
  &__footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: $padding-md 10upx;
    .left {
      display: flex;
      align-items: center;
    }
    .btn {
      font-size: $font-md;
      padding: $padding-md;
      width: 200upx;
      box-sizing: border-box;
      border-radius: 10upx;
      position: relative;
      display: flex;
      align-items: center;
      justify-content: center;
      &::after {
        padding: 0;
        margin: 0;
        border: none;
        content: "";
        pointer-events: none; /* 防止点击触发 */
        box-sizing: border-box;
        position: absolute;
        width: 200%;
        height: 200%;
        left: 0;
        top: 0;
        border: 1upx solid $color-border;
        border-radius: 20upx;
        transform: scale(0.5);
        transform-origin: 0 0;
      }
      &.confirm {
        background-color: $color-primary;
        color: $color-white;
      }
      &.paste {
        margin-left: $padding-sm;
      }
      &.active {
        background-color: darken($color-white, 15%);
      }
    }
  }
}
</style>