質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.62%

【Vue.js】アルファベットの配列をスマートに作成したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 413

ttkun

score 28

vue.js(Nuxt.js)で連続したアルファベットのファイルを作成しv-forで繰り返し出力しようとしました。
そのときscript内で配列からimageファイルを作成しtemplateに出力する方法がうまくないか調べています。

ファイルの作成

images/logo-a.png


こんな感じのファイルをアルファベット順に作成していきます。

images/logo-a.png
images/logo-b.png
images/logo-c.png
images/logo-d.png
images/logo-e.png

配列の作成

次に配列を作成します。

var alphabet = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];

配列をスマートに

ちょっとスマートじゃなかったのでこちらのサイトを参考にそのままですが作ってみました。
JavaScriptでアルファベットの配列をスマートに作る

function Range(first, last) {
    var first = first.charCodeAt(0);
    var last = last.charCodeAt(0);
    var result = new Array();
    for(var i = first; i <= last; i++) {
            result.push(String.fromCodePoint(i));
    }
    return result;
}

var alphabet = Range('A', 'Z');

アルファベットの配列を取得してv-forで出力する

こちらをまとめると下記のソースになります。

<template lang="pug">
    section.py-12
        v-container.mt-12.mb-6
            div(class="d-flex flex-wrap")
                .card(v-for="alphabet in alphabets" :key="alphabet.id")
                    img(:src="`/images/logo-${alphabet}.png`")
</template>


<script>
export default {    
    data () {
        function Range(first, last) {
            var first = first.charCodeAt(0);
            var last = last.charCodeAt(0);
            var result = new Array();
            for(var i = first; i <= last; i++) {
                                result.push(String.fromCodePoint(i));
            }
            return result;
        }
        var alphabets = Range('A', 'Z');
        return {
            alphabets,
        }
    },
}
</script>


こちらでも画像ファイルは出力するのですが、img部分をscript内に収めtemplate内をもっとスマートにしたいと思い。

img(:src="`/images/logo-${alphabet}.png`")

このような書き方をしたのですがうまく表示されません。

<template lang="pug">
    section.py-12
        v-container.mt-12.mb-6
            div(class="d-flex flex-wrap")
                .card(v-for="alphabet in alphabets" :key="alphabet.id")
                    img(:src="alphabet.logoimage")
</template>


<script>
export default {    
    data () {
        function Range(first, last) {
            var first = first.charCodeAt(0);
            var last = last.charCodeAt(0);
            var result = new Array();
            for(var i = first; i <= last; i++) {
                                result.push(String.fromCodePoint(i));
            }
            return result;
        }
    var alphabets = Range('A', 'Z');
    for(var j = 0; j < alphabets.length; j++) {
            alphabets.push({
                logoimage: `/images/home/logo-${this.alphabets}.png`
            })
        };
        return {
            alphabets,
        }
    },
}
</script>

dataの外の配列をscript内で回してv-forまで持っていく方法をさがしています。
従来のv-forでのやり方は検索したらでてくるのですがこのやり方の調べ方がよくないのかいまいち調べきれておりません。

配列されたものをscript内で回しtemplateで出力する方法のロジックや調べ方などの回答をお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

問題点は2つ

問題点は2つあります。

  1. 無限ループしている
  2. templateで必要としてるオブジェクトが作成できていない

1. 無限ループしている

alphabets作成後に実行しているfor文で無限ループを起こしています。

for(var j = 0; j < alphabets.length; j++) {
  alphabets.push({
    logoimage: `/images/home/logo-${this.alphabets}.png`
  })
};

ループはalphabets.lengthの数だけ繰り返します。
最初、alphabetsにはA~Zの26個格納されています。

ループ内の処理でalphabetsに新たな値を格納しています。つまり、alphabets.lengthはループ内の処理が実行されるたびに27, 28...と増えていきます。
ループ処理を繰り返すたびに増え続けるのでこのfor文は永遠と終わらず、無限ループしてしまいます。

2. templateで必要としてるオブジェクトが作成できていない

pugで書かれたtemplateには以下のように定義されています。

.card(v-for="alphabet in alphabets" :key="alphabet.id")
    img(:src="alphabet.logoimage")

alphabetsという配列の中には以下のようなオブジェクトがA~Zの26個格納されていることを必要としています。

{
  "id": "A",
  "logoimage": "/images/home/logo-A.png"
}

つまり、上記のようなオブジェクトの配列をdataで作成する必要があります。

解決策

  1. 無限ループを起こさない
  2. idlogoimageを持つオブジェクトを配列に格納する

この2点を対応します。

解決方法1: alphabetsとは別の配列を用意する

新たにalphabetObjectsという配列を用意し、そちらにtemplateで必要としているオブジェクトを格納していきます。

data() {
  function Range(first, last) {
        var first = first.charCodeAt(0);
        var last = last.charCodeAt(0);
        var result = new Array();
        for (var i = first; i <= last; i++) {
          result.push(String.fromCodePoint(i));
        }
        return result;
      }
      var alphabets = Range("A", "Z");
  var alphabetObjects = []; //idとlogoimageを持つオブジェクトを格納するための配列を用意
  for(var j = 0; j < alphabets.length; j++) {
    alphabetObjects.push({ // alphabetsではなくalphabetObjectsにオブジェクトを追加する
      id: alphabets[j],  // idの定義を追加
      logoimage: `/images/home/logo-${alphabets[j]}.png`  // this.alphabets -> alphabets[j]に変更
    })
  };

  return {
    alphabets: alphabetObjects
  };
}

解決方法2: map関数を使う。

Arrayのmap関数を使ってtemplateで必要としているオブジェクトの配列を作成します。
個人的には余計な変数を定義せずに済むのでこちらの書き方を好みます。

data() {
  function Range(first, last) {
    var first = first.charCodeAt(0);
    var last = last.charCodeAt(0);
    var result = new Array();
    for (var i = first; i <= last; i++) {
      result.push(String.fromCodePoint(i));
    }
    return result;
  }
  var alphabets = Range("A", "Z");
  return {
    alphabets: alphabets.map(alphabet => {
      return {
        id: alphabet,
        logoimage: `/images/home/logo-${alphabet}.png`
      };
    })
  };
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/04/12 11:16

    丁寧に解説ありがとうございます。
    こんなやり方があったのですね。大変勉強になりました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る