概要
Vue.jsでVuex+axiosを利用してみました。
コードをシンプルにすると理解が進んで良いです^^
GitHubにコードをUPしましたので、よろしければご参考ください。
https://github.com/kai-kou/vue-js-typescript-vuex-axios
環境構築
Dockerを利用して、APIのモックサービスも立ち上げられるようにdrakovを利用しています。
drakovについては下記をご参考ください。
api blueprintとdrakovを利用してAPIモックサーバを立ち上げる
https://cloudpack.media/43359
> mkdir 任意のディレクトリ > cd 任意のディレクトリ > vi Dockerfile > vi docker-compose.yml
Dockerfile
FROM node:10.8.0-stretch RUN npm install --global @vue/cli RUN npm install -g drakov WORKDIR /projects
docker-compose.yml
version: '3' services: app: build: . ports: - "8080:8080" volumes: - ".:/projects" tty: true drakov: build: . ports: - "3000:3000" volumes: - "./docs:/projects" tty: true command: drakov -f "**/*.md" --public --watch --p 3000
API用のmdファイルを用意しておきます。
> mkdir docs > touch docs/sample.md
docs/sample.md
# GET / + Response 200 (text/plain) Hello World!
コンテナを起動して、Vue.jsのプロジェクトを作成するコンテナに入ります。
> docker-compose up -d > docker-compose exec app bash
コンテナ内
> vue create app Vue CLI v3.0.1 ? Please pick a preset: Manually select features ? Check the features needed for your project: Babel, TS, Vuex, Linter, Unit ? Use class-style component syntax? Yes ? Use Babel alongside TypeScript for auto-detected polyfills? Yes ? Pick a linter / formatter config: TSLint ? Pick additional lint features: Lint on save ? Pick a unit testing solution: Mocha ? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? In dedicated config files ? Save this as a preset for future projects? No ? Pick the package manager to use when installing dependencies: (Use arrow keys) ❯ Use Yarn Use NPM
プロジェクトが作成されたらVue.jsサービスを起動します。
コンテナ内
> cd app > yarn serve
src/store.tsに実装を追加します。
Stateにcounter
とmessage
を用意してcounter
をインクリメントするアクションと、APIからテキストを取得してmessage
に保存するアクションを追加しました。
src/store.ts
import Vue from 'vue'; import Vuex from 'vuex'; import axios from 'axios'; Vue.use(Vuex); interface State { conuter: number; message: string; } export default new Vuex.Store({ state: { conuter: 0, message: '', } as State, getters: { getCounter: (state, getters) => () => { return state.conuter; }, getMessage: (state, getters) => () => { return state.message; }, }, mutations: { increment(state, payload) { state.conuter += 1; }, getMessage(state, payload) { state.message = payload.message; }, }, actions: { incrementAction(context) { context.commit('increment'); }, async getMessageAction(context) { const payload = { message: '', }; await axios.get('http://localhost:3000') .then((res) => { payload.message = res.data; }); context.commit('getMessage', payload); }, }, });
src/main.tsはそのままです。
src/main.ts
import Vue from 'vue'; import App from './App.vue'; import store from './store'; Vue.config.productionTip = false; new Vue({ store, render: (h) => h(App), }).$mount('#app');
src/App.vueでStoreが利用できるようにします。
画像をクリックとcounter
のインクリメントとAPIアクセスがされるようにしています。
src/App.vue
<template> <div id="app"> <p>{{ message }}</p> <img alt="Vue logo" src="./assets/logo.png" @click="increment"> <HelloWorld :msg="`Welcome to Your Vue.js + TypeScript App ${this.counter}`"/> </div> </template> <script lang="ts"> import { Component, Vue } from 'vue-property-decorator'; import HelloWorld from './components/HelloWorld.vue'; @Component({ components: { HelloWorld, }, }) export default class App extends Vue { private get counter(): number { return this.$store.getters.getCounter(); } private get message(): string { return this.$store.getters.getMessage(); } private increment(): void { this.$store.dispatch('incrementAction'); this.$store.dispatch('getMessageAction'); } } </script> (略)
ブラウザで確認してみます。
> open http://localhost:8080/
はい。
うまくAPIにアクセスできてますね。
ポイントとしてはsrc/store.tsでAPIアクセス時にasync
とawait
を利用するところでしょうか?利用しなくても以下のように書けますが、行き着く先に、きっとコールバック地獄が待っていると思います^^
src/store.ts(抜粋)
getMessageAction(context) { const payload = { message: '', }; axios.get('http://localhost:3000') .then((res) => { payload.message = res.data; context.commit('getMessage', payload); }); },
GitHubの方に、vuex-type-helperというライブラリを利用してstoreをモジュール化する実装も置いてますので、ご参考ください。
vuex-type-helperについては別記事にまとめています。
VuexをTypeScriptで利用するのに悩んだ
https://cloudpack.media/42966
それでは、良きVuex+axiosを利用したVue.js開発ライフを^^
Vue.js+TypeScriptで開発するときの参考記事まとめ
https://cloudpack.media/43084