InputButtons.vue 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. <template>
  2. <div class="input-buttons-container">
  3. <!-- 上一个对话按钮 -->
  4. <div class="arrow-icon-circle" @click="handlePrev" :class="{ 'disabled': !canPrev }">
  5. <el-icon class="arrow-icon"><CaretLeft /></el-icon>
  6. </div>
  7. <!-- 下一个对话按钮 -->
  8. <div class="arrow-icon-circle" @click="handleNext" :class="{ 'disabled': !canNext }">
  9. <el-icon class="arrow-icon"><CaretRight /></el-icon>
  10. </div>
  11. </div>
  12. </template>
  13. <script setup>
  14. import { CaretLeft, CaretRight } from '@element-plus/icons-vue';
  15. /**
  16. * InputButtons - 底部控制按钮组件
  17. * 包含上一句/下一句切换按钮
  18. */
  19. /**
  20. * Props 定义
  21. * @prop {Boolean} canPrev - 是否可以切换到上一句
  22. * @prop {Boolean} canNext - 是否可以切换到下一句
  23. */
  24. const props = defineProps({
  25. canPrev: {
  26. type: Boolean,
  27. default: true
  28. },
  29. canNext: {
  30. type: Boolean,
  31. default: true
  32. }
  33. });
  34. /**
  35. * Emits 定义
  36. * @event prev - 切换到上一句
  37. * @event next - 切换到下一句
  38. */
  39. const emit = defineEmits(['prev', 'next']);
  40. const handlePrev = () => {
  41. if (props.canPrev) emit('prev');
  42. };
  43. const handleNext = () => {
  44. if (props.canNext) emit('next');
  45. };
  46. </script>
  47. <style scoped lang="scss">
  48. @use "sass:math";
  49. @function rpx($px) {
  50. @return math.div($px, 750) * 100vw;
  51. }
  52. .input-buttons-container {
  53. position: fixed;
  54. bottom: 0;
  55. left: 0;
  56. right: 0;
  57. display: flex;
  58. align-items: center;
  59. justify-content: center;
  60. width: 100%;
  61. z-index: 10;
  62. transition: all 0.3s ease;
  63. gap: rpx(20);
  64. margin-bottom: 0;
  65. padding-bottom: rpx(10);
  66. }
  67. .arrow-icon-circle {
  68. width: rpx(20);
  69. height: rpx(20);
  70. border-radius: 50%;
  71. border: rpx(1) solid rgba(0, 100, 192);
  72. background: linear-gradient(135deg, #A0DCF0, #50BEF0);
  73. display: flex;
  74. align-items: center;
  75. justify-content: center;
  76. cursor: pointer;
  77. transition: all 0.3s ease;
  78. &:hover:not(.disabled) {
  79. transform: scale(1.1);
  80. box-shadow: 0 rpx(1) rpx(6) rgba(0, 0, 0, 0.3);
  81. }
  82. &:active:not(.disabled) {
  83. transform: scale(0.95);
  84. }
  85. &.disabled {
  86. opacity: 0.5;
  87. cursor: not-allowed;
  88. border-color: rgba(0, 100, 192, 0.3);
  89. background: linear-gradient(135deg, rgba(160, 220, 240, 0.5), rgba(80, 190, 240, 0.5));
  90. }
  91. .arrow-icon {
  92. font-size: rpx(15);
  93. color: #0064BE;
  94. }
  95. }
  96. </style>