Vue.jsを使って管理画面を作る
はじめに
Cloud9 + Vue.jsを使って管理画面を作成するチュートリアルとなります。
管理画面テンプレートの導入
Cloud9のターミナルで以下実行します。
Cloud9の基本的な操作方法は以下を参考にしてください。
Core UI のダウンロード
# リポジトリのクローン
git clone https://github.com/coreui/coreui-free-vue-admin-template.git CoreUI-Vue
# ダウンロードしたCore UIのディレクトリに移動
cd CoreUI-Vue
# パッケージをインストール
npm install
Vue 設定ファイルの更新
module.exports = {
// 以下追加
devServer: {
disableHostCheck: true
},
// 以上追加
lintOnSave: false,
runtimeCompiler: true,
configureWebpack: {
//Necessary to run npm link https://webpack.js.org/configuration/resolve/#resolve-symlinks
resolve: {
symlinks: false
}
},
transpileDependencies: [
'@coreui/utils',
'@coreui/vue'
]
}
セキュリティグループの設定
画面右上にあるManage EC2 Instanceを選択
EC2インスタンスにチェックを入れてセキュリティグループを選択
インバウンドルールを編集を選択
ルールを追加をクリックして、左から順に「カスタムTCP」、「8080」、「マイIP」を選択
テストサーバを起動
Cloud9に戻りテストサーバを起動します。
npm run serve
アプリケーションにアクセス
Cloud9のプレビューボタンをクリックして表示できたらOKです。
プレビュー画面の右上のボタンをクリックすると別タブで大きく表示できます。
管理画面のカスタマイズ
管理画面にTodosページを追加してみましょう。
テストサーバを停止
テストサーバを停止します。
Cloud9のnpm run serve
を実行しているターミナルを選択してctrl + c
を押します。
画面を選択した状態でctrl(Control) + c
(MacはCommand
と間違えないように注意)
ナビゲーションメニューにTodosを追加
既存のファイルを以下のように編集します。
export default [
{
_name: 'CSidebarNav',
_children: [
// 以下追加
{
_name: 'CSidebarNavItem',
name: 'Todos',
to: '/todos',
icon: 'cil-check',
},
// 以上追加
{
_name: 'CSidebarNavItem',
name: 'Dashboard',
to: '/dashboard',
icon: 'cil-speedometer',
badge: {
color: 'primary',
text: 'NEW'
}
},
(以下省略)
import Vue from 'vue'
import Router from 'vue-router'
// Containers
const TheContainer = () => import('@/containers/TheContainer')
// Views
const Dashboard = () => import('@/views/Dashboard')
const Colors = () => import('@/views/theme/Colors')
const Typography = () => import('@/views/theme/Typography')
const Charts = () => import('@/views/charts/Charts')
const Widgets = () => import('@/views/widgets/Widgets')
// Views - Components
const Cards = () => import('@/views/base/Cards')
const Forms = () => import('@/views/base/Forms')
const Switches = () => import('@/views/base/Switches')
const Tables = () => import('@/views/base/Tables')
const Tabs = () => import('@/views/base/Tabs')
const Breadcrumbs = () => import('@/views/base/Breadcrumbs')
const Carousels = () => import('@/views/base/Carousels')
const Collapses = () => import('@/views/base/Collapses')
const Jumbotrons = () => import('@/views/base/Jumbotrons')
const ListGroups = () => import('@/views/base/ListGroups')
const Navs = () => import('@/views/base/Navs')
const Navbars = () => import('@/views/base/Navbars')
const Paginations = () => import('@/views/base/Paginations')
const Popovers = () => import('@/views/base/Popovers')
const ProgressBars = () => import('@/views/base/ProgressBars')
const Tooltips = () => import('@/views/base/Tooltips')
// Views - Buttons
const StandardButtons = () => import('@/views/buttons/StandardButtons')
const ButtonGroups = () => import('@/views/buttons/ButtonGroups')
const Dropdowns = () => import('@/views/buttons/Dropdowns')
const BrandButtons = () => import('@/views/buttons/BrandButtons')
// Views - Icons
const CoreUIIcons = () => import('@/views/icons/CoreUIIcons')
const Brands = () => import('@/views/icons/Brands')
const Flags = () => import('@/views/icons/Flags')
// Views - Notifications
const Alerts = () => import('@/views/notifications/Alerts')
const Badges = () => import('@/views/notifications/Badges')
const Modals = () => import('@/views/notifications/Modals')
// Views - Pages
const Page404 = () => import('@/views/pages/Page404')
const Page500 = () => import('@/views/pages/Page500')
const Login = () => import('@/views/pages/Login')
const Register = () => import('@/views/pages/Register')
// Users
const Users = () => import('@/views/users/Users')
const User = () => import('@/views/users/User')
// -- 以下追加 --
// Todos
const Todos = () => import('@/views/todos/Todos')
// -- 以上追加 --
Vue.use(Router)
export default new Router({
mode: 'hash', // https://router.vuejs.org/api/#mode
linkActiveClass: 'active',
scrollBehavior: () => ({ y: 0 }),
routes: configRoutes()
})
function configRoutes () {
return [
{
path: '/',
redirect: '/dashboard',
name: 'Home',
component: TheContainer,
children: [
{
path: 'dashboard',
name: 'Dashboard',
component: Dashboard
},
{
path: 'theme',
redirect: '/theme/colors',
name: 'Theme',
component: {
render (c) { return c('router-view') }
},
children: [
{
path: 'colors',
name: 'Colors',
component: Colors
},
{
path: 'typography',
name: 'Typography',
component: Typography
}
]
},
{
path: 'charts',
name: 'Charts',
component: Charts
},
{
path: 'widgets',
name: 'Widgets',
component: Widgets
},
// 以下追加
{
path: 'todos',
name: 'Todos',
component: Todos
},
// 以上追加
{
path: 'users',
meta: {
label: 'Users'
},
component: {
render(c) {
return c('router-view')
}
},
children: [
{
path: '',
name: 'Users',
component: Users
},
{
path: ':id',
meta: {
label: 'User Details'
},
name: 'User',
component: User
}
]
},
(以下省略)
TodosページとTodoデータの追加
/CoreUI-Vue/src/views
にtodos
ディレクトリを追加します。
追加したtodos
ディレクトリにTodos.vue
ファイルと、TodosData.js
ファイルを作成します。
const todosData = [
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
},
{
"userId": 1,
"id": 2,
"title": "quis ut nam facilis et officia qui",
"completed": false
},
{
"userId": 1,
"id": 3,
"title": "fugiat veniam minus",
"completed": false
},
{
"userId": 1,
"id": 4,
"title": "et porro tempora",
"completed": true
},
{
"userId": 1,
"id": 5,
"title": "laboriosam mollitia et enim quasi adipisci quia provident illum",
"completed": false
},
{
"userId": 1,
"id": 6,
"title": "qui ullam ratione quibusdam voluptatem quia omnis",
"completed": false
},
{
"userId": 1,
"id": 7,
"title": "illo expedita consequatur quia in",
"completed": false
},
{
"userId": 1,
"id": 8,
"title": "quo adipisci enim quam ut ab",
"completed": true
},
{
"userId": 1,
"id": 9,
"title": "molestiae perspiciatis ipsa",
"completed": false
},
{
"userId": 1,
"id": 10,
"title": "illo est ratione doloremque quia maiores aut",
"completed": true
},
{
"userId": 1,
"id": 11,
"title": "vero rerum temporibus dolor",
"completed": true
},
{
"userId": 1,
"id": 12,
"title": "ipsa repellendus fugit nisi",
"completed": true
},
{
"userId": 1,
"id": 13,
"title": "et doloremque nulla",
"completed": false
},
{
"userId": 1,
"id": 14,
"title": "repellendus sunt dolores architecto voluptatum",
"completed": true
},
{
"userId": 1,
"id": 15,
"title": "ab voluptatum amet voluptas",
"completed": true
},
{
"userId": 1,
"id": 16,
"title": "accusamus eos facilis sint et aut voluptatem",
"completed": true
},
{
"userId": 1,
"id": 17,
"title": "quo laboriosam deleniti aut qui",
"completed": true
},
{
"userId": 1,
"id": 18,
"title": "dolorum est consequatur ea mollitia in culpa",
"completed": false
},
{
"userId": 1,
"id": 19,
"title": "molestiae ipsa aut voluptatibus pariatur dolor nihil",
"completed": true
},
{
"userId": 1,
"id": 20,
"title": "ullam nobis libero sapiente ad optio sint",
"completed": true
}
]
export default todosData
<template>
<CRow>
<CCol col="12" xl="8">
<CCard>
<CCardHeader>
Todos
</CCardHeader>
<CCardBody>
<CDataTable
hover
striped
:items="items"
:fields="fields"
:items-per-page="5"
clickable-rows
:active-page="activePage"
:pagination="{ doubleArrows: false, align: 'center'}"
@page-change="pageChange"
>
<template #completed="data">
<td>
<CBadge :color="getBadge(data.item.completed)">
{{data.item.completed}}
</CBadge>
</td>
</template>
</CDataTable>
</CCardBody>
</CCard>
</CCol>
</CRow>
</template>
<script>
import todosData from './TodosData'
export default {
name: 'Todos',
data () {
return {
items: todosData,
fields: [
{ key: 'userId' },
{ key: 'id' },
{ key: 'title' },
{ key: 'completed' }
],
activePage: 1
}
},
watch: {
$route: {
immediate: true,
handler (route) {
if (route.query && route.query.page) {
this.activePage = Number(route.query.page)
}
}
}
},
methods: {
getBadge (status) {
switch (status) {
case true: return 'success'
case false: return 'danger'
default: 'primary'
}
},
pageChange (val) {
this.$router.push({ query: { page: val }})
}
}
}
</script>
テストサーバを起動
テストサーバを起動します。
npm run serve
Todosページにアクセス
画面左のナビゲーションメニューにTodosが追加されているのでクリックします。
Todoの一覧が表示されていればOKです。
APIを使ったデータの読み込み
以下のAPIで取得できるJSONデータを使ってTodoリストを作成します。
Cloud9のターミナルに戻ります。
テストサーバを停止
Cloud9のnpm run serve
を実行しているターミナルを選択してctrl + c
を押します。
axiosのインストール
npm install axios
axiosのGET処理を追加
axiosでAPIからTodoデータを取得する処理を追加します。
Todosテーブルの読み込むデータをitems
からfetchItems
に変更するため、12行目を :items="fetchItems"
に更新しています。
<template>
<CRow>
<CCol col="12" xl="8">
<CCard>
<CCardHeader>
Todos
</CCardHeader>
<CCardBody>
<CDataTable
hover
striped
:items="fetchItems"
:fields="fields"
:items-per-page="5"
clickable-rows
:active-page="activePage"
:pagination="{ doubleArrows: false, align: 'center'}"
@page-change="pageChange"
>
<template #completed="data">
<td>
<CBadge :color="getBadge(data.item.completed)">
{{data.item.completed}}
</CBadge>
</td>
</template>
</CDataTable>
</CCardBody>
</CCard>
</CCol>
</CRow>
</template>
<script>
import todosData from './TodosData'
import axios from 'axios' // 追加
export default {
name: 'Todos',
data () {
return {
items: todosData,
fetchItems: [], // 追加
fields: [
{ key: 'userId' },
{ key: 'id' },
{ key: 'title' },
{ key: 'completed' }
],
activePage: 1
}
},
watch: {
$route: {
immediate: true,
handler (route) {
if (route.query && route.query.page) {
this.activePage = Number(route.query.page)
}
}
}
},
// 以下追加
mounted () {
this.getTodos()
},
// 以上追加
methods: {
// 以下追加
getTodos() {
axios.get('https://jsonplaceholder.typicode.com/users/2/todos')
.then(response => (this.fetchItems = response.data))
},
// 以上追加
getBadge (status) {
switch (status) {
case true: return 'success'
case false: return 'danger'
default: 'primary'
}
},
pageChange (val) {
this.$router.push({ query: { page: val }})
}
}
}
</script>
テストサーバを起動
テストサーバを起動します。
npm run serve
Todosページにアクセス
Todoの一覧の内容がUser Idが2のデータに変わっていればOKです。
Discussion