AgreementDateWriteBlock.vue 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. <template>
  2. <div class="ymd-block">
  3. <a-space wrap align="center">
  4. <span v-if="prefix" class="text-secondary">{{ prefix }}</span>
  5. <a-input-number
  6. :value="modelValue.year"
  7. :max-length="4"
  8. size="small"
  9. class="w-12!"
  10. @update:value="(v: any) => patch('year', v)"
  11. />
  12. <span class="text-secondary">年</span>
  13. <a-input-number
  14. :value="modelValue.month"
  15. :max-length="2"
  16. size="small"
  17. class="w-12!"
  18. @update:value="(v: any) => patch('month', v)"
  19. />
  20. <span class="text-secondary">月</span>
  21. <a-input-number
  22. :value="modelValue.day"
  23. :max-length="2"
  24. size="small"
  25. class="w-12!"
  26. @update:value="(v: any) => patch('day', v)"
  27. />
  28. <span class="text-secondary">日</span>
  29. </a-space>
  30. <div v-if="hint" class="text-secondary hint">{{ hint }}</div>
  31. </div>
  32. </template>
  33. <script setup lang="ts">
  34. import AgreementPrefillInline from './AgreementPrefillInline.vue';
  35. export type AgreementYmdParts = {
  36. year: string;
  37. month: string;
  38. day: string;
  39. };
  40. const props = withDefaults(
  41. defineProps<{
  42. modelValue: AgreementYmdParts;
  43. prefix?: string;
  44. hint?: string;
  45. }>(),
  46. {
  47. prefix: '时间:',
  48. hint: '',
  49. },
  50. );
  51. const emit = defineEmits<{
  52. 'update:modelValue': [value: AgreementYmdParts];
  53. }>();
  54. function digitsOnly(v: string | number, maxLen: number) {
  55. const str = String(v ?? '').replace(/\D/g, '');
  56. return str.slice(0, maxLen);
  57. }
  58. function patch(key: keyof AgreementYmdParts, v: string | number) {
  59. const max = key === 'year' ? 4 : 2;
  60. const next = digitsOnly(v, max);
  61. emit('update:modelValue', {
  62. ...props.modelValue,
  63. [key]: next,
  64. });
  65. }
  66. </script>
  67. <style scoped>
  68. .ymd-block {
  69. margin-top: 8px;
  70. }
  71. .hint {
  72. margin-top: 6px;
  73. font-size: 13px;
  74. }
  75. </style>