1. 環境構築と基本セットアップ
1.1 Vueプロジェクトの初期化
CLIまたはGUIツールによりVue 2.xプロジェクトを生成し、IDEでプロジェクトを開く。
1.2 Element UIの導入
以下のコマンドでライブラリをインストール:
npm install element-ui --save
1.3 メインスクリプトでのグローバル登録
main.js に以下を追加:
import Vue from 'vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
2. 認証フローと状態管理
2.1 ログイン画面の実装
Vuex を利用し、認証状態をグローバルに管理。LoginView.vue では以下のような構成:
<template>
<el-row type="flex" justify="center">
<el-col :span="10">
<el-card>
<h2>システムへようこそ</h2>
<el-form ref="loginForm" :model="credentials" label-width="80px">
<el-form-item label="ID">
<el-input v-model="credentials.id" placeholder="ユーザーID" />
</el-form-item>
<el-form-item label="パスワード">
<el-input v-model="credentials.password" type="password" show-password />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="attemptLogin">ログイン</el-button>
</el-form-item>
</el-form>
</el-card>
</el-col>
</el-row>
</template>
<script>
import { mapActions } from 'vuex'
export default {
name: 'LoginView',
data() {
return {
credentials: { id: '', password: '' }
}
},
methods: {
...mapActions('auth', ['authenticate']),
async attemptLogin() {
try {
const res = await this.authenticate(this.credentials)
if (res.success) {
this.$message.success('ログインに成功しました')
this.$router.push({ name: 'Dashboard' })
} else {
this.$message.error('IDまたはパスワードが正しくありません')
}
} catch (err) {
console.error('ログインエラー:', err)
this.$message.error('通信エラー')
}
}
}
}
</script>
2.2 Vuexによる認証状態と永続化
/store/modules/auth.js:
import Vue from 'vue'
const state = {
currentUser: null
}
const mutations = {
SET_USER(state, user) {
state.currentUser = user
},
CLEAR_USER(state) {
state.currentUser = null
}
}
const actions = {
async authenticate({ commit }, { id, password }) {
try {
const response = await Vue.prototype.$axios.get('/api/auth', {
params: { id, password }
})
if (response.status === 200 && response.data.code === 2000) {
commit('SET_USER', response.data.user)
return { success: true }
}
return { success: false }
} catch (e) {
throw e
}
},
logout({ commit }) {
commit('CLEAR_USER')
}
}
export default { namespaced: true, state, mutations, actions }
/store/index.js で状態をセッションに永続化:
import Vuex from 'vuex'
import createPersistedState from 'vuex-persistedstate'
import auth from './modules/auth'
export default new Vuex.Store({
modules: { auth },
plugins: [
createPersistedState({
storage: window.sessionStorage,
key: 'auth_state'
})
]
})
3. 画面構成とルーティング制御
3.1 認可钩子関数とルート定義
router/index.js:
import VueRouter from 'vue-router'
import { store } from '@/store'
import LoginView from '@/views/LoginView.vue'
import DashboardView from '@/views/DashboardView.vue'
const routes = [
{ path: '/', redirect: '/login' },
{ path: '/login', name: 'Login', component: LoginView },
{
path: '/dashboard',
name: 'Dashboard',
component: DashboardView,
meta: { requiresAuth: true }
},
{
path: '/user',
name: 'UserList',
component: () => import('@/views/UserListView.vue'),
meta: { requiresAuth: true }
}
]
const router = new VueRouter({
mode: 'history',
routes
})
router.beforeEach((to, from, next) => {
const isAuthRequired = to.matched.some(record => record.meta.requiresAuth)
const user = store.state.auth.currentUser
if (isAuthRequired && !user) {
next({ name: 'Login', query: { redirect: to.fullPath } })
} else {
next()
}
})
export default router
3.2 ダッシュボードレイアウト(主画面)
<template>
<el-container class="app-container">
<el-header class="app-header">
<div class="header-left">管理ダッシュボード</div>
<el-button type="text" @click="logout">ログアウト</el-button>
</el-header>
<el-container>
<el-aside width="200px" class="app-aside">
<el-menu :default-openeds="['dashboard']">
<el-submenu index="dashboard">
<template #title>
<i class="el-icon-s-operation"></i>
<span>ダッシュボード</span>
</template>
<el-menu-item index="1">
<router-link :to="{ name: 'Dashboard' }">概要</router-link>
</el-menu-item>
</el-submenu>
<el-submenu index="user">
<template #title>
<i class="el-icon-user"></i>
<span>ユーザー管理</span>
</template>
<el-menu-item index="2">
<router-link :to="{ name: 'UserList' }">一覧</router-link>
</el-menu-item>
</el-submenu>
</el-menu>
</el-aside>
<el-main>
<router-view />
</el-main>
</el-container>
</el-container>
</template>
<script>
import { mapActions } from 'vuex'
export default {
name: 'DashboardView',
methods: {
...mapActions('auth', ['logout'])
}
}
</script>
<style scoped>
.app-container { height: 100vh; }
.app-header { display: flex; justify-content: space-between; align-items: center; }
.app-aside { background-color: #f0f1f5; }
</style>
3.3 ユーザー一覧画面:検索・ページネーション対応
検索
クリア
編集
削除
import axios from 'axios'
export default {
name: 'UserListView',
data() {
return {
users: [],
filters: { id: '', phone: '' },
currentPage: 1,
pageSize: 10,
totalCount: 0
}
},
async mounted() {
await this.loadUsers()
},
methods: {
async loadUsers(page = 1) {
try {
const { data } = await axios.get('/api/users', {
params: {
pageNum: page,
pageSize: this.pageSize,
...Object.fromEntries(Object.entries(this.filters).filter(([_, v]) => v))
}
})
this.users = data.records || []
this.totalCount = data.total || 0
this.currentPage = page
} catch (e) {
console.error('ユーザー取得失敗:', e)
}
},
handleSizeChange(size) {
this.pageSize = size
this.loadUsers()
},
handlePageChange(page) {
this.loadUsers(page)
},
searchUsers() {
this.loadUsers(1)
},
resetFilters() {
this.filters = { id: '', phone: '' }
this.loadUsers(1)
},
handleEdit(user) {
// 編集モーダルを開く処理
},
handleDelete(user) {
this.$confirm('このユーザーを削除してもよろしいですか?', '確認', {
type: 'warning'
}).then(async () => {
await axios.delete(`/api/users/${user.id}`)
this.$message.success('削除完了')
this.loadUsers()
})
}
}
}
上記コードはVue 2 + Element UI v1.4系に準拠した典型的な管理画面実装を示しています。実際のバックエンドAPI连携時はレスポンス構造を適宜調整し、認証状態の管理にはVuexストアのモジュール設計を推奨します。