Search code examples
vuejs3vee-validate

Custom vee-validate input field


I have this input field here from vee-validate that is a simple password field. However currently i have a reveal password button that is outside of the field, I want to place the button inside the field and towards the end of the field, does anyone know how to do that?

<div class="form-group mb-3 ">
    <div class="d-flex">
      <Field name="password" :type="password.fieldType" class="form-control col-12"
        :class="{ 'is-invalid': errors.password }" id="password" :placeholder="t('password')" />
      <div class="d-flex px-2" @click="toggleVisibility">
        <div class="my-auto" v-if="password.fieldType === 'password'">
          <i class="fa-solid fa-eye-slash"></i>
        </div>
        <div class="my-auto" v-if="password.fieldType === 'text'">
          <i class="fa-solid fa-eye"></i>
        </div>

      </div>
    </div>
    <div class="invalid-feedback">{{ t('passwordIsRequired') }}</div>
  </div>

Desired output desired output

Current output current output


Solution

  • The Field component renders a simple input, if you need a more complex layout, you have to use its default slot. Provide your own input along with any other elements, and bind the field slot prop to the input. The Field component will be renderless, except when you request a tag using the as prop.

    Here is an example for Bootstrap 4.6:

    <Field 
      name="password"  
      placeholder="password"
      v-model="password.value"
      as="div"
      class="input-group form-group"
      v-slot="{field, errorMessage}"
    >
      <input 
        v-bind="field" 
        :type="password.fieldType" 
        class="form-control col-12"
        :class="{ 'is-invalid': errorMessage }" 
      />
      <div class="input-group-append">
        <button class="btn btn-outline-secondary" type="button" @click="toggleVisibility">
          <i 
            class="fa-solid" 
            :class="password.fieldType === 'text' ? 'fa-eye-slash' : 'fa-eye'"
          />
        </button>
      </div>
      
      <div class="invalid-feedback">{{ errorMessage }}</div>
    
    </Field>
    

    playground