——-
追記2
うまくいったのでこっちの記事の方が良いです
>> [TypeScript] Vue.jsをTypeScriptで使ってみたい -> 成功した
——-
追記1
新しい記事かきました。たぶんこっちの方が良いと思います。
> [TypeScript] Vue.jsをTypeScriptで使ってみたい2
以下もとの記事
——-
こんにちは。きんくまです。
今回はVue.jsをTypeScriptで試してみたメモでございます。
>> 作ったデモです。ボタンを押すとメッセージが変わって、下のところはTODOリストです。
TypeScriptは関数型っぽいソースの分け方じゃなくて、やっぱりMVCっぽいのがいいのかなと思ってます。わかりやすいし。
で、View部分を担当するのはいろいろあってReactとかもあるんだけど、JSの中にDOM書いていくのが自分的にどうにも嫌で、Vue.jsを試してみた次第です。
Vue.jsはGettings Startedを見る限りすぐにできそうでした。
> Getting Started
それで、これをTypeScriptからも使いたいと思って、Vueそのものをextendしてみたり、いろいろしたんだけれどもうまくいかなかったです。またネットを検索してみたんだけど、いろいろやり方はあるみたいだけど、もうちょっとTSそのままっぽい書き方がないかなと今回自己流に書いてみました。
まずはhtml部分です。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>vue</title> <link rel="stylesheet" href="css/sample.css" /> </head> <body> <div id="app"> <h3>メッセージ</h3> <p>{{ message }}</p> <div class="message_button" v-on:click="changeMessage">click me</div> <h3>TODOリスト</h3> <div id="todo_input"> <input id="editing_todo_message" v-model="editingTodoMessage"> <div class="todo_add_button" v-on:click="addTodo"> + </div> </div> <ul id="todo_list"> <li v-for="todo in todos" v-on:click="removeTodo($index, $event)"> {{ todo.text }} </li> </ul> </div> <script src="js/jquery-1.11.2.min.js"></script> <script src="js/vue.min.js"></script> <script src="js/main.js"></script> <script> $(function(){ var main = new Main(); main.init({ }); }); </script> </body> </html>
つぎにVueのTSファイルです
/// <reference path="./defs/vue.d.ts" /> class SampleVueModel { //メッセージ部分用 message:string = "hello vue"; count:number = 0; //TODO用 todos:any[] = []; editingTodoMessage:string = ''; countUp(){ this.count++; } resetTodos(){ this.todos = []; } addTodo(todoMessage:string){ this.todos.push({ text: todoMessage }); } removeTodo(index:number){ if(index + 1 > this.todos.length){ console.log('index error'); return; } this.todos.splice(index, 1); } } export default class SampleVueController{ appVue:any; el:string = "#app"; model:SampleVueModel; constructor(){ this.model = new SampleVueModel(); this.appVue = new Vue({ el:this.el, data: this.model, methods:{ changeMessage:(e)=>{ this.changeMessage(e); }, addTodo:(e)=>{ this.addTodo(e); }, removeTodo:(index, e)=>{ this.removeTodo(index, e);} } }); } changeMessage(e){ this.model.message = "hello vue " + this.model.count; this.model.countUp(); } addTodo(e){ this.model.addTodo(this.model.editingTodoMessage); } removeTodo(index, e){ this.model.removeTodo(index); } }
ポイントとしては、Vueそのものを継承するんじゃなくて vueをプロパティとしてもつControllerを作成するところと、vueのdataをModelとしてクラス化するところです。
Vue.jsは最初に new Vue({ ここに初期化処理 }) っていうふうにする必要があるみたいです。
Vueそのものを継承すると、その初期化のタイミングと TypeScriptのコンストラクタとsuperのタイミングがかみあわなくてうまくいかないみたいです。
なので、vueのコントローラーとしてクラスを作りました。
あと、 初期化処理に data というオブジェクトを入れてあげると2-wayバインディングができるみたいです。
APIのdataの項目を読むと「ゲッターセッターとかprototypeとか無視するよー」と書いているので、逆手をとって自前のModelクラスを突っ込んでみました。
vueのmethods部分は渡し方をいろいろと試してみたけど、結局この書き方になりました。ちょっとめんどいけど、許容範囲という結論です。
こんな感じにやれば、TypeScriptとVue.jsは共存できそうかなと思いました。
まだまだ暑い日が続きますが、体調にお気をつけて!
■ 自作iPhoneアプリ 好評発売中!
・フォルメモ - シンプルなフォルダつきメモ帳
・ジッピー電卓 - 消費税や割引もサクサク計算!
■ LINEスタンプ作りました!
毎日使える。とぼけたウサギ