I have a component holding input controls ( e.g. v-text-field
). This component provides some props, e.g. the field rules for the input. Whenever the input value passes every rule / enters the success state I want to call a function.
Given the following sample code
<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.log(newValue);
}
}
</script>
How can I check if this field passed every rule? I wasn't able to find an event in the docs
I think it would be slow to run each rule function again.
CodePudding user response:
You should wrap your input with v-form
component that triggers the input event with form validation state (false/true) as parameter :
<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.log('passed ',newValue);
}
}
</script>
CodePudding user response:
Place a ref
on the element. And watch
its error
value:
<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
}
})
See it here.
Notes:
- uncomment
<pre v-text="JSON.stringify(input, null, 2)"></pre>
to see everything<v-text-field>
has to offer. - watch is, by default, lazy. Meaning it won't be checked when the component is mounted. If you want to make this check when the component has mounted, pass a third param to it:
{ immediate: true }
.
Example.
CodePudding user response:
As you said you want to validate that on focus out event, You can do that by adding the reference
to the input field and then validate that by using this syntax in your focus out event.
this.$refs.msgInput.validate()
Live Demo :
new Vue({
vuetify: new Vuetify(),
data: {
msg: ''
},
methods: {
validateField() {
this.$nextTick(() => {
if (this.$refs.msgInput.validate()) {
console.log('validation passed')
} else {
console.log('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>
Note : If you have a multiple inputs in your component, Then my suggestion would be that use v-form
and attached the reference to the form. So that you can validate all the inputs in a single go on submit.