Phone.vue 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. <!--
  2. Champs de saisie d'un numéro de téléphone
  3. @see https://github.com/yogakurniawan/vue-tel-input-vuetify
  4. // TODO: tester compatibilité avec Vue 3
  5. -->
  6. <template>
  7. <client-only>
  8. <vue-tel-input-vuetify
  9. :error="error || !!violation"
  10. :error-messages="errorMessage || violation ? $t(violation) : ''"
  11. :field="field"
  12. :label="label"
  13. v-model="myPhone"
  14. :readonly="readonly"
  15. clearable
  16. valid-characters-only
  17. validate-on-blur
  18. :rules="rules"
  19. @input="onInput"
  20. @change="onChangeValue"
  21. />
  22. </client-only>
  23. </template>
  24. <script setup lang="ts">
  25. import { useNuxtApp } from '#app'
  26. import { useFieldViolation } from '~/composables/form/useFieldViolation'
  27. import type { Ref } from '@vue/reactivity'
  28. const props = defineProps({
  29. label: {
  30. type: String,
  31. required: false,
  32. default: '',
  33. },
  34. field: {
  35. type: String,
  36. required: false,
  37. default: null,
  38. },
  39. data: {
  40. type: [String, Number],
  41. required: false,
  42. default: null,
  43. },
  44. readonly: {
  45. type: Boolean,
  46. required: false,
  47. },
  48. error: {
  49. type: Boolean,
  50. required: false,
  51. },
  52. errorMessage: {
  53. type: String,
  54. required: false,
  55. default: null,
  56. },
  57. })
  58. const { emit, i18n } = useNuxtApp()
  59. const { violation, onChange } = useFieldViolation(props.field, emit)
  60. const nationalNumber: Ref<string | number> = ref('')
  61. const internationalNumber: Ref<string | number> = ref('')
  62. const isValid: Ref<boolean> = ref(false)
  63. const onInit: Ref<boolean> = ref(true)
  64. const onInput = (
  65. _: any,
  66. {
  67. number,
  68. valid,
  69. countryChoice,
  70. }: { number: any; valid: boolean; countryChoice: any },
  71. ) => {
  72. isValid.value = valid
  73. nationalNumber.value = number.national
  74. internationalNumber.value = number.international
  75. onInit.value = false
  76. }
  77. const onChangeValue = () => {
  78. if (isValid.value) {
  79. onChange(internationalNumber.value)
  80. }
  81. }
  82. const myPhone = computed({
  83. get: () => {
  84. return onInit.value ? props.data : nationalNumber.value
  85. },
  86. set: (value) => {
  87. return props.data
  88. },
  89. })
  90. const rules = [
  91. (phone: string) => !phone || isValid.value || i18n.t('phone_error'),
  92. ]
  93. </script>
  94. <style lang="scss">
  95. input:read-only {
  96. color: rgb(var(--v-theme-on-neutral));
  97. }
  98. </style>