ModusCreateOrg / ionic-vue

Vuejs integration for Ionic versions 4 and 5
MIT License
271 stars 26 forks source link

IonInputVue not working #121

Closed EdwardMillen closed 4 years ago

EdwardMillen commented 4 years ago

I feel like I must be missing something here, but I really can't figure out what.

When I try to use an IonInputVue tag in my template (which seems to be the current way to create an input element as far as I can tell), it doesn't work and I get this in my Chrome DevTools console:

vue.runtime.esm.js?2b0e:619 [Vue warn]: Unknown custom element: <IonInputVue> - did you register the component correctly? For recursive components, make sure to provide the "name" option.

I actually have another project I started a couple of months ago (which is on hold for now) using @ionic/vue@0.0.9 (I switched to the Modus version for this new project because it seems to be further along and being more actively developed). IonInputVue works fine in that one, and I've actually copied in the exact same template file I was using in that project, but still get the same error. I've also compared and can't see any real differences in the other main project files, other than that obviously that project importing from @ionic/vue and this one from @modus/ionic-vue.

I've looked through the source and found that the code for handling IonInputVue all seems to be there, and this line is definitely running during initialisation in the browser (I found it in DevTools and added a breakpoint to make sure):

var IonInputVue = createInputComponent('IonInputVue', 'ion-input', 'ionInput');

Actually I've just noticed there is a difference at this point - createInputComponent in the Ionic version is calling Vue.component, whereas in the Modus version it's calling Vue.extend. Does that mean I need to be doing something different in order to use it?

Thanks

EdwardMillen commented 4 years ago

Just as some further information, one of the reasons why I was thinking <IonInputVue> must be the correct way to create an input currently is that in the README for this project, the only mention of inputs is "Functional Inputs" (I'm not entirely sure what that means yet), and the only link from there is to your pull request in the main Ionic repository. Then looking at the changed files in that pull request, the usage document has been changed to use <IonInputVue> instead of <ion-input>. But it looks like the changed code there still uses Vue.component, so the change to using Vue.extend must have happened at some point since then.

michaeltintiuc commented 4 years ago

Vue.component registers the component for you, Vue.extend requires you to import the component manually:

import { IonInputVue } from '@modus/ionic-vue'

export default {
  components: {
    IonInputVue,
  },
}

Just tested the above with latest @modus/ionic-vue version

michaeltintiuc commented 4 years ago

Functional Inputs refers to inputs becoming functional components, this is better for performance, also Vue.extend is a better way to provide such functionality as it may be tree-shaken by webpack as it will not be included for pages/code that doesn't use inputs at least in theory

EdwardMillen commented 4 years ago

Ah yep that works, thanks for the super fast reply :D (I'd got as far as importing IonInputVue already to test whether it existed, but then didn't know how I would refer to it)

And that makes sense regarding performance so I'll only import it in the pages where I use it.

I am also having a sort-of related issue, so I hope it's ok to ask here - password inputs use clearOnEdit by default, which I don't want. I've added clearOnEdit="false" to the IonInputVue element in the template, but it doesn't seem to get passed through to the underlying object correctly (there seems to be the same issue with the @ionic/vue version and even with using <ion-input> directly with the attribute added to that).

If I add a breakpoint to the bit of code that checks for this (which seems to be part of the core Ionic input component, with the function shouldClearOnEdit) then I can see the value of this.clearOnEdit is undefined (it does already exist as a property of this though). If I manually set this.clearOnEdit = false in the console at this point and then continue, the input behaves as I want it to after that.

So I'm thinking I could work around it by setting the property from code when my page is loaded, but I'm not sure how I would get a reference to the correct object from there?

EdwardMillen commented 4 years ago

It seems that the object it's checking for the clearOnEdit property is the actual <ion-input> DOM element (so I'm not sure why it's not picking up the clearOnEdit attribute from there). So I've found I can refer to that in Vue by setting ref="password" as an attribute and using the code mounted: function() { this.$refs.password.clearOnEdit = false; }

That seems to do the job, but I would appreciate you letting me know if there is a better way to do it.

Thanks :)

michaeltintiuc commented 4 years ago

Yeah, unfortunately it's a quirk with how Vue parses camelCase properties and in case of Ionic they expect a dash-case attribute, so on your case you'd have to do clear-on-edit="false" thanks for reporting this, I'll create an issue for that and fix in the upcoming versions as it's not quite comfortable to use with dynamic data

EdwardMillen commented 4 years ago

clear-on-edit="false" works so I'll just use that for now, that's perfect, thanks :D