Vue.js v-repeatで文字列を指定するとv-modelが動かない


vue.jsのv-repeatの中でinput要素等にbindingのためのv-modelを指定した時に少しはまったのでメモ。

以下のようなvue modelを定義して、modelの中の配列をhtml側でv-repeatを使用して、ループの中でbindingを指定する時に以下のようなコードで動くと思っていました。

文字列のArrayを持つVue model

  Vue.extend({
        template: "#test",
        data: {
            texts: ["hoge", "fuga"]
        },
        methods: {
            add: function(){
                this.texts.push("hogehoge");
            }
        }
    });

v-repeatで各input要素の値と文字列をv-modelによる指定でbindingするhtml

<div id="test">
    <div v-repeat="texts">
        <input type="text" v-model="$value">
    </div>
    <div v-on="click: add()">追加</div>
</div>

これで追加ボタンを押すと、自動的にhogehogeという値がセットされたinput要素が随時追加されていくのかなー、っと思ったらならない!

しばし奮闘して原因が判明。
Vueのv-repeatは対象の”オブジェクト”に対して独自にgetter/setterを追加してbindingを実現しており、単なる文字列だとgetter/setterが追加されないようです。

ということで以下のようにオブジェクトの配列で書き直すと期待通り動きます。

    Vue.extend({
        template: "#test",
        data: {
            texts: [{value: "hoge"}, {value: "fuga"}]
        },
        methods: {
            add: function(){
                this.texts.push({value: ""});
            }
        }
    });