Проект у меня мультиязычный, использую я 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 то это отработает. Подскажите пожалуйста что может помочь решить данную проблему, уже несколько часов голову ломаю