経緯
GET APIでデータをもらってきてVMに渡して、ユーザがそのデータを変更して、変更された内容をUPDATE APIに投げてサーバー側のデータを更新する!ようなことをしたいと思っていて、じゃあユーザが操作を間違えてしまったので手元の変更内容をキャンセルしたいことが生じたらどうしようかなと思ったので、$dataを初期状態に戻せるコンポーネントを作ってみました。
使い方
- 使いたいvmで
mixins: [resettable]
します。 - $dataの読み書きは通常どおり行えます。
- 初期値を読みたい時は
getBase([プロパティ名])
で取得できます。 -
reset()
メソッドで$data
を初期値に戻します。 -
setAsBase()
メソッドを呼ぶと、現在値を新しい初期値として扱います。 -
changed
プロパティで、初期値から書き換わっているかどうかを取得できます。
サンプルコード (scriptタグで読み込む版)
index.html
<script language="javascript" src="http://cdnjs.cloudflare.com/ajax/libs/vue/0.12.10/vue.js"></script>
<script language="javascript" src="http://satetsu888.github.io/vue-resettable/dest/vue-resettable.js"></script>
<div id="app">
<color-component color="#aabbcc"></color-component>
</div>
<script type="x-template" id="color-component">
<div>
<p style="background-color:{{getBase('color')}}">baseData:{{getBase('color')}}</p>
<p style="background-color:{{color}}">currentData:{{color}}</p>
<p><input type=text v-model="color"></p>
changed: {{changed("color")}} <br>
<input type=button value="Reset" v-on="click: reset">
<input type=button value="Update"v-on="click: update()">
</div>
</script>
<script>
var colorComponent = Vue.extend({
props: ["color"],
template: "#color-component",
mixins: [resettable]
});
var app = new Vue({
el: '#app',
components:{
'color-component': colorComponent
}
})
</script>
サンプルコードとデモ(webpack版)
本体
内部でやってること
-
created
イベントのタイミングで、内部で base, current という名前でもっているプロパティに初期値と現在の値を登録します。この時、base, current以外のmixin
されたプロパティを全て$watch
し、更新をcurrentにも反映するようにします。 -
reset
時は base プロパティの中身を使って、currentおよびそれ以外の全てのプロパティの中身を書き換えます。 -
setAsBase
の時は逆に、currentでbaseを書き換えます。
TODO
- base, currentというプロパティを使っている状態なので、mixinしても迷惑をかけないようにする
- computed propertyの変更も見張れるようにとか
おまけ
なんとか動くようにはなったんですが、もうちょっとスマートな実装方法がありそうな気がしています。よりよい方法をご存知の方、同じようなことがやりたくて困っている方は情報をお寄せください。