簡単にTypeScriptでVuex入門をしたかったのでTodoリストを作ってみました。
(※pageの記載はtsですが、ストアはjsで実装しています)
この記事で伝えること
- pages/index.vueでのストアの呼び出し方
- JavaScriptとTypeScriptの比較
この記事で伝えないこと
- 環境構築
- TypeScriptでのストアの書き方
- Vuexの解説
①ストアを作成(JavaScript)
下記リンクを参考にストアを作っていきます
ディレクトリ構成
- pages
- index.vue(TypeScriptでのtodoリスト)
- todos.vue(JavaScriptでのtodoリスト)
- store(ストアはJS・TS共に共通)
- index.js
- todos.js
export const mutations = {
add(state, text) {
state.todos.list.push({
text: text,
done: false
})
},
remove(state, { todo }) {
state.list.splice(state.list.indexOf(todo), 1)
},
toggle(state, todo) {
todo.done = !todo.done
}
}
export const state = () => ({
list: []
})
モジュールモードなので、明示的に new Vuex.Store
する必要はありません。
モジュールモード: store ディレクトリ内のすべての *.js ファイルが 名前空間付きモジュール に変換されます(index はルートモジュールとして存在します)
②まずはお馴染みのJavaScriptで実装
<template>
<ul>
<li v-for="(todo, i) in todos" :key="i">
<input type="checkbox" :checked="todo.done" @change="toggle(todo)" />
<span :class="{ done: todo.done }">{{ todo.text }}</span>
</li>
<li>
<input placeholder="What needs to be done?" @keyup.enter="addTodo" />
</li>
</ul>
</template>
<script>
import { mapMutations } from 'vuex'
export default {
computed: {
todos() {
return this.$store.state.todos.list
}
},
methods: {
addTodo(e) {
this.$store.commit('add', e.target.value)
e.target.value = ''
},
...mapMutations({
toggle: 'toggle'
})
}
}
</script>
<style>
.done {
text-decoration: line-through;
}
</style>
このコードでしっかりと動作・エラーが出ないことを確認します。
③TypeScriptで実装
上記のコードをTypeScriptで書くとこのようになります。
-- template内は上記コードと同様 --
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'
import { mapMutations } from 'vuex'
@Component({
methods: {
...mapMutations({ toggle: 'toggle' })
}
})
export default class extends Vue {
private get todos(): Object {
return this.$store.state.todos.list
}
addTodo(e): void {
this.$store.commit('add', e.target.value)
e.target.value = ''
}
}
</script>
TypeScriptでの変更点は以下です。
vue-property-decoratorの導入
methods
メソッドはクラスのメソッドになるため、 methods: {}
の記述は不要です。
computed
computedは getter / setter で記述します。
map系ヘルパー(Vuex)
メソッドは上記のようにクラスのメソッドとして記述しますが、
...mapMutations を使う場合、@Component内にそのまま書きます
ちなみに、下記記事によるとmap系ヘルパーを使うと全てanyになってしまうため、TypeScriptで記述する恩恵が少ないみたいです。
→ Vuexによる状態管理を含む最高に快適な Vue.js + TypeScript の開発環境を目指す話 - Qiita
以上で、<script>
から<script lang="ts">
化ができました!
Vue(Nuxt)でTypeScriptを書く際は、すこしクセがあるのでJSとの違いがわかるVuexのコードを見たくて書きました。
ストアをTS化したらまた書きたいと思います。
参考資料
めちゃくちゃわかりやすいです
上記以外のTypeScriptの書き方が不明な方はこちらを参考に
ストアをTS化するときに参考にしたいと思ってます
クラスの書き方がわからないときはこちら
Vuexのmap系ヘルパーをどう使えば良いか悩みました
こちらを参考に@Component内に記述しました