Vue Component で2枚の画像を切り替えるチェックボックスをつくってみよう

さてさて、いかに開発を効率的にするかは第1に「いかに再利用できる部品を作っておくか」が大きく関わってきます。

プログラマー(パソコン)の最大強みは「コピーができること」です。つまり、過去に作ったコードが再利用できるなら、(もちろん契約でしばられない限りですが)いつでもその作業をショートカットすることができるわけですね。

そして、VueJSの「Vue Component」はまさにこの「再利用」に焦点をあてた機能で、一度作っておけば、いつでもHTMLタグのように使えます。

そこで、今回のテーマは「2枚の画像を切り替えるチェックボックスをつくる」です。
例えば次のような切り替えです。

いらすとやさんの画像を使わせていただいてます。ありがとうございます ^^

ぜひプログラミング学習に役立ててくださいね。
(最後に教材をダウンロードできます)

やりたいこと

例えば、始めは次のような「バツマーク」の画像を表示しています。

そして、もしクリックされた場合は、OKの画像画像に切り替わります。もう一度クリックされたら、また元のバツマークに戻ります。

もちろんチェックボックスですから、内部的にtrue or falseのデータを持っていて、変更したらきちんと呼び出し側にもイベント通知します。

つまり、通常のチェックボックスの画像切り替えバージョンですね。
例えば、上の例なら「規約に同意する」部分に使うといいかもしれません。

では、実際に開発をしていきましょう!

Vueの基本形を作る

まずはVueが使える環境を整えましょう。
今回はcdnを使ってVue本体を読み込んでいます。

<html>
<body>
    <div id="app">

    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.min.js"></script>
    <script>

        new Vue({
            el: '#app'
        });

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

そして、ここにこれからつくるVue Componentのv-image-checkboxタグを追加。acceptという名前の変数を作ってバインディングします。

<div id="app">
    <v-image-checkbox
        true-image="./images/ok.png"
        false-image="./images/ng.png"
        v-model="accept">
    </v-image-checkbox>
</div>
<script>

    new Vue({
        el: '#app',
        data: {
            accept: false
        }
    });

</script>

つまり何が起きるかというと、v-image-checkboxがクリックされて切り替わると、そのtrue or falseacceptにも伝わるという内容になっています。

また、true-imagefalse-imageは表示する2枚の画像へのURL(URI)です。そのため、この場合はimages/に2枚の画像をコピーしておいてください。

では、実際にコンポーネントをつくっていきましょう。

Vue Componentをつくる

できるだけ再利用しやすいように、コンポーネントは専用のファイルをつくって、そこへコードを書いていきます。まずv-image-checkbox.jsというファイルを作成してください。

そして、このファイルの中に次のようなコードを追加します。

Vue.component('v-image-checkbox', {
    props: {
        'true-image': {
            type: String,
            default: ''
        },
        'false-image': {
            type: String,
            default: ''
        },
        'value': {
            type: Boolean,
            default: false
        }
    },
    template: '<a href="#" @click.prevent="onClick()"><img style="border:1px solid #ccc;border-radius:5px;" :src="imageUrl"></a>',
    methods: {
        onClick: function() {

            this.value = !this.value;

        }
    },
    computed: {
        imageUrl: function() {

            return (this.value) ? this.trueImage : this.falseImage

        }
    },
    watch: {
        value: function(value) {

            this.$emit('input', value);

        }
    }
});

やっていることは次のとおりです。

props

<v-image-checkbox>タグに設定できるプロパティを定義しています。

まず、true-imagefalse-imageは文字列で初期値は空白。

そして、valueは実際には指定していませんが、これはv-modelと連携することになっています。つまり、今回の例ではさっき指定したacceptの中身がここに入ってくることになります。そのため、初期値はfalseとしました。

template

template部分は実際に表示される場所になります。そのため、画像を<a>タグで囲んで@click.preventを使ってクリックイベントを追加しています。

また、<img>タグの:srcにはimageUrlという変数には存在しないものを指定していますが、これはcomputedから呼び出せる擬似的な変数になっています。

methods

onClick()は画像リンクがクリックされたときに実行されるメソッドです。
この中身では、クリックするごとに変数"value"の値がtruefalseに切り替わります。(つまり、次のcomputedのimageUrlも自動的に切り替わります)

computed

ここで設定したものは、擬似的な変数として利用することができるようになります。
imageURL内でやっていることは、次のとおりです。

  • value が true ・・・ true-image のURLで画像を表示する
  • value が false ・・・ false-image のURLで画像を表示する

watch

ここでは変数"value"の値が変化した場合に実行されるようにしています。
実行する内容はイベントの通知です。つまり、この部分があるので、true 、もしくは falseが呼び出し元のacceptに伝わるわけです。

テストしてみる

ではこのコンポーネントを読み込んで実際にテストしてみましょう。

<script src="./js/v-image-checkbox.js"></script>

ちなみに、よりtruefalseの切り替えが分かりやすいよう、次のようにコード少し足してみました。

規約に同意する:<br><br>
<v-image-checkbox
    true-image="/images/ok.png"
    false-image="/images/ng.png"
    v-model="accept">
</v-image-checkbox>
<button type="button" :disabled="!accept">送信する</button>

つまり、acceptの中身がtrueならボタンはクリックできますが、falseならクリックはできないようdisabledを設定しています。

では、実際に見ていきましょう。

まずページを表示した初期状態です。
ボタンは無効になっています。

続いて、画像をクリックしてみます。

画像が自動的に切り替わり、ボタンも有効になりました。

教材をダウンロードする

今回開発したコード(コンポーネントを含む)教材を以下からダウンロードできます。

再配布はできないので画像は変更してありますが、cdnを使ってvueを読み込んでいるのですぐ動作を確認することができます。

2枚の画像を切り替えるチェックボックス: ソースコード