In this tutorial, we’ll have a look at how we can show a password strength indicator of varied colors (red, orange, green), based on the strength of the password.
Earlier, we saw how we could achieve the same in Vue 2 Options API. However, in this example, we’ll see how to do that in the Vue 3 Composition API using the setup script (SFC).
Here’s the template code for the view:
<template>
<div id="app">
<h2>Password strength indicator example in Vue 3 Composition API</h2>
<div>
<input
name="passwordInput"
type="password"
placeholder="Enter password"
v-model="inputValue"
@keyup="checkInputStrength"
/>
</div>
<div class="np-password-hint">
<small>
Password should be at least 8 characters long and contain a number and a
symbol.
</small>
</div>
<h4>Password strength</h4>
<div class="np-password-strength-indicator-container">
<div
class="np-password-strength-indicator"
:style="{
backgroundColor: getIndicatorBackgroundColor(),
width: getIndicatorWidth() + '%',
}"
></div>
</div>
</div>
</template>
Code language: HTML, XML (xml)
And here’s the script for the view:
<script setup>
import { ref } from 'vue'
const inputStrength = ref(0)
const inputValue = ref('')
const inputContainsSpecialCharacters = () => {
const specialCharacters = /[`!@#$%^&*()_+\-=\\|,.<>?~]/
return specialCharacters.test(inputValue.value)
}
const inputContainsNumbers = () => {
const numbers = /\d/
return numbers.test(inputValue.value)
}
const checkInputStrength = () => {
inputStrength.value = 0
const inputStrengthLengthCheck = inputValue.value && inputValue.value.length >= 8
const inputContainsSpecialChars = inputContainsSpecialCharacters()
const inputContainsNum = inputContainsNumbers()
if (inputStrengthLengthCheck) {
inputStrength.value++
}
if (inputContainsSpecialChars) {
inputStrength.value++
}
if (inputContainsNum) {
inputStrength.value++
}
}
const getIndicatorBackgroundColor = () => {
let color = "gray"
switch (inputStrength.value) {
case 0:
case 1:
color = "red";
break;
case 2:
color = "orange";
break;
case 3:
color = "green";
break;
default:
color = "gray";
}
return color
}
const getIndicatorWidth = () => {
return parseInt((inputStrength.value / 3) * 100).toString()
}
</script>
Code language: HTML, XML (xml)
We’ve created two reactive states named inputStrength and inputValue. inputStrength to store the value of the strength of the password, beginning with 0. and inputValue to store the value of the actual password.
We then have a method named inputContainsSpecialCharacters to check if the password contains any special characters.
We have another method named inputContainsNumbers to check if the input contains any number.
Finally, in the checkInputStrength method, we increment the strength of the password if any of the above methods return true. We also increase the inputStrength if the password is greater than or equal to 8 characters in length.
We also have a method named getIndicatorWidth which returns the width of the progress bar depending on the value of the inputStrength reactive state. Therefore, these values can be 0, 33.33, 66.66, or 99.99 ~ 100%.
We can customize the look and feel with some CSS styles:
<style>
input {
font-size: 16px;
padding: 4px;
border: 1px solid rgb(34, 34, 34);
outline: none;
}
.np-password-strength-indicator-container {
width: 300px;
height: 20px;
background: #eee;
border-radius: 6px;
}
.np-password-strength-indicator {
width: 300px;
height: 20px;
background: #eee;
border-radius: 6px;
width: 33%;
transition: all 0.3s;
}
.np-password-hint {
margin-top: 10px;
max-width: 300px;
}
</style>
Code language: HTML, XML (xml)
Here’s how the above code would look like in action: