logaretm / vee-validate

✅ Painless Vue forms
https://vee-validate.logaretm.com/v4
MIT License
10.8k stars 1.26k forks source link

Loading component from ui-package not invalidating input #4156

Open yormy opened 1 year ago

yormy commented 1 year ago

What happened?

I follow this example: https://vee-validate.logaretm.com/v4/examples/custom-inputs/ This works nice and the field validates. Now when I place the exact component TextInput.vue inside my ui npm library that I import Then the validation is not working properly 1) On page load the component shows the success message 2) the message never disappears, whatever I type

Yes, the component (copy pasted) inside the main app works fine

On page load the state of the meta is

meta: { "touched": false, "pending": false, "valid": true, "validated": false, "initialValue": "", "dirty": false }

It makes sense that the success is shown when the state is valid, but why is the sate valid on page load, and why is it not set to invalid when I delete the content. note: I copied the working component to a new component in the ui lib with no modifications and loaded that next to the original component

Any ideas ?

Could it be the the useform schema validation is diving into usefields defined by local components only and not those defined in external packages ?

yormy commented 1 year ago

Form code used from example and set name to same rules as email copied the component to a synlinked package imported the copied component in the form.vue replaced TextInput with the name of the copied component

image

The local generates a proper invalid response the copied component does not

Any ideas ?

yormy commented 1 year ago

also on page load I see something wierd:

image

The original component locally loaded (2nd) is inital valid=false (which is oke) the copied component loaded from the package initially valid = true (? WTF? )

I am lost ...

logaretm commented 1 year ago

Are you by any chance importing vee-validate in both your package and your project? if so then it might be getting bundled in your package causing you to have 2 different installations with vee-validate that do not communicate with one another.

See this discussion for reference and let me know if this is the case.

yormy commented 1 year ago

Somehow I am getting closer to the root, but I am still having some problems

Solution 1 Package:

Result: Still not working

Solution 2 removing from my package component import { useField } from 'vee-validate'; replacing it with const useField: any = inject('useField')

adding to my main application the provide

import { useField } from 'vee-validate';
app.provide("useField", useField)

Result: Now it DOES work

yormy commented 1 year ago

but no idea why the import { useField } from 'vee-validate'; is not working

yormy commented 1 year ago

btw.. forgot to mention.. you did create an AWESOME package... really love it... even though I am struggeling a bit now

logaretm commented 1 year ago

Sorry for the delay. I have no idea why the injections you are using are working. If it is possible can you create a mono-repo setup to replicate this so I can take a look?

Also I think the docs should have a guide for including vee-validate as part of packages as well to help folks building libs on top of it.

joris-fonck-loreal commented 10 months ago

Hello,

I encountered the same problem. Here's my technical stack and how I solved the problem:

I fixed it by putting this configuration in my vite.config on my application that uses the ui-library:

resolve: {
  dedupe: ['vee-validate']
}

I hope this helps people who encounter the same problem.

TomDeSmet commented 6 months ago

For people still using Webpack (e.g. Vue-Cli) you can do almost the same as dedupe with externals: https://webpack.js.org/configuration/externals/

almost As I understand it, externals removes the library completely from the dependencies that get bundled in the build. So I think you can use externals inside your library to exclude all dependencies and install them in your project instead. So you have more control. When using Vite, I think you can leave all dependencies bundled in your library but use dedupe in your application's Vite config so the application decides if it needs to use a dependency from the library or its own.

Please correct me if I'm wrong!

Another work-around is to use defineField which is also used to connect with other third-party libraries such as Vuetify. That works, but the error handling needs to be handled differently as well. So not the best solution.

olemarius commented 4 months ago

Hello,

I encountered the same problem. Here's my technical stack and how I solved the problem:

  • Vite
  • Monorepo
  • shared-workspace-lockfile=false in .npmrc <-- This is the root cause 🤕

I fixed it by putting this configuration in my vite.config on my application that uses the ui-library:

resolve: {
  dedupe: ['vee-validate']
}

I hope this helps people who encounter the same problem.

dedupe fixed it for me! Here's the fix committed to a repro of the issue https://github.com/olemarius/vee-validate-repro/commit/a3c1df8752e148984edc69bf5b25c2659529c02a

TomDeSmet commented 4 months ago

Unfortunately dedupe doesn't seem to work in my case. I'm using the less ideal external from the rollupOptions in the Vite config.