@KonstantinDyulin

Как правильней передать правила валидации?

Проект у меня мультиязычный, использую я nuxt i18n plugin.
У меня есть компонент input'a
<template>
  <div class="flex flex-col">
    <span v-if="label" class="mb-2.5">{{ label }}</span>
    <div class="flex flex-col gap-2.5">
      <div class='flex flex-col justify-center items-end relative'>
        <input
            :type="!passwordInput ? type : showPassword ? 'text' : 'password'"
            :value="modelValue"
            class="w-full relative rounded h-[44px] px-4 border border-gray-300 placeholder-gray-fill"
            :class="{'w-full rounded h-[44px] px-4 border-gray-dark/50 bg-gray-light placeholder-gray-fill': disabled}"
            :placeholder="placeholder"
            @input="emitUpdate"
            @change="emit('change')"
        />
      </div>
      <div class="flex flex-col pl-4 text-red">
        <span v-for="(error, index) in v$.modelValue.$errors" :key="`error-${index}`">{{error.$message}}</span>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import useVuelidate from "@vuelidate/core";

const props = defineProps({
  label: {
    required: false,
    type: String,
  },
  placeholder: {
    required: false,
    type: String,
    default: "",

  },
  modelValue: {
    required: true,
  },
  type: {
    required: false,
    default: 'text'
  },
  passwordInput: {
    required: false,
    default: false,
    type: Boolean
  },
  disabled: {
    required: false,
    default: false,
    type: Boolean
  },
  validation: {
    default: {}
  },
});

const showPassword = ref(false)

const v$ = useVuelidate(
    {
      modelValue: props.validation
    },
    props
)

const emit = defineEmits(["update:modelValue", 'change']);

function emitUpdate(event: any) {
  emit("update:modelValue", event.target.value);

  nextTick(() => {
    v$.value.modelValue.$validate();
  });
}
</script>

И представим страницу на которой я отрисовал какую-то форму
<template>
  <div class="flex flex-col gap-3 w-1/2">
    <ui-input
      :label="'какой-то label'"
      :placeholder="'какой-то placeholder'"
      v-model="form.input1"
      :validation="validationRules.input1"
    />
    <ui-input
      :label="'какой-то label'"
      :placeholder="'какой-то placeholder'"
      v-model="form.input2"
      :validation="validationRules.input2"
    />
    <ui-input
      :label="'какой-то label'"
      :placeholder="'какой-то placeholder'"
      v-model="form.input3"
      :validation="validationRules.input3"
    />
    <ui-button @click="save">Save</ui-button>
  </div>
</template>
<script setup lang="ts">
import { definePageMeta } from "#imports";
import useVuelidate from "@vuelidate/core";
import { helpers, required } from "@vuelidate/validators";

definePageMeta({
  layout: 'profile'
})

const i18n = useI18n()

const form = ref({
  input1: null,
  input2: null,
  input3: null,
})

const v$ = useVuelidate()
const validationRules = computed(() => {
  return {
    input1: {
      required: helpers.withMessage(i18n.t('validationMessages.required'), required)
    },
    input2: {
      required: helpers.withMessage(i18n.t('validationMessages.required'), required)
    },
    input3: {
      required: helpers.withMessage(i18n.t('validationMessages.required'), required)
    }
  }
})

async function save() {
  if (!(await v$.value.$validate())) {
    return
  }

  alert('успех')
}
</script>

При изменении локали перерисовывается все кроме сообщений валидации (свойство locale устанавливаю глобально через метод setLocate объекта i18n).
Насколько я знаю компоненты которые зависимы от каких либо вычисляемых свойств, при изменения самих свойств должны перерисовываться, этого не происходит, хотя если прокинуть строку перевода в аттрибут :placeholder то это отработает. Подскажите пожалуйста что может помочь решить данную проблему, уже несколько часов голову ломаю
  • Вопрос задан
  • 60 просмотров
Пригласить эксперта
Ответы на вопрос 1
yarkov
@yarkov Куратор тега JavaScript
Помог ответ? Отметь решением.
Можно попробовать отслеживать изменения свойства this.$i18n.locale и что-то делать
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
SummerWeb Ярославль
от 120 000 до 180 000 ₽
КРАФТТЕК Санкт-Петербург
от 60 000 до 80 000 ₽
Brightdata Тель-Авив
от 5 500 до 6 500 $