0

I'm creating a re-usable component for input fields where I can define them easier in one component tag with props. However, I want to make it versatile as to be able to use it as text, date, password, number etc. By a conditional prop. But I'm having trouble getting that prop to bind

Here is my input field component

<template>
<div class="uk-margin">
    <label class="uk-form-label" for="trackid">{{label}}</label>
    <div class="uk-form-controls">
      <input v-if="number" class="uk-input" type="number" v-model="defaultvalue" />
      <input v-else-if="date" class="uk-input" type="date" v-model="defaultvalue" />
      <input v-else-if="email" class="uk-input" type="email" v-model="defaultvalue" />
      <input v-else-if="password" class="uk-input" type="password" v-model="defaultvalue" />
      <input v-else class="uk-input" type="text" v-model="defaultvalue" />
    </div>
</div>
</template>

<script>
export default {
  name: "input-text-field",
  props: {
    label: {
      type: String
    },
    defaultvalue: {
      type: String
    },
    type: {
      type: String
    },
    number: {
      type: Number
    },
    date: {
      type: Object
    },
    email: {
      type: String
    },
    password: {
      type: String
    }
  },
  data() {
    return {
      value: ""
    };
  }
};

</script>

And I'm calling like this or would like to use them like this

<InputField label="User Name" :defaultvalue="myName" />
<InputField label="User Email" email :defaultvalue="myEmail" />
<InputField label="User Password" password :defaultvalue="myPass" />
<InputField label="Tracking #" number :defaultvalue="trackingNumber" />

In my understanding of this, if I call password, it should obfuscate the value as it would render the type="password" given the conditional statement. No? What am I doing wrong

*P.S. the defaultvalue would be stored and used as a state. That part works. Right now, I am not getting console errors, but the component renders as a text regardless.

0

2 Answers 2

2

Let's take this as an example:

<VInputField label="User Password" password :defaultvalue="'myPass'"/>

After checking the console, we can see that passing password(when its prop type is String) is not enough.

props: {
 /* ... */
 password: {
   type: String
  }
},

created () {
 console.log(this.$props);
 /*
  ...
  password: ""
  ...
 */
}

An empty string("", '') evaluates to false.

I can think of one approach, by making the prop's type Boolean:

password: {
   type: Boolean
}
  • <VInputField label="User Password" :password="true" :defaultvalue="'myPass'"/>

Here is a CodeSanbox example.

Edit

By passing password this way
<VInputField label="User Password" password :defaultvalue="'myPass'"/>
you will always get a true value(if the prop's type is also Boolean).

Sign up to request clarification or add additional context in comments.

Comments

2

v-else-if="password" tests the value of the password prop. It is equivalent to:

if (vm.password)

However,

<InputField label="User Password" password :defaultvalue="myPass" />

provides the password prop, but without a value which is the same as :password="true". However, the password prop requires a string, not a boolean. In that case, Vue apparently assigns the empty string to the prop which evaluates to false. It's the same with all your other examples which is why the else clause is always chosen.

By the way, you should have warnings in the console regarding this. You shouldn't ignore those.

This should work:

<InputField label="User Password" password="true" :defaultvalue="myPass" />

However, I suggest you rework your component. Instead of having so many props defined, have a single one called inputType and pass the desired input type as a string. Then you would have:

<InputField label="User Email" inputType="email" :defaultvalue="myEmail" />
<InputField label="User Password" inputType="password" :defaultvalue="myPass" />

1 Comment

I agree on the idea of simply passing in the input type instead of making a conditional component, seems a bit messy. I've made a fiddle of how I'd build the custom input component codesandbox.io/s/vue-template-7m29w

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.