1

Is it possible to set a form input type using a prop?

The below does not seem to work, any others ways to do this?

For example

<script setup>
defineProps({
  InputType: String,
  InputId: String,
  InputLabel: String,
  InputPlaceholder: String
});
</script>
<template>
  <div class="ml-6 mt-5 mr-6 mb-5 lg:w-1/2">
    <label
      :for="InputId"
      class="block text-sm font-medium leading-6 text-gray-900"
    >
      {{ InputLabel }}
    </label>
    <div class="mt-2">
      <input
        :id="InputId"
        :type="InputType"
        class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-pink-600 sm:text-sm sm:leading-6"
        :placeholder="InputPlaceholder"
      />
    </div>
  </div>
</template>
1
  • How do you use the component in parent one? Commented Mar 14, 2023 at 14:27

4 Answers 4

0

Read carefully the documentation on how to use props with <script setup>. The value of defineProps must be assigned, then props will be usable in your template.

const props = defineProps({
    InputType: String,
    InputId: String,
    InputLabel: String,
    InputPlaceholder: String,
})
<label :for="props.InputId">{{ props.InputLabel }}</label>
<div class="mt-2">
  <input :type="props.InputType" :id="props.InputId" v-bind:placeholder="props.InputPlaceholder">
</div>

Note: props can be automatically unwrapped in your template so InputId can be used instead of props.InputId. It is only strictly necessary if used elsewhere in <script setup>

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

2 Comments

+1 on the assigning the props notice. But, are you sure we have to use props. in the template bindings? I don't think so. I bet it should be just :type="InputType"
You don't have to, no, I'm just being verbose for clarity. You can do it either way
0

The child component should define the props with camelCase names inputLabel instead of InputLabel :

defineProps({
  inputType: String,
  inputId: String,
  inputLabel: String,
  inputPlaceholder: String
});

and they should be used in parent component like :

<Child input-label="somee label"/> or <Child inputLabel="somee label"/>

LIVE DEMO

Comments

-1

You could use a prop "type" for rendering the input base on it.

<script setup>
const props = defineProps({
    type: {type: String, default: ''},
    formField: {type: Object, default: {}}
    }) 
<script>
    
<template>
    <div v-if="type === 'text'">
    </div>
    <div v-if="type === 'file'">
    </div>
    <div v-if="type === 'checkbox'">
    </div>
</template>

Comments

-2

Basic solution.

Check also How to force a Vue component to re-render if you will need to reload your component.

const { createApp } = Vue

const MyInput = {
  props: ['type'],
  template: 'Type: {{type}} <br/> <input :type="type" />'  
}

const App = {  
  components: {
    MyInput
  },
  data() {
    return {
      type: 'text',
      types: ['text', 'radio', 'checkbox']
    }
  },
}

const app = createApp(App)
app.mount('#app')
#app { line-height: 1.75; }
[v-cloak] { display: none; }
 <div id="app" v-cloak>
  Type: <select v-model="type">
  <option v-for="t in types">{{t}}</option>
  </select><br/>
  <my-input :type="type"></my-input>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>

Comments

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.