useVuetifyValidation.ts 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // composables/useVuetifyValidation.ts
  2. import { computed, ref, inject, onMounted, onUnmounted } from 'vue'
  3. export function useVuetifyValidation(
  4. value: Ref<any>,
  5. rules: Ref<Array<(value: any) => boolean | string>>
  6. ) {
  7. const hasBeenTouched = ref(false)
  8. const forceValidation = ref(false)
  9. const form = inject<any>('form', null)
  10. const errorMessages = computed(() => {
  11. if (!rules.value.length) return []
  12. const errors: string[] = []
  13. for (const rule of rules.value) {
  14. const result = rule(value.value)
  15. if (result !== true) {
  16. errors.push(typeof result === 'string' ? result : 'Erreur de validation')
  17. }
  18. }
  19. return errors
  20. })
  21. const hasError = computed(() => {
  22. if (!hasBeenTouched.value && !forceValidation.value) return false
  23. return errorMessages.value.length > 0
  24. })
  25. const isValid = computed(() => errorMessages.value.length === 0)
  26. const validationState = {
  27. id: Math.random().toString(36).substr(2, 9),
  28. isValid,
  29. errorMessages,
  30. validate: () => {
  31. forceValidation.value = true
  32. return isValid.value
  33. },
  34. reset: () => {
  35. hasBeenTouched.value = false
  36. forceValidation.value = false
  37. },
  38. resetValidation: () => {
  39. forceValidation.value = false
  40. }
  41. }
  42. const touch = () => {
  43. hasBeenTouched.value = true
  44. }
  45. const validate = () => {
  46. forceValidation.value = true
  47. }
  48. onMounted(() => {
  49. if (form?.register) {
  50. form.register(validationState)
  51. }
  52. })
  53. onUnmounted(() => {
  54. if (form?.unregister) {
  55. form.unregister(validationState.id)
  56. }
  57. })
  58. return {
  59. hasError,
  60. errorMessages,
  61. isValid,
  62. touch,
  63. validate
  64. }
  65. }