logaretm / vee-validate

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

useField - reactive field-id not working #4849

Closed OlliL closed 3 days ago

OlliL commented 1 month ago

What happened?

I have to use a uno-ui input-component which has no name and it's id is generated and private. So I need to "find" the input fields ID to make useField work. It all works until I start giving the field an initial value. No matter if i use the initialFieldValue option, use setValue or setting value. The moment I try to set a field value programatically the field validation breaks. The errorMessage is no longer printed out. Validation still works in the background somehow (preventing submitting for example) but it looks like the reference to the error message returned by useField is detached from the field registered and validated in vee-validate.

Reproduction steps

Version

Vue.js 3.x and vee-validate 4.x

What browsers are you seeing the problem on?

Relevant log output

No response

Demo link

https://stackblitz.com/edit/puuk1z-8qgtme?file=src%2FInputText.vue

Code of Conduct

logaretm commented 3 days ago

This is because before the mounting happens your field has an empty string for a name:

  if (spanFieldRef.value) {
    const inputField = spanFieldRef.value.querySelector('input');
    if (inputField) {
      return inputField.id;
    }
  }
  return '';

You can have dynamic names, as long as they are stable. The name implementation here changes during mount which is unstable. Could you pass the field name as a prop instead or have it being referenced in the script so that it is stable enough?

I don't think this case will be supported, but I'm curious why you define field names like that? Any requirements in your app? Happy to revise my position if so.

OlliL commented 3 days ago

As said in my initial post, I have to use a 3rd party vue component which does not offer a prop for specifying the id or the name of the <input> element which it contains "hidden" inside multiple div tags. Instead, the 3rd party component generates an unpredictable (kind of random) id during runtime itself.

Thats why I came up with that code to find the <input> element id during runtime.

But in the meantime I also found out that vee-validate works with an id specified on the surrounding/outer component which itself contains that targeted <input> element. Looks like it is not necessary to directly reference the <input> field but its also sufficient to reference a surrounding component when registering a field. No idea if thats supposed to be supported or if its working by accident.

<div id="myId" class="thisIsThe3rdPartyComponent">
<div>
<input id="randomId" />
</div>
</div>

using "myId" when calling useField appears to work.