# 6.5 Vue プロジェクト作成(Pinia / Router / Vuetify 導入)
ここからは フロントエンド(Vue 3) を構築する。
Django API と連携するために、Vue プロジェクトを新規作成し、ログイン画面を用意する。
1. Vue プロジェクト作成
cd project
mkdir frontend
cd frontend
# Vite ベースで Vue プロジェクトを作成
npm create vite@latest . -- --template vue
# 依存パッケージをインストール
npm install
👉 今回は Vue CLI ではなく Vite ベースで進める。
公式も Vue 3 以降は Vite を推奨している。
2. 開発に必要なライブラリを追加
# 状態管理(Pinia)
npm install pinia
# ルーティング(Vue Router)
npm install vue-router
# UI コンポーネント(Vuetify)
npm install vuetify
npm install sass sass-loader --save-dev
npm install @mdi/font
# API 通信(axios)
npm install axios
3. Vuetify の設定
src/plugins/vuetify.js を作成:
// src/plugins/vuetify.js
import { createVuetify } from "vuetify";
import * as components from "vuetify/components";
import * as directives from "vuetify/directives";
import { aliases, mdi } from "vuetify/iconsets/mdi";
export default createVuetify({
components,
directives,
icons: {
defaultSet: "mdi",
aliases,
sets: {
mdi,
},
},
});
4. ルータとストアの設定
4.1 Router
src/router/index.js を作成:
import { createRouter, createWebHistory } from "vue-router";
import LoginView from "../views/LoginView.vue";
const routes = [
{ path: "/login", name: "Login", component: LoginView },
];
const router = createRouter({
history: createWebHistory(),
routes,
});
export default router;
4.2 Store
src/store/auth.js を作成:
import { defineStore } from "pinia";
export const useAuthStore = defineStore("auth", {
state: () => ({
user: null,
departments: [],
roles: [],
}),
actions: {
setUser(userData) {
this.user = userData;
this.departments = userData.departments || [];
this.roles = userData.roles || [];
},
clearUser() {
this.user = null;
this.departments = [];
this.roles = [];
},
},
});
5. main.js の修正
src/main.js を以下のように編集:
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import { createPinia } from "pinia";
import vuetify from "./plugins/vuetify";
const app = createApp(App);
app.use(router);
app.use(createPinia());
app.use(vuetify);
app.mount("#app");
6. App.vue の修正
デフォルトの Vite テンプレートを削除し、Router が機能するように修正する。
<template>
<router-view />
</template>
<script setup>
</script>
<style>
/* 共通スタイルをここに追加していく */
</style>
👉 これで /login にアクセスすると LoginView.vue が表示される。
7. axios の共通化
7.1 .env.development
frontend/ に .env.development を作成:
# Vue 側の環境変数は VITE_ プレフィックス必須
VITE_API_BASE_URL=http://localhost:8000/api/
👉 本番用には .env.production を用意して https://example.com/api/ などに切り替える。
補足:127.0.0.1 と localhost の違いに注意
Django 側の Cookie (sessionid, csrftoken) は 発行されたホスト名に紐づく
フロントが http://localhost:5173 で動いている場合、
VITE_API_BASE_URL を http://127.0.0.1:8000 にすると Cookie が別オリジン扱いになって送信されない
そのため、フロントとバックで 同じホスト名 (localhost) に統一 する必要がある
7.2 axios クライアント
src/api/axios.js を作成:
// src/api/axios.js
import axios from "axios";
// Cookie から csrftoken を取り出す関数
function getCsrfToken() {
const match = document.cookie.match(/csrftoken=([\w-]+)/);
return match ? match[1] : "";
}
const apiClient = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL, // 例: http://127.0.0.1:8000/api/
withCredentials: true, // Cookie を必ず送る
});
// リクエスト時に CSRF ヘッダを自動追加
apiClient.interceptors.request.use((config) => {
const token = getCsrfToken();
if (token) {
config.headers["X-CSRFToken"] = token;
}
return config;
});
export default apiClient;
7.3 認証 API
src/api/auth.js を作成:
import apiClient from "./axios";
export function login(username, password) {
return apiClient.post("auth/login/", { username, password });
}
export function logout() {
return apiClient.post("auth/logout/");
}
export function authStatus() {
return apiClient.get("auth/status/");
}
8. ログイン画面の作成
src/views/LoginView.vue を作成:
<template>
<v-container>
<v-card class="pa-6 mx-auto" max-width="400">
<v-card-title>ログイン</v-card-title>
<v-card-text>
<v-form @submit.prevent="handleLogin">
<v-text-field v-model="username" label="ユーザー名" required />
<v-text-field v-model="password" label="パスワード" type="password" required />
<v-btn type="submit" block color="primary">ログイン</v-btn>
</v-form>
<p v-if="error" class="text-error mt-2">{{ error }}</p>
</v-card-text>
</v-card>
</v-container>
</template>
<script setup>
import { ref } from "vue";
import { useAuthStore } from "../store/auth";
import { login, authStatus } from "../api/auth";
const username = ref("");
const password = ref("");
const error = ref("");
const authStore = useAuthStore();
async function handleLogin() {
try {
await login(username.value, password.value);
const res = await authStatus();
authStore.setUser(res.data);
alert("ログイン成功: " + res.data.username);
} catch (err) {
error.value = "ログイン失敗";
}
}
</script>
9. 動作確認
-
Django サーバーを起動
python manage.py runserver -
Vue 開発サーバーを起動
npm run dev -
http://localhost:5173/loginにアクセス


- ユーザー名・パスワード入力 → ログイン成功時にアラート表示
-
/api/auth/status/からユーザ情報を取得して Pinia に保存
今回のゴール
- Vue プロジェクトを新規作成(Vite ベース)
- Pinia / Vue Router / Vuetify を導入
- axios を共通化して env 管理に対応
- App.vue を修正し、ログイン画面を正しく表示
- Django API と接続してログイン確認
次の展開
次は 6.6 ログイン状態管理とメニュー画面 に進む。
ナビゲーションバーを Vuetify で実装し、ログイン状態に応じてメニューを制御する。
Discussion