question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Prevent creation of $validator on every component.

See original GitHub issue

Versions:

  • VueJs: 2.3.2
  • Vee-Validate: 2.0.0-rc.3

Description:

In the beforeCreate() hook of the vee-validate mixin, a $validator object is created for every component in Vue.

I think this is a bit excessive, and would like to propose that instead it is created only when needed, through a computed property that creates it on the fly on the first use. That way, only the components that use validation need to create this property. In my app, that’s maybe about 5% of the used components.

mixin.js:

import Validator from './validator';

export default (Vue, options) => ({
  computed: {
    $validator() {
      const validator = new Validator(null, { init: false });
      Vue.util.defineReactive(validator, 'errorBag', validator.errorBag);
      Vue.util.defineReactive(validator, 'fieldBag', validator.fieldBag);
      validator.init();
      return validator;
    },
    [options.errorBagName]: {
      get() {
        return this.$validator.errorBag;
      }
    },
    [options.fieldsBagName]: {
      get() {
        return this.$validator.fieldBag;
      }
    }
  }
});

I haven’t tested this yet but am fairly certain that it should work. I am happy to do the testing and create a PR if it’s welcome.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:4
  • Comments:58 (16 by maintainers)

github_iconTop GitHub Comments

15reactions
chlabcommented, Mar 22, 2018

Validation works for me.

First of all, you must be using ^2.0.0-rc.4.

Disable automatic injection of new $validator instances in every component: Vue.use(VeeValidate, { inject: false })

On the children:

export default {
  inject: ['$validator'],
  // ...the rest of your component
}

on the parent:

export default {
  $_veeValidate: {
    validator: 'new'
  },
  // ...the rest of your component
}

validation: this.$validator.validateAll()

That’s all it takes. Make sure you aren’t using scopes anymore in case you were using them before.

6reactions
lehnicommented, May 4, 2017

I am just realising that this change would allow for another welcome scenario: The possibility to share one validator across multiple child components. I have now tested this, and it works well in my tests:

  1. Remove the default beforeCreated() and mounted() hooks. It would be nice if this hack wasn’t needed:

    import VeeValidate from 'vee-validate'
    Vue.use(VeeValidate)
    // Remove the VeeValidate beforeCreate() and mounted() hooks again that create
    // and assume $validator objects for every component:
    Vue.options.beforeCreate.pop()
    Vue.options.mounted.pop()
    
  2. Define a $validator property on the parent component that creates the validator. It is worth considering if this functionality that is already present internally in vee-validator could be exposed for such a scenario:

    computed: {
      $validator() {
        const validator = new Validator(null, { init: false })
        Vue.util.defineReactive(validator, 'errorBag', validator.errorBag)
        Vue.util.defineReactive(validator, 'fieldBag', validator.fieldBag)
        return validator
      }
    }
    
  3. Define a $validator property on the child components that retrieves the $validator from the parent. Note that this even allows for multiple levels of nested children:

    computed: {
      $validator() {
        return this.$parent.$validator
      }
    }
    
  4. Components that are going to use validation need to explicitly call $validator.init() from their mounted() callback:

    mounted() {
      this.$validator.init()
    }
    

And that’s it! It just works.

Note that this would allow for a much simpler pattern to address the situation outlined in https://gist.github.com/sproogen/147d75db261505e8a558a7fd11a20551

Read more comments on GitHub >

github_iconTop Results From Across the Web

angular prevent form validation until touched - Stack Overflow
I have a create and edit component. I just duplicated/refactored create to make the edit. on arrival in edit-mode the component subscribes to...
Read more >
Is there a way to stop validation from firing for the first time for ...
I fixed my problem by updating the rules object after the component was mounted (this prevented the AJX post when the component was...
Read more >
The best way to implement custom validators - Angular inDepth
Learning best practices on how to build your custom validator in Angular by reverse engineering the built-in Angular validators.
Read more >
Restrict data input by using validation rules - Microsoft Support
Validations rules help you check data as it is added to your Access desktop database which improves accuracy and consistency of data entry....
Read more >
Advanced usage - Vuelidate
When using useVuelidate , Vuelidate will collect all validation $errors and $silentErrors from all nested components. No need to pass any props or...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found