Created
October 6, 2018 23:50
-
-
Save takaheraw/79499e5a3295ea1374bcdc4a6f1bd3de to your computer and use it in GitHub Desktop.
vue router
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Vue.js SPAのサンプルアプリケーション</title> | |
<style> | |
[v-cloak] { | |
display: none | |
} | |
</style> | |
</head> | |
<body> | |
<div id="app"> | |
<nav> | |
<router-link to="/top">トップページ</router-link> | |
<router-link to="/users">ユーザー一覧ページ</router-link> | |
<router-link to="/users/new?redirect=true">新規ユーザー登録</router-link> | |
<router-link to="/login" v-show="!Auth.loggedIn()">ログイン</router-link> | |
<router-link to="/logout" v-show="Auth.loggedIn()">ログアウト</router-link> | |
</nav> | |
<router-view></router-view> | |
</div> | |
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script> | |
<script src="https://unpkg.com/[email protected]/dist/vue-router.js"></script> | |
<script type="text/x-template" id="user-list"> | |
<div> | |
<div class="loading" v-if="loading">読み込み中...</div> | |
<div v-if="error" class="error">{{ error }}</div> | |
<div v-for="user in users" :key="user.id"> | |
<router-link :to="{ path: '/users/' + user.id }">{{ user.name }}</router-link> | |
</div> | |
</div> | |
</script> | |
<script type="text/x-template" id="user-detail"> | |
<div> | |
<div class="loading" v-if="loading">読み込み中...</div> | |
<div v-if="error" class="error"> | |
{{ error }} | |
</div> | |
<div v-for="user"> | |
<h2>{{ user.name }}</h2> | |
<p>{{ user.description }}</p> | |
</div> | |
</div> | |
</script> | |
<script type="text/x-template" id="user-create"> | |
<div> | |
<div class="sending" v-if="sending">Sending...</div> | |
<div> | |
<h2>新規ユーザー作成</h2> | |
<div> | |
<label>名前: </label> | |
<input type="text" v-model="user.name"> | |
</div> | |
<div> | |
<label>説明文: </label> | |
<textarea v-model="user.description"></textarea> | |
</div> | |
<div v-if="error" class="error"> | |
{{ error }} | |
</div> | |
<div> | |
<input type="button" @click="createUser" value="送信"> | |
</div> | |
</div> | |
</div> | |
</script> | |
<script type="text/x-template" id=login> | |
<div> | |
<h2>Login</h2> | |
<p v-if="$route.query.redirect"> | |
ログインしてください | |
</p> | |
<form @submit.prevent="login"> | |
<label><input v-model="email" placeholder="email"></label> | |
<label><input v-model="pass" placeholder="password"></label> | |
<br> | |
<button type="submit">ログイン</button> | |
<p v-if="error" class="error">ログインに失敗しました</p> | |
</form> | |
</div> | |
</script> | |
<script> | |
var Auth = { | |
login: function(email, pass, cb) { | |
setTimeout(function() { | |
if(email === '[email protected]' && pass === 'vue') { | |
localStorage.token = Math.random().toString(36).substring(7) | |
if(cb) { cb(true) } | |
} else { | |
if(db) { cb(false) } | |
} | |
}, 0) | |
}, | |
logout: function() { | |
delete localStorage.token | |
}, | |
loggedIn: function() { | |
return !!localStorage.token | |
} | |
} | |
var userData = [ | |
{ | |
id: 1, | |
name: 'Takahero', | |
description: 'エンジニアです' | |
}, | |
{ | |
id: 2, | |
name: 'Nanase', | |
description: 'アイドルです' | |
} | |
] | |
var getUsers = function(callback) { | |
setTimeout(function() { | |
callback(null, userData) | |
}, 1000) | |
} | |
var getUser = function(userId, callback) { | |
setTimeout(function() { | |
var filteredUsers = userData.filter(function(user) { | |
return user.id === parseInt(userId, 10) | |
}) | |
callback(null, filteredUsers && filteredUsers[0]) | |
}, 1000) | |
} | |
var postUser = function(params, callback) { | |
setTimeout(function() { | |
params.id = userData.length + 1 | |
userData.push(params) | |
callback(null, params) | |
}, 1000) | |
} | |
var Login = { | |
template: '#login', | |
data: function() { | |
return { | |
email: '[email protected]', | |
pass: '', | |
error: false | |
} | |
}, | |
methods: { | |
login: function() { | |
Auth.login(this.email, this.pass, (function(loggedIn) { | |
if(!loggedIn) { | |
this.error = true | |
} else { | |
this.$router.replace(this.$route.query.redirect || '/') | |
} | |
}).bind(this)) | |
} | |
} | |
} | |
var UserList = { | |
template: '#user-list', | |
data: function() { | |
return { | |
loading: false, | |
users: function() { | |
return [] | |
}, | |
error: null | |
} | |
}, | |
created: function() { | |
this.fetchData() | |
}, | |
watch: { | |
'$route': 'fetchData' | |
}, | |
methods: { | |
fetchData: function() { | |
this.loading = true | |
getUsers((function(err, users) { | |
this.loading = false | |
if(err) { | |
this.error = err.toString() | |
} else { | |
this.users = users | |
} | |
}).bind(this)) | |
} | |
} | |
} | |
var UserDetail = { | |
template: '#user-detail', | |
data: function() { | |
return { | |
loading: false, | |
user: null, | |
error: null | |
} | |
}, | |
created: function() { | |
this.fetchData() | |
}, | |
watch: { | |
'$route': 'fetchData' | |
}, | |
methods: { | |
fetchData: function() { | |
this.loading = true | |
getUser(this.$route.params.userId, (function(err, user) { | |
this.loading = false | |
if(err) { | |
this.error = err.toString() | |
} else { | |
this.user = user | |
} | |
}).bind(this)) | |
} | |
} | |
} | |
var UserCreate = { | |
template: '#user-create', | |
data: function() { | |
return { | |
sendding: false, | |
user: this.defaultUser(), | |
error: null | |
} | |
}, | |
created: function() { | |
}, | |
methods: { | |
defaultUser: function() { | |
return { | |
name: '', | |
description: '' | |
} | |
}, | |
createUser: function() { | |
if(this.user.name.trim() === '') { | |
this.error = 'Nameは必須です' | |
return | |
} | |
if(this.user.description.trim() === '') { | |
this.error = 'Descriptionは必須です' | |
return | |
} | |
postUser(this.user, (function(err, user) { | |
this.sending = false | |
if(err) { | |
this.error = err.toString() | |
} else { | |
this.error = null | |
this.user = this.defaultUser() | |
alert('新規ユーザーが登録されました') | |
this.$router.push('/users') | |
} | |
}).bind(this)) | |
} | |
} | |
} | |
var router = new VueRouter({ | |
routes: [ | |
{ | |
path: '/top', | |
component: { | |
template: '<div>トップページです。</div>' | |
} | |
}, | |
{ | |
path: '/users', | |
component: UserList | |
}, | |
{ | |
path: '/users/new', | |
component: UserCreate, | |
beforeEnter: function(to, from, next) { | |
if(!Auth.loggedIn()) { | |
next({ | |
path: '/login', | |
query: { redirect: to.fullPath } | |
}) | |
} else { | |
next() | |
} | |
} | |
}, | |
{ | |
path: '/users/:userId', | |
component: UserDetail | |
}, | |
{ | |
path: '/login', | |
component: Login | |
}, | |
{ | |
path: '/logout', | |
beforeEnter: function(to, from, next) { | |
Auth.logout() | |
next('/top') | |
} | |
}, | |
{ | |
path: '*', | |
redirect: '/top' | |
} | |
] | |
}) | |
var app = new Vue({ | |
data: { | |
Auth: Auth | |
}, | |
router: router | |
}).$mount('#app') | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment