<template>
    <div class="numberKeyboard_wrapper" ref="keyboard">
      <transition name="keyboard">
        <div v-if="show" class="numberKeyboard_body">
          <div v-for="item in keyboardList" :key="item.value" class="numberKeyboard_body_item" @click="clickKeyboard(item)">
            {{ item.label }}
          </div>
        </div>
      </transition>
    </div>
  </template>
  <script>
  export default {
    props: {
      visible: { // 显示控制
        type: Boolean,
        required: true
      },
      value: {  // v-model传入的值
        type: String,
        default: ''
      },
      inputElement: { // 传入整页dom节点 || 输入框dom节点（根据需求选择测试）
        type: [Object, HTMLElement],
        default: () => ({})
      }
    },
    data() {
      return {
        keyboardList: [
          { label: "1", value: "1" },
          { label: "2", value: "2" },
          { label: "3", value: "3" },
          { label: "4", value: "4" },
          { label: "5", value: "5" },
          { label: "6", value: "6" },
          { label: "7", value: "7" },
          { label: "8", value: "8" },
          { label: "9", value: "9" },
          { label: ".", value: "." },
          { label: "0", value: "0" },
          { label: "退格", value: "-1" },
        ]
      }
    },
    computed: {
      show: {
        get() {
          return this.visible
        },
        set(newVal) {
          this.$emit('update:visible', newVal)
        }
      },
      keyboardValue: { // 利用计算属性更新
        get() {
          return this.value
        },
        set(newVal) {
          this.$emit('input', newVal)
        }
      }
    },
    watch: {
      // 禁止背景滚动 && 键盘显示时，判断距离会遮住输入框dom时，把输入框dom往上推
      show(newVal) {
        if(newVal) {
          document.body.style.overflow = "hidden";
        } else {
          document.body.style.overflow = "";
        }
        Object.keys(this.inputElement).length > 0 && this.keyboardHandle(newVal) // 有传入dom时执行
      },
    },
    methods: {
      // 键盘显示时，判断距离会遮住输入框dom时，把输入框dom往上推
      async keyboardHandle(visible) {
        await this.$nextTick()
        if (visible) { // 键盘打开
          const inputElement = this.inputElement // 输入框dom
          const keyboardElement = this.$refs.keyboard //键盘组件dom
          const windowHeight = window.innerHeight; // 游览器视口高度
          const inputElementTop = inputElement.getBoundingClientRect().bottom; // 输入框dom元素底部 距离当前视口顶部距离
          const keyboardTop = windowHeight - keyboardElement.offsetHeight // 可视高度 - 键盘高度 = 键盘距离可视区域顶部距离
          if (inputElementTop > keyboardTop) { // 输入框被键盘遮挡情况
            console.log('输入框被键盘遮挡了')
            inputElement.style.transition = "transform 0.3s" // 加上过渡效果
            inputElement.style.transform = `translateY(-${
              inputElementTop - (windowHeight - keyboardElement.offsetHeight)
            }px)`;
          } else {
            console.log('输入框没有被键盘遮挡情况')
          }
        } else { // 键盘关闭，恢复输入框的位置
          this.inputElement.style.transform = "translateY(0)";
        }
      },
      // 点击键盘按钮回调
      // 更新计算属性值 会自动触发更新 value值
      clickKeyboard({ value, label }) {
        const decimalPoint =  /\./g // 小数点正则
        switch (value) {
          case '-1':
            this.keyboardValue = this.keyboardValue.slice(0, -1)
            break;
          case '.': // 只允许输入一个小数点
            if (!decimalPoint.test(this.keyboardValue)) {
              this.keyboardValue += label
            }
            break
          default:
            this.keyboardValue += label
            break;
        }
        this.$emit('change', this.keyboardValue)
      },
      // 点击键盘外部区域关闭键盘
      handleOutsideClick(event) {
        if (this.$refs.keyboard && !this.$refs.keyboard.contains(event.target)) {
         this.show = false
        }
      }
    },
    mounted() {
      // 插入body
      document.body.appendChild(this.$el);
      // 添加全局关闭事件侦听器
      document.addEventListener('click', this.handleOutsideClick, true);
    },
    destroyed() {
      // 组件销毁后同步清除元素
      this.$el.parentNode.removeChild(this.$el);
      // 移除全局关闭事件侦听器
      document.removeEventListener('click', this.handleOutsideClick, true);
    }
  }
  </script>
  <style lang="less" scoped>
  .numberKeyboard{
    &_wrapper{
      width: 100%;
      position: fixed;
      bottom: 0;
      left: 0;
      display: flex;
      justify-content: center;
    }
    &_body{
      width: 100%;
      max-width: 800px;
      height: 40vh;
      background-color:#f2f3f5;
      display: flex;
      flex-wrap: wrap;
      padding: 10px;
      border-radius: 10px 10px 0 0;
      border: 1px solid #EBEEF5;
      &_item{
        flex: 1 1 calc(33.333% - 10px);
        margin-right: 10px;
        background-color: #fff;
        margin-bottom: 10px;
        border-radius: 10px;
        font-size: 22px;
        display: flex;
        align-items: center;
        justify-content: center;
        font-weight: bold;
        cursor: pointer;
      }
      &_item:active{
        background-color: #dcdee0;
      }
      &_item:nth-child(3n) {
        margin-right: 0;
      }
      &_item:nth-child(n+10):nth-child(-n+12){
        margin-bottom: 0;
      }
    }
  }
  
  .keyboard-enter-active,.keyboard-leave-active { // 元素进入和离开时的过渡动画定义
    transition: transform 0.3s;
  }
  .keyboard-enter,.keyboard-leave-to { // 元素进入和离开时的动作
    transform: translateY(100%);
  }
  </style>
  