0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Vueでできそうでできないこと(1) あるケースでのv-model

Posted at

はじめに

入力パーツがたくさんある場合、templateにバラで書くと長くなるのでv-forで回して生成したくなりますが、そこでv-modelをループ変数に基づいて動的に作ろうとすると、やりたいようにできないことがあります。

できる方法があればぜひ教えて下さい!

うまくいくケース

このようにv-modelの参照先が階層化されていてトップが固定のliteralで書ける場合は特に問題がありません。

<template>
    <div>
        <div v-for="key1 in level1" :id="key1">
            <span>{{ key1 }}</span>
            <div v-for="key2 in level2" :id="key2">
                <input v-model="form[key1][key2]">
            </div>
        </div>
    </div>
</template>
<script>
export default {
    data () {
        return {
            form: {
                tokyo: {
                    prop1: 0,
                    prop2: 0,
                },
                osaka: {
                    prop1: 0,
                    prop2: 0,
                },
            },
            level1: ["tokyo", "osaka"],
            level2: ["prop1", "prop2"],
        };
    },
};
</script>

うまく行かないケース

では上記のformの内容を1段上げてみるとどうでしょう。

<template>
    <div>
        <div v-for="key1 in level1" :id="key1">
            <span>{{ key1 }}</span>
            <div v-for="key2 in level2" :id="key2">
                <!-- this[key1][key2]に行ってほしい -->
                <input v-model="[key1][key2]">
            </div>
        </div>
    </div>
</template>
<script>
export default {
    data () {
        return {
            tokyo: {
                prop1: 0,
                prop2: 0,
            },
            osaka: {
                prop1: 0,
                prop2: 0,
            },
            level1: ["tokyo", "osaka"],
            level2: ["prop1", "prop2"],
        };
    },
};
</script>

エラーは出ませんが、値も変わりません。
内部的にどういう解釈になっているのか追っかけていないのでわかりませんが、とりあえず動作しません。

まとめ

上記のように、dataのトップレベルのプロパティ名を動的に指定する方法が見つかりませんでした。

通常はとりあえず1段下げれば回避できるのですが、
例えばvuexのストアの中にある値をv-modelで使いたい場合get/set形式のcomputed propertyにするのがよくありますが、computedは階層化できないので、1段下げることができません。

実は回避方法はひとつ見つけていて、このように遠回りにthisを置き換えると動きます。

<input v-model="$vnode.componentInstance[key1][key2]">

ただちょっと変化球ですしずっと使えるかどうかもわからないので、ストレートなやり方があったら教えて下さいませ。

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?