LoginSignup
17
7

More than 5 years have passed since last update.

Vue.jsでMap型データをv-forで取り出す方法

Last updated at Posted at 2018-01-12

結論から言うとあっているのかはわかりませんが

v-for="[key, val] in Array.from(map)" だと確実に動きました。

連想配列的なものは v-for="(val, key) in xxx" 形式でしか受け取れないと思っていたときにできたもの

<html>
  <head>
    <script src="https://unpkg.com/vue"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
  </head>
  <body>
    <div id="app">
      <div v-for="(val, key) in _.fromPairs(Array.from((new Map([['a', 10], ['b', 20]])).entries()))">
        {{key}}:{{val}}
      </div>
    </div>
    <script>
      new Vue({el: '#app'})
    </script>
  </body>
</html>

そのままではエラーもでずスルーされたので entries() を返してみたものの、それは配列ではなく MapIterator 型だったので試しに Array.from に渡してみたらキーと値のペアの配列になったものの、Array.from はあっても Object.from みたいなのがなくて素の連想配列に戻せず、しかし lodash にまさにそれ用の機能があったので使ってみた次第です。

正しい方法があったら教えてください。

さらに試行錯誤の結果 (val, key) ではなく [key, val] で受け取れることに気づく

<html>
  <head>
    <script src="https://unpkg.com/vue"></script>
  </head>
  <body>
    <script>
      console.log("方法1")
      const map = new Map([['a', 10], ['b', 20]])
      for (const [key, val] of map) {
        console.log(`${key}:${val}`)
      }
    </script>

    <div id="app">
      方法2
      <div v-for="[key, val] in Array.from(map.entries())">
        {{key}}:{{val}}
      </div>

      方法3
      <div v-for="[key, val] in Array.from(map)">
        {{key}}:{{val}}
      </div>

      方法4
      <div v-for="[key, val] in [...map.entries()]">
        {{key}}:{{val}}
      </div>

      方法5
      <div v-for="[key, val] in [...map]">
        {{key}}:{{val}}
      </div>
    </div>

    <script>
      const vm = new Vue({
        el: '#app',
        data: {
          map: new Map([['a', 10], ['b', 20]]),
        },
      })
    </script>
  </body>
</html>

方法1のように JavaScript の for で繰り返すとき [key, val] of map という書き方をするので試しに v-for の中で書いてみたら動きました(方法2)。ポイントは (val, key)[key, val] に変更したところです。このあたりドキュメントのどこにも見あたらなかったのは書くまでもないことだったのかそのへんはわかりません。とりあえず動いた方法2を元にした3、4、5の方法も動きました。(この結果だけ見ると entries() って何のためにあるんだろう?)

ところが単一ファイルコンポーネントのなかでは挙動がおかしい

喜びも束の間、.vue の中の template タグのなかで方法5の書き方 [...map] をすると動かなかったのは謎です。Vueのテンプレートのタグの構築を関数化(?)したときのスコープだとスプレッド演算子(...)が正しく解釈されないのかもしれません。とりあえずこの場合、Array.from(map) としたら動きました。

17
7
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
7