index.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. <template>
  2. <div class="count-box">
  3. <span class="label">{{ label }}</span>
  4. <li v-for="(_, index) in numberItems" :key="index" class="number-item">
  5. <span class="number-box">
  6. <i ref="numberBoxes" class="number-list">0123456789.</i>
  7. </span>
  8. </li>
  9. </div>
  10. </template>
  11. <script setup lang="ts">
  12. import { ElMessage } from 'element-plus'
  13. const props = defineProps({
  14. countNumber: {
  15. type: Number,
  16. default: 0,
  17. },
  18. length: {
  19. type: Number,
  20. default: 6,
  21. validator(value: number) {
  22. return value > 0
  23. },
  24. },
  25. label: {
  26. type: String,
  27. default: '总数',
  28. },
  29. })
  30. const numberBoxes = ref<HTMLElement[] | undefined[]>([])
  31. const numberItems = computed(() => {
  32. let numberString = props.countNumber.toString()
  33. if (numberString.length > props.length) {
  34. ElMessage.error(`${props.label}过大`)
  35. numberString = '9'.repeat(props.length)
  36. }
  37. numberString = '0'.repeat(props.length) + numberString
  38. return numberString.slice(-props.length).split('')
  39. })
  40. watch(numberItems, items => {
  41. for (let index = 0; index < numberBoxes.value.length; index++) {
  42. const box = numberBoxes.value[index]
  43. if (box) {
  44. if (items[index] === '.') {
  45. box.style.transform = `translate(-50%, -${1000 / 11}%)`
  46. } else {
  47. box.style.transform = `translate(-50%, -${
  48. (Number(items[index]) * 100) / 11
  49. }%)`
  50. }
  51. }
  52. }
  53. })
  54. </script>
  55. <style scoped lang="scss">
  56. .count-box {
  57. position: relative;
  58. height: 32px;
  59. line-height: 32px;
  60. text-align: center;
  61. list-style: none;
  62. writing-mode: vertical-lr;
  63. text-orientation: upright;
  64. /*文字禁止编辑*/
  65. -moz-user-select: none; /*火狐*/
  66. -webkit-user-select: none; /*webkit浏览器*/
  67. -ms-user-select: none; /*IE10*/
  68. -khtml-user-select: none; /*早期浏览器*/
  69. user-select: none;
  70. overflow: hidden;
  71. .label {
  72. padding-right: 8px;
  73. line-height: 32px;
  74. font-family: DIN, Microsoft YaHei;
  75. font-weight: bold;
  76. color: #101116;
  77. writing-mode: horizontal-tb !important;
  78. text-orientation: none !important;
  79. /*文字禁止编辑*/
  80. -moz-user-select: none; /*火狐*/
  81. -webkit-user-select: none; /*webkit浏览器*/
  82. -ms-user-select: none; /*IE10*/
  83. -khtml-user-select: none; /*早期浏览器*/
  84. user-select: none;
  85. }
  86. .number-item {
  87. width: 32px;
  88. height: 32px;
  89. list-style: none;
  90. margin-right: 4px;
  91. background: #410425;
  92. border-radius: 4px;
  93. border: 1px solid #d2d6df;
  94. font-family: DIN, Microsoft YaHei;
  95. font-weight: bold;
  96. color: #ffffff;
  97. & > .number-box {
  98. position: relative;
  99. display: inline-block;
  100. margin-right: 10px;
  101. width: 100%;
  102. height: 100%;
  103. writing-mode: vertical-rl;
  104. text-orientation: upright;
  105. overflow: hidden;
  106. & > .number-list {
  107. font-family: DIN, Microsoft YaHei;
  108. font-style: normal;
  109. position: absolute;
  110. top: 7px;
  111. left: 14px;
  112. transform: translate(-50%, 0%);
  113. transition: transform 1s ease-in-out;
  114. letter-spacing: 10px;
  115. }
  116. }
  117. &:last-child {
  118. margin-right: 0;
  119. }
  120. }
  121. }
  122. </style>