Reusable Vue 3 Password Field Component (Composition API + Tailwind)

Last updated 2 weeks, 4 days ago | 28 views 75     5

Tags:- Vue

Fifth page link: Reusable React Password Field Component

Great! Let's now implement a Vue 3 component for password validation with:

✅ Show/hide toggle
✅ Regex-based rule validation
✅ Password strength meter
✅ Confirm password support
✅ Responsive design with Tailwind CSS


Reusable Vue 3 Password Field Component (Composition API + Tailwind)


Setup Requirements

Ensure your project uses:

  • Vue 3

  • Tailwind CSS (optional but recommended for styles below)

If you're using Vite with Vue 3, you're good to go.


Component Code: PasswordField.vue

<template>
  <div class="space-y-4 max-w-md text-sm">
    <div>
      <label>Password</label>
      <input
        :type="showPassword ? 'text' : 'password'"
        v-model="password"
        class="w-full p-2 border rounded"
        required
      />
      <label class="block mt-1">
        <input type="checkbox" v-model="showPassword" /> Show Password
      </label>

      <div class="mt-2 space-y-1">
        <div
          v-for="(rule, index) in rules"
          :key="index"
          :class="rule.regex.test(password) ? 'text-green-600' : 'text-red-500'"
        >
          {{ rule.regex.test(password) ? '✔' : '✖' }} {{ rule.label }}
        </div>
      </div>

      <div class="mt-2 h-2 bg-gray-300 rounded">
        <div class="h-2 rounded" :class="strengthClass" />
      </div>
    </div>

    <div v-if="requireConfirmation">
      <label>Confirm Password</label>
      <input
        :type="showConfirm ? 'text' : 'password'"
        v-model="confirmPassword"
        class="w-full p-2 border rounded"
        required
      />
      <label class="block mt-1">
        <input type="checkbox" v-model="showConfirm" /> Show Confirm Password
      </label>

      <div class="mt-1">
        <span
          v-if="confirmPassword"
          :class="confirmPassword === password ? 'text-green-600' : 'text-red-500'"
        >
          {{ confirmPassword === password ? '✔ Passwords match' : '✖ Passwords do not match' }}
        </span>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';

const props = defineProps({
  requireConfirmation: {
    type: Boolean,
    default: true,
  },
});

const password = ref('');
const confirmPassword = ref('');
const showPassword = ref(false);
const showConfirm = ref(false);

const rules = [
  { regex: /.{8,}/, label: 'At least 8 characters' },
  { regex: /[a-z]/, label: 'At least one lowercase letter' },
  { regex: /[A-Z]/, label: 'At least one uppercase letter' },
  { regex: /\d/, label: 'At least one number' },
  { regex: /[\W_]/, label: 'At least one special character' },
];

const strength = computed(() => {
  let score = 0;
  rules.forEach((rule) => {
    if (rule.regex.test(password.value)) score++;
  });
  return score <= 2 ? 'weak' : score <= 4 ? 'medium' : 'strong';
});

const strengthClass = computed(() => {
  return {
    weak: 'w-1/3 bg-red-500',
    medium: 'w-2/3 bg-yellow-500',
    strong: 'w-full bg-green-500',
  }[strength.value];
});
</script>

Usage Example: RegisterForm.vue

<template>
  <div class="p-6">
    <h2 class="text-xl font-bold mb-4">Register</h2>
    <form @submit.prevent="submitForm">
      <PasswordField :requireConfirmation="true" />
      <button
        class="mt-4 px-4 py-2 bg-blue-600 text-white rounded"
        type="submit"
      >
        Register
      </button>
    </form>
  </div>
</template>

<script setup>
import PasswordField from './PasswordField.vue';

const submitForm = () => {
  alert('Form submitted (add real validation logic)');
};
</script>

Tips

  • Replace checkboxes with eye icons (font-awesome or lucide-vue).

  • Use v-model:password and v-model:confirm props if you want to expose password data back to parent components.

  • Emit validation status to disable/enable the submit button dynamically.


⚠️ Common Pitfalls

  • ❌ Forgetting to validate passwords again on the backend.

  • ❌ Using weak regex (ensure you test special characters like !@#$%^&*()).

  • ❌ Overcomplicating show/hide logic—checkboxes work well for toggling.