Как правильней передать правила валидации?
Проект у меня мультиязычный, использую я 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"> <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> |
<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 то это отработает. Подскажите пожалуйста что может помочь решить данную проблему, уже несколько часов голову ломаю
Дополнительно:
Ответы:
Можно попробовать отслеживать изменения свойства this.$i18n.locale и что-то делать
- Я пробовал отслеживать изменения с помощью встроенных во vue наблюдателей, но они как будто не засекают никаих изменений. Хотя если просто выводить в шаблон аттрибут validation то сообщения изменяются
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Для передачи правил валидации в PHP можно использовать множество различных подходов, в зависимости от конкретной задачи и обстоятельств. Ниже представлены несколько способов, которые могут быть использованы для передачи правил валидации:
1. Создание массива с правилами валидации:
$rules = [ 'username' => 'required|string|max:255', 'email' => 'required|email|unique:users', 'password' => 'required|string|min:6', ];
2. Использование классов и объектов для описания правил валидации:
class UserValidationRules { public function rules() { return [ 'username' => 'required|string|max:255', 'email' => 'required|email|unique:users', 'password' => 'required|string|min:6', ]; } } $validator = new UserValidationRules(); $rules = $validator->rules();
3. Использование конфигурационных файлов для хранения правил валидации:
// config/validation.php return [ 'user' => [ 'username' => 'required|string|max:255', 'email' => 'required|email|unique:users', 'password' => 'required|string|min:6', ], ]; // usage $rules = config('validation.user');
4. Использование специальных библиотек и пакетов для валидации данных, таких как Laravel Validation или Symfony Validator.
Каждый из этих способов имеет свои преимущества и недостатки, поэтому выбор конкретного метода зависит от требований проекта и личных предпочтений разработчика. Важно помнить, что передача правил валидации должна быть удобной и эффективной, чтобы обеспечить надежную проверку данных на корректность.