Как проверить, имеет ли v-text-field состояние успеха (или какое-либо правило не удалось)?

У меня есть компонент, содержащий элементы управления вводом (например, 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>

Как я могу проверить, соответствует ли это поле всем правилам? Мне не удалось найти событие в документах

Я думаю, что было бы медленно запускать каждую функцию правила снова.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
111
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вы должны обернуть свой ввод компонентом 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>

ДЕМО

Спасибо за ваш ответ. Значит, нет другого пути? Потому что я работаю с событием выхода из фокуса, и тогда мне придется синхронизировать два события.

baitendbidz 13.01.2023 16:17

и v-form только проверяет, действительна ли вся форма. Он не знает о конкретном поле

baitendbidz 17.01.2023 10:43
Ответ принят как подходящий

Поместите 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 даже лучше, потому что вам не нужно проверять снова

baitendbidz 23.01.2023 08:38

Если вы не хотите проверять всю форму, вы можете обернуть каждый элемент ввода в отдельную форму и проверить форму этого конкретного поля, когда это необходимо, используя метод проверки формы.

Например-

<!-- 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
  }
}

Другие вопросы по теме