vue3 PC端自定义一个拨打电话的软键盘实现

对接的第三方平台在浏览器上进行的拨号,挂号,通话过程中需要进行的输入有时就需要有一个可以看见的数字按键键盘让我们可以看到自己的操作.

效果展示:

对应代码:

由于框架里面存在将 px 转换成rem 的自动转换组件,所以直接复制存在一些偏差.

文件目录是 

index.vue :
 

<template>
  <div class="float_view_phone" ref="floatButton" @click="showSoftKeyboard">
    <el-icon :size="22" color="white"><PhoneFilled /></el-icon>
  </div>

  <SK :isShow="skVisible" @close="skVisible = false" />
</template>

<script setup>
import SK from "./SK.vue";
import { ref, onMounted, onBeforeUnmount } from "vue";
const skVisible = ref(false);
const floatButton = ref(null);

const mouseMoveHandler = (event) => {
  const mouseX = event.clientX;
  const buttonRect = floatButton.value.getBoundingClientRect();
  // 判断鼠标是否靠近按钮
  if (mouseX > window.innerWidth - buttonRect.width - 20) {
    floatButton.value.classList.add("show");
  } else {
    floatButton.value.classList.remove("show");
  }
};

const showSoftKeyboard = () => {
  skVisible.value = !skVisible.value;
};

onMounted(() => {
  document.addEventListener("mousemove", mouseMoveHandler);
});

onBeforeUnmount(() => {
  document.removeEventListener("mousemove", mouseMoveHandler);
});
</script>

<style lang="less" scoped>
.float_view_phone {
  position: fixed;
  right: -20px;
  bottom: 100px;
  border-radius: 50%;
  width: 40px;
  height: 40px;
  background-color: #1677ff;
  box-shadow: 0 6px 16px 0 rgba(0, 0, 0, 0.08),
    0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 9px 28px 8px rgba(0, 0, 0, 0.05);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  opacity: 0.5;
  transition: all 0.3s linear;

  &.show {
    opacity: 1;
    right: 5px;
  }

  &:hover {
    opacity: 0.9;
  }
}
</style>

SK.vue

<template>
  <!-- 
  name="fade"
  enter-active-class="animate__animated animate__fadeInRight"
  leave-active-class="animate__animated animate__fadeOutRight" 
  -->
  <transition name="moveCartoon" appear>
    <div class="sk-contain" v-show="isShow">
      <input type="text" v-model.trim="fjPhone" placeholder="请输入..." />
      <div class="btns">
        <button @click="$emit('close')">取消</button>
        <button>确认</button>
      </div>
      <ul class="sk-box">
        <li @click="keyChange(item)" v-for="item in keyNodes" :key="item">
          {{ item }}
        </li>
      </ul>
    </div>
  </transition>
</template>

<script setup>
import { ref, defineProps } from "vue";
const props = defineProps({
  isShow: {
    type: Boolean,
    default: false,
  },
});
const fjPhone = ref("");
const keyNodes = [1, 2, 3, 4, 5, 6, 7, 8, 9, "#", 0, "删除"];
const keyChange = (key) => {
  if (key == "删除") {
    fjPhone.value = fjPhone.value.slice(0, -1);
  } else {
    fjPhone.value += key;
  }
};
</script>

<style lang="less" scoped>
.moveCartoon-enter-active {
  animation: move 0.5s;
}
.moveCartoon-leave-active {
  animation: move 0.3s reverse;
}

@keyframes move {
  from {
    transform: translateX(100%);
  }
  to {
    transform: translate(0);
  }
}
.sk-contain {
  position: fixed;
  right: 20px;
  bottom: 150px;
  width: 250px;
  // height: 350px;
  background-color: #dfebff; /* 半透明背景 */
  // backdrop-filter: blur(2px); /* 应用模糊效果 */
  border-radius: 5px; /* 可选:添加圆角 */
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); /* 可选:添加阴影 */
  text-align: center;
  input {
    height: 44px;
    width: 90%;
    margin: 10px auto 5px;
    outline: none;
    border: none;
    border-radius: 4px; /* 添加圆角 */
    background-color: #c9daf9; /* 设置背景色,使用半透明白色 */
    padding: 2px 10px;
    box-sizing: border-box;

    &::placeholder {
      font-size: 12px;
    }
  }

  .btns {
    text-align: right;
    padding: 5px 5%;
    margin-bottom: 10px;

    button {
      margin-left: 10px;
      width: 55px;
      height: 32px;
      font-size: 14px;
      border-radius: 5px;
      border: none;
      background-color: #82a4e1;
      cursor: pointer;

      &:nth-of-type(1) {
        background-color: transparent;
        outline: none;
        border: 2px solid #647fb9;
        color: #5c83b9;
        &:active {
          background-color: #ccc !important; /* 点击时背景色 */
        }
      }
      &:nth-of-type(2) {
        border: none;
        background-color: #82a4e1;
        color: white;
        &:active {
          background-color: rgb(163, 148, 148) 4e1 !important; /* 点击时背景色 */
        }
      }
    }
  }

  .sk-box {
    padding: 8px 5px;
    background-color: #bdcbe2;
    display: grid;
    grid-template-rows: repeat(4, 35px);
    grid-template-columns: repeat(3, 1fr);
    gap: 5px;

    li {
      background-color: #dfebff;
      border-radius: 5px;
      display: grid;
      place-items: center;
      font-size: 14px;
      transition: all 0.3s linear;
      cursor: pointer;
      &:hover {
        opacity: 0.8;
        box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
      }

      &:active {
        background-color: #aab9d3; /* 点击时背景色 */
      }
    }
  }
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值