Using Vee Validate with Vue and am getting the following errors when compiling:
error: 'required' is defined but never used (no-unused-vars)
error: 'max' is defined but never used (no-unused-vars)
My code snippet is below
<ValidationObserver ref="observer" v-slot="{ invalid }" tag="form" #submit.prevent="submit()">
<div class="form-group">
<label for="password">Password</label>
<ValidationProvider rules="required|max:50" v-slot="{ errors }">
<input type="password" v-model="password" name="password" class="form-control"/>
<span>{{ errors[0] }}</span>
</ValidationProvider>
</div>
</ValidationObserver>
<script>
import { ValidationProvider, ValidationObserver } from 'vee-validate'
import { required, max } from 'vee-validate/dist/rules'
export default {
components: {
ValidationProvider,
ValidationObserver
}
}
</script>
I can suppress the errors by adding this code
Vue.use(required)
Vue.use(max)
But is that the correct way or is there a setting I can use in eslint to prevent these errors?
Turns out it was quite easy, but I'm still unsure if this is the best way - if someone has a better answer, please post!
/* eslint-disable no-unused-vars */
import { required, max } from 'vee-validate/dist/rules'
/* eslint-enable no-unused-vars */
UPDATE
I think the official way is to extend each rule you're using:
extend('required', required)
extend('max', max)
Related
I just tried to make a single login form in Vue but it returns
[Vue warn]: Failed to resolve component: v-text-field
and
[Vue warn]: Failed to resolve component: v-form
the code in login component:
<template lang="html">
<div>
<v-form>
<v-text-field v-model="loginInfo.username" label="Username"/>
<v-text-field v-model="loginInfo.password" label="Password"/>
<v-btn>Login</v-btn>
</v-form>
</div>
</template>
<script>
export default {
data() {
return{
loginInfo: {
username:'',
password:'',
}
}
},
}
</script>
I got the same issue and put around 2 hours to figure out. The only problem with me was my browser was getting the cached js file that did not have my required component.
I see two options to answer the question:
Either you use Vuetify.js as you are trying to in the code provided above. I would recommend checking if you are using Vuetify.js correctly by following the quick start guide.
The other option would be not to use Vuetify.js and therefor use the regular HTML expressions in the form:
<div>
<form>
<label for="username">Username</label>
<input id="username" type="text" v-model="loginInfo.username"/>
<label for="password">Password</Label>
<input id="password" type="password" v-model="loginInfo.password"/>
<input type="submit"value="Login" />
</form>
</div>
From the docs, I think I need to use configure to add custom classes to my validated fields, but I can't get it to work.
This is what I have so far...
import { extend, configure, localize } from 'vee-validate'
import { required, min, max } from 'vee-validate/dist/rules'
import en from 'vee-validate/dist/locale/en.json'
// Install rules
extend('required', required)
extend('min', min)
extend('max', max)
// Install classes
configure({
classes: {
valid: 'is-valid',
invalid: 'is-invalid'
}
})
// Install messages
localize({
en
})
And in my view....
<ValidationObserver ref="observer" v-slot="{ invalid }" tag="form" #submit.prevent="checkRef()">
<div class="form-group">
<label for="reference">Reference</label>
<ValidationProvider rules="required|max:20" name="reference" v-slot="{ errors }">
<input maxlength="20" name="reference" v-model="ref" id="reference" class="form-control"/>
<span class="warning">{{ errors[0] }}</span>
</ValidationProvider>
</div>
<button #click="checkRef" class="btn btn-primary app-button">Check Reference</button>
</ValidationObserver>
When I click the button, I see the error message but I don't get the 'in-invalid' class applied to my field.
What am I doing wrong?
VeeValidate does not apply the classes automatically anymore, since v3 you now must bind it yourself. Like errors you can extract classes from the slot props and apply it to your input:
<ValidationProvider rules="required|max:20" name="reference" v-slot="{ errors, classes }">
<input maxlength="20" name="reference" v-model="ref" id="reference" class="form-control" :class="classes" />
<span class="warning">{{ errors[0] }}</span>
</ValidationProvider>
i using vee-validate version 3.0.11 for validate my form like below
<validation-observer v-slot="{ invalid }" slim>
<validation-provider rules="required" v-slot="{ errors, dirty, invalid}" slim>
<div class="form-group">
<label class="sr-only" for="txtUsername"></label>
<input
autocomplete="off"
id="txtUsername"
name="username"
type="text"
class="form-control txtUsername"
placeholder="Email or Username"
v-model="username"
v-bind:class="{ 'is-invalid': invalid && dirty,'is-valid': !invalid }" />
</div>
</validation-provider>
<validation-provider rules="required" v-slot="{ errors, dirty, invalid}" slim>
<div class="form-group">
<label class="sr-only" for="txtPassword"></label>
<input
id="txtPassword"
name="password"
type="password"
class="form-control"
placeholder="Password"
v-model="password"
v-bind:class="{ 'is-invalid': invalid && dirty,'is-valid': !invalid }" />
</div>
</validation-provider>
<div >
<button
type="button"
name="login"
class="btn btn-primary"
v-on:click="doLogin()"
:disabled="invalid">
Login
</button>
</div>
</validation-observer>
and i wrote some test with chai and mocha
in my test i need to find the button
but when i using find method for find button all html tag between validation-observer tag is not loaded in my wrapper.
my test code is:
// i change it to shallowMount to mount but problem is exist,
// mount does not render any thing between validation-observer tag
const wrapper = mount(LoginView, { sync: false });
describe('Login.vue', () => {
it('some text, () => {
console.log(wrapper.html());
// my log include all of tag except tags between the validation-observer tag
});
});
can some one tell me how i can find my button by using warraper.find(), please?
You are trying to shallow mount a component that needs to be mounted in order to render its children. If you want to ignore ValidationProvider all together you can provide a fake one as shown below.
ContactForm.vue
<template>
<div>
<ValidationProvider rules="required" name="input" v-slot="{ errors }">
<p :style="{color: 'red'}">To be, or not to be</p>
<input type="text" v-model="value">
<span id="error">{{ errors[0] }}</span>
</ValidationProvider>
</div>
</template>
<script>
import { ValidationProvider } from "vee-validate";
export default {
name: "ContactForm",
components: {
ValidationProvider
},
data: () => ({
value: ""
})
};
</script>
ContactForm.test.js
import { shallowMount, createLocalVue } from "#vue/test-utils";
import ContactForm from "./ContactForm";
import FakeValidationProvider from "./FakeValidationProvider";
test("Test shallow mount renders what's inside validation provider", async () => {
const localVue = createLocalVue();
var wrapper = shallowMount(ContactForm, {
stubs: {
ValidationProvider: FakeValidationProvider
},
localVue
});
expect(wrapper.text()).toContain("To be, or not to be");
});
FakeValidationProvider.vue
<template>
<div v-bind="{ ...$props, ...$attrs }">
<slot :errors="errors"></slot>
</div>
</template>
<script>
export default {
name: "FakeValidationProvider",
data() {
return {
errors: []
};
}
};
</script>
Feel free to extend the slot with any other parameters you need besides errors. If you want to make those parameters dynamic as well, check out this article on rendering slots
I try to do a simple validation with Vuelidate, for required, but I get an error, and I am not sure why!?
Thanks!
<form ref="form" #submit.stop.prevent>
<b-form-group>
<b-form-input
v-model="name"
:state="name"
v-model.trim="$v.name.$model"
:class="{
'is-invalid':$v.name.$error, 'is-valid':!$v.name.$invalid}"
></b-form-input>
</b-form-group>
<div class="valid-feedback">Ok!</div>
<div class="invalid-feedback">
<span v-if="!$v.name.required">Not ok!</span>
</div>
</form>
import required from "vuelidate/lib/validators";
validations: {
account_name: {
required
}
}
Error in render: "TypeError: Cannot convert undefined or null to object"
I found the problem.
import { required } from "vuelidate/lib/validators";
Required must have { } .
I've almost got my form validation working - I'm using Vee Validate 3 with Vue.js. Most of the examples of Vee Validate are for version 2, so I'm struggling a bit.
The issue I have is triggering the validation when submitting the form.
If I click the text field to focus on it first, then click submit, the validation fires and I see the error message.
If however, I don't click the text field first and just click the submit button, I don't see the error message.
How can I make this work without having to focus on the text field before I click submit?
Update
Weirdly, the console shows the error TypeError: this.validate is not a function in both cases - whether the validation works or not.
<ValidationProvider rules="required" v-slot="{ validate, errors }">
<div>
<input type="text" rules="required">
<p id="error">{{ errors[0] }}</p>
</div>
</ValidationProvider>
<script>
export default {
methods: {
async validateField() {
const valid = await this.validate()
}
}
};
</script>
Adam pointed me in the right direction with the ValidationObserver.
This code works for me...
<ValidationObserver ref="observer" v-slot="{ invalid }" tag="form" #submit.prevent="submit()">
<ValidationProvider rules="required" v-slot="{ errors }">
<input type="text">
<p id="error">{{ errors[0] }}</p>
</ValidationProvider>
<button #click="submit()">Submit>/button>
</ValidationObserver>
<script>
import { VslidationProvider, ValidationObserver } from 'vee-validate'
import { required } from 'vee-validate/dist/rules'
export default {
methods: {
async submit () {
const valid = await this.$refs.observer.validate()
}
}
};
</script>
New way of doing it
<ValidationObserver v-slot="{ handleSubmit }">
<ValidationProvider rules="required" v-slot="{ errors }">
<input type="text">
<p id="error">{{ errors[0] }}</p>
</ValidationProvider>
<button #click="handleSubmit(onSubmit)">Submit>/button>
</ValidationObserver>
<script>
import { VslidationProvider, ValidationObserver } from 'vee-validate'
export default {
methods: {
onSubmit() {
// ...
}
}
};
</script>