У меня есть компонент, содержащий элементы управления вводом (например, v-text-field
). Этот компонент предоставляет некоторые реквизиты, например. правила поля для ввода. Всякий раз, когда входное значение проходит каждое правило/переходит в состояние успеха, я хочу вызвать функцию.
Учитывая следующий пример кода
<template>
<v-app>
<v-main>
<v-text-field v-model = "msg"
:rules = "[ v => v.length > 0 || 'required' ]"
@update:model-value = "onInput"
/>
</v-main>
</v-app>
</template>
<script setup>
import { ref } from 'vue'
const msg = ref('')
function onInput(newValue) {
if (true /* text-field has success state => do things */) {
console.info(newValue);
}
}
</script>
Как я могу проверить, соответствует ли это поле всем правилам? Мне не удалось найти событие в документах
Я думаю, что было бы медленно запускать каждую функцию правила снова.
Вы должны обернуть свой ввод компонентом v-form
, который запускает событие ввода с состоянием проверки формы (false/true) в качестве параметра:
<template>
<v-app>
<v-main>
<v-form @update:model-value = "onInput" >
<v-text-field v-model = "msg" :rules = "[ v => v.length > 0 || 'required' ]" />
</v-form>
</v-main>
</v-app>
</template>
<script setup>
import { ref } from 'vue'
const msg = ref('')
function onInput(newValue) {
if (newValue) {
console.info('passed ',newValue);
}
}
</script>
и v-form
только проверяет, действительна ли вся форма. Он не знает о конкретном поле
Поместите ref
на элемент. И watch
его error
значение:
<template>
<v-text-field ref = "input" />
</template>
<script setup>
import { ref, watch } from 'vue'
const input = ref(null)
watch(() => input.value?.error, (val) => {
if (val) {
// input not valid
} else {
// input is now valid
}
})
Смотрите здесь.
Примечания:
<pre v-text = "JSON.stringify(input, null, 2)"></pre>
, чтобы увидеть все, что <v-text-field>
может предложить.{ immediate: true }
.Как вы сказали, вы хотите проверить это в событии фокуса. Вы можете сделать это, добавив reference
в поле ввода, а затем подтвердить это, используя этот синтаксис в событии фокуса.
this.$refs.msgInput.validate()
Живая демонстрация:
new Vue({
vuetify: new Vuetify(),
data: {
msg: ''
},
methods: {
validateField() {
this.$nextTick(() => {
if (this.$refs.msgInput.validate()) {
console.info('validation passed')
} else {
console.info('validation failed')
}
})
}
}
}).$mount('#app');
<script src = "https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src = "https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>
<link rel = "stylesheet" type = "text/css" href = "https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css"/>
<div id = "app">
<v-text-field
outline
v-model = "msg"
label = "Enter your message"
:rules = "[(v) => !!v || 'required']"
@blur = "validateField"
ref = "msgInput"
/>
</div>
Примечание. Если у вас есть несколько входных данных в вашем компоненте, я предлагаю использовать v-form
и прикрепить ссылку к форме. Так что вы можете проверить все входные данные за один раз при отправке.
Спасибо за ваш ответ. Это очень хорошее решение, но я думаю, что проверка на input.value?.error
даже лучше, потому что вам не нужно проверять снова
Если вы не хотите проверять всю форму, вы можете обернуть каждый элемент ввода в отдельную форму и проверить форму этого конкретного поля, когда это необходимо, используя метод проверки формы.
Например-
<!-- Field 1 -->
<v-form ref = "form_1_ref">
<v-text-field v-model = "msg"
:rules = "[ v => v.length > 0 || 'required' ]"
@blur = "validate('form_1_ref')"
/>
</v-form>
<!-- Field 2 -->
<v-form ref = "form_2_ref">
<v-text-field v-model = "msg2"
:rules = "[ v => v.length > 0 || 'required' ]"
@blur = "validate('form_2_ref')"
/>
</v-form>
methods:{
validate(form_ref) {
// If form is not valid then return from here
if (!this.$refs[form_ref].validate()) {
return false;
}
// Write code here
}
}
Спасибо за ваш ответ. Значит, нет другого пути? Потому что я работаю с событием выхода из фокуса, и тогда мне придется синхронизировать два события.