【Vue】パスワードの強弱をリアルタイムで表示する(DL可)

さてさて、前回のVueでセレクトボックス、ラジオボタン、チェックボックスを連動するという記事で久しぶりにVueの話題をお届けしましたので、その流れで今回もVueの基本テクニックを紹介します。

そして、今回のテーマは、

入力されたパスワードの強弱をリアルタイムで表示する

というものです。

ちなみに、なぜこの機能を作ってみたくなったかというと、実はwordpressにも以下のような同じ機能がついているので、いつかVueでも作ってみたくなったんですね。

【wordpressのパスワード入力サンプル】

ということで、今回はVueを使ってこの「パスワード強弱のリアルタイム表示」を実装してみます。(最後に今回実際に開発したソースコード一式をダウンロードできます!)

開発環境: Vue 2.6、Tailwind 1.0

この記事を読んで実装できるもの

まずこの記事で開発できる機能は次のようなものです。

実際のソースコード

では、まずは実際のソースコードになります。

<html>
<head>
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
</head>
<body>
    <h1 class="text-center md:text-2xl sm:text-sm m-5">Vueでパスワードの強弱をリアルタイム表示する</h1>
    <div id="app" class="flex">
        <div class="md:w-1/3"></div>
        <div class="md:w-1/3 w-full">

            <form class="p-3">
                <label class="block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2" for="grid-password">
                    パスワード
                </label>
                <div class="flex flex-wrap items-stretch w-full relative">
                    <input
                        ref="password"
                        type="password"
                        class="w-px flex-1 border h-10 bg-gray-200 text-gray-700 border border-gray-200 rounded rounded-r-none py-3 px-4 focus:outline-none focus:bg-white focus:border-gray-500"
                        placeholder="******************"
                        v-model="password">
                    <div class="flex -mr-px">
                        <button
                            type="button"
                            class="flex items-center leading-normal bg-grey-lighter rounded rounded-l-none border border-l-0 border-grey-light px-3 whitespace-no-wrap text-grey-dark text-sm"
                            v-text="passwordVisibilityText"
                            @click="changePasswordVisibility"></button>
                    </div>
                </div>
                <p :class="passwordMessageCss" v-text="passwordMessage"></p>
            </form>

        </div>
        <div class="md:w-1/3"></div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.0"></script>
    <script>

        new Vue({
            el: '#app',
            data: {
                password: '',
                showPassword: false
            },
            methods: {
                changePasswordVisibility() {    // パスワード表示/非表示を切り替え

                    this.showPassword = !this.showPassword;
                    this.$refs.password.type = ((this.showPassword)) ? 'text' : 'password';
                    this.$refs.password.focus();

                }
            },
            computed: {
                passwordScore() {   // パスワードの強さを計算

                    let score = 0;

                    if(this.password.length >= 11) {

                        score += 10;    // 長さが11文字以上あるか

                    }

                    const patterns =  [
                        /\d/,           // 数字があるか
                        /[a-z]/,        // 小文字のアルファベットがあるか
                        /[A-Z]/,        // 大文字のアルファベットがあるか
                        /[^a-zA-Z0-9]/  // 数字・アルファベット以外の文字
                    ];

                    patterns.forEach((pattern) => {

                        if(this.password.match(pattern)) {

                            score += 10;

                        }

                    });

                    return score;

                },
                passwordMessage() {

                    let message = '';
                    const score = this.passwordScore;

                    if(score >= 50) {

                        message = '非常に強力';

                    } else if(score >= 40) {

                        message = '強力';

                    } else if(score >= 30) {

                        message = '普通';

                    } else if(score >= 20) {

                        message = '脆弱';

                    } else if(score >= 10) {

                        message = '非常に脆弱';

                    }

                    return message;

                },
                passwordMessageCss() {

                    let css = [
                        'text-gray-600',
                        'text-xs',
                        'italic',
                        'p-2',
                        'my-2',
                        'font-bold',
                        'rounded'
                    ];
                    const score = this.passwordScore;

                    if(score >= 50) {

                        css.push('bg-green-200');
                        css.push('text-green-700');

                    } else if(score >= 40) {

                        css.push('bg-blue-200');
                        css.push('text-blue-700');

                    } else if(score >= 30) {

                        css.push('bg-orange-200');
                        css.push('text-orange-700');

                    } else if(score >= 20) {

                        css.push('bg-yellow-200');
                        css.push('text-yellow-700');

                    } else if(score >= 10) {

                        css.push('bg-red-200');
                        css.push('text-red-700');

                    }

                    return css;

                },
                passwordVisibilityText() {

                    return (this.showPassword) ? '非表示' : '表示';

                }
            }
        });

    </script>
</body>
</html>

まずこの中で重要なのは、computed内にあるpasswordScore()で、この中で入力されたパスワードが強いのか弱いのかを数字に変換しています。

そして、その強弱を判断するのは以下の5つで、それぞれ条件を満たすと10ポイント獲得する仕組みになっています。(つまり最高点は、50点)

  1. パスワードの長さが11文字以上ある?
  2. 数字が入ってる?
  3. アルファベット(小文字)が入ってる?
  4. アルファベット(大文字)が入ってる?
  5. 数字・アルファベット以外の文字が入ってる?

パスワードの強弱が分かるようになったら、以下5パターンのテキストと、それに関連するCSS(色とかですね)の切り替えをする部分です。

  • 非常に強力
  • 強力
  • 普通
  • 脆弱
  • 非常に脆弱

具体的なメソッドは、passwordMessage()passwordMessageCss()になります。この中でpasswordScoreによって、表示する内容を切り替えています。

さらに、wordpressと同じくパスワードの内容を確認できるように「表示/表示」ボタンをクリックしたら実行されるのがchangePasswordVisibility()です。

内容としては、showPasswordtrue / falseによって<input>タグのtypeを変更しているだけです。

<input type="text"> (表示する場合)

↓↑ 切り替え

<input type="password"> (非表示にする場合)

また、該当する<input>タグにアクセスするためにタグのプロパティにref="password"を付けていることに注目してください。

つまり、ここで指定した「password」という名前を使って<input>タグにアクセスしています。

this.$refs.password

// もしくは以下もOK

this.$refs['password']

ソースコード一式をダウンロードする

今回実際に開発したソースコードを以下からダウンロードすることができます。
CDNCSSJSを読み込んでいるのでダウンロードして展開したらすぐ試すことができますよ!

Vueでパスワードの強弱をリアルタイムで表示する

おわりに

ちなみにですが、今回はじめてCSSフレームワークにTailwind CSSを使ってみました。

感想としては、Bootstrapよりフレキシブルな使い方ができる(逆に言うと要求される)のかな、というものでした。

というのも、Bootstrapだとボタンならbtn-*など専用のCSSクラスが存在していますが、Tailwindの場合はそういった固定されたものというよりは、背景や丸角、線などを組み合わせて独自のコンポーネントを作っていくというイメージだったからです。

そのため、私のようにそれほどデザインが得意でない人間からすると一度基礎からデザインを勉強してから使った方がよりいい使い方ができるかな、とも思いました。

ただ、Tailwindも人気のフレームワークだけあって、Bootstrapとはまた違ったキレイでおしゃれな雰囲気をもっていました。この辺は好みの出てくるかもしれません。

ということで、今回はVueでパスワードの強弱をリアルタイムで表示する方法をご紹介しました。

ぜひ皆さんも試してみてくださいね。

ではでは〜!

この記事が役立ちましたらシェアお願いします😊✨