ログインを実装
ログイン画面作成
Login.vue
<template>
<v-form>
<v-container>
<v-row>
<v-col cols="12">
<v-text-field
v-model="username"
label="Username"
outlined
></v-text-field>
</v-col>
</v-row>
<v-row>
<v-col cols="12">
<v-text-field
v-model="password"
outlined
label="Password"
style="min-height: 96px"
type="password"
>
</v-text-field>
</v-col>
</v-row>
<div class="text-right">
<v-btn depressed large color="primary">ログイン</v-btn>
</div>
</v-container>
</v-form>
</template>
<script>
export default {
name: 'Login',
data: function () {
return {
username: null,
password: null
}
},
mounted () {
//
}
}
</script>
router/index.tsを修正
router/index.ts
import Vue from 'vue'
import Router from 'vue-router'
import PlayScreen from '@/views/PlayScreen.vue'
import Login from '@/views/Login.vue'
Vue.use(Router)
export default new Router({
mode:'history',
routes: [
{
path: '/',
redirect: 'login'
},
{
path: '/login',
name: 'login',
component: Login
},
{
path: '/playscreen',
name: 'playscreen',
component: PlayScreen
},
]
})
npm run dev
すると作成したログイン画面が初期表示されるようになります。
vuexのインストール
npm install vuex --save
axiosをインストール
axiosは「Promise ベースの HTTP クライアント」です(公式より)。
npm install axios --save
axiosでget, postリクエストを投げる共通関数を用意
src
直下にapi
フォルダを用意し、またその直下にcommon.tsを作成してaxiosの共通関数を用意
concentratio # プロジェクトルートディレクトリ
├── config
│ ├── ...
│
├── frontend
│ ├── ...
│ ├── ..
│ ├── .
│ └── src
│ └──api # 作成
│ └──common.ts # 作成
└── manage.py
src/api/common.ts
import axios from "axios";
const baseRequest = axios.create({
baseURL: "http://localhost:8000",
headers: {
"Content-Type": "application/json",
}
});
/**
* GETリクエスト
* @param url URL
*/
function get(url) {
return baseRequest.get(url);
}
/**
* POSTリクエスト
* @param url URL
*/
function post(url, payload) {
return baseRequest.post(url, payload);
}
export default {
get,
post
};
認証用のvuexモジュールを用意
単一のgettersやactionsで管理するとソースコードが膨れ上がるだけだなあと思って機能毎にモジュール分割してみようと思って挑んだのですが、見事に半日ほどハマりました・・・。concentratio # プロジェクトルートディレクトリ
├── config
│ ├── ...
│
├── frontend
│ ├── ...
│ ├── ..
│ ├── .
│ └── src
│ └──store # 作成
│ └──authenticates # 作成
│ ├──actions.ts # 作成
│ └──index.ts.ts # 作成
│ └──mutations.ts # 作成
└── manage.py
store/authenticates/actions.ts
import commonAxios from "../../api/common";
export default {
LOGIN: function({ commit }, payload) {
return new Promise((success, error) => {
commonAxios.post("/api-token-auth/", payload).then(
response => {
// 成功時の処理
commit("SET_TOKEN", response.data.token); // mutations.tsのSET_TOKEN関数にトークンを渡す
commonAxios.baseRequest.defaults.headers.common['Authorization'] = `JWT ${response.data.token}`;
success();
}
);
});
}
}
store/authenticates/index.ts
import actions from './actions';
export const state = {};
export default {
namespaced: true, // 必ずつける、外すとvueのmapActionsで読み込む時にエラーになるよ。
state,
actions,
mutations
};
store/authenticates/mutations.ts
export default {
SET_TOKEN: function(state, token) {
state.token = token
}
};
src/store
直下にindex.ts
を作成
store/index.ts
import Vue from "vue";
import Vuex from "vuex";
import authModules from "./authenticates"; // authenticates配下のモジュールをauthModulesという名前で読み込む
Vue.use(Vuex);
export default new Vuex.Store({
modules: {
authModules: authModules,
}
});
src/main.ts
を修正
src/main.ts
.
..
...
import store from "./store"; // 追加
...
..
.
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>',
vuetify: new Vuetify(),
store // 追加
});
Login.vueを修正
Login.vue
<template>
<v-form>
<v-container>
...
..
.
<div class="text-right">
<v-btn depressed large color="primary" @click="login">
ログイン
</v-btn>
</div>
</v-container>
</v-form>
</template>
<script>
import { mapActions } from "vuex";
export default {
name: "Login",
data: function() {
return {
username: null,
password: null
};
},
methods: {
...mapActions("authModules", ["LOGIN"]), // モジュール分割したaction.tsからLOGIN関数を読み込み
login: function() {
const data = {
username: this.username,
password: this.password
};
this.LOGIN(data).then(res => {
console.log(res);
});
}
},
mounted() {
//
}
};
</script>
responseが返ってくるか確認
正しいusernameとpasswordを入力後ログインボタン押下でresponseが返ってくる確認します。
返ってきました!
認証成功後、トップページに遷移するようにする。
Login.vue
のconsole.log(res);
をthis.$router.push("/playscreen");
に書き換えるだけ。
以上
無事、ログイン画面からトップページに遷移することができました。