Node.jsãVue.jsãMongoDBã䜿çšããŠBudget Manager Webã¢ããªã±ãŒã·ã§ã³ãäœæããããã®äžé£ã®è³æã®2çªç®ã®éšåã次ã«ç€ºããŸãã
æåã®éšåã§ã¯ããµãŒããŒãæ±ããŸãããã€ãŸããRESTful APIã®äž»èŠãªã¡ãœãããæºåããJWTèªèšŒã確ç«ããŸããã ä»æ¥ã¯ãã¢ããªã±ãŒã·ã§ã³ã®ã¯ã©ã€ã¢ã³ãéšåã§äœæ¥ãéå§ããããã³ããšã³ããã¬ãŒã ã¯ãŒã¯ãã·ã¹ãã ã«ç»é²ããã³ã·ã¹ãã ãå
¥åããããã®ããŒã«ãäœæããã«ãŒããšãã®ä¿è·ã«ã€ããŠèª¬æããŸãã
Vue.jsãã€ã³ã¹ããŒã«ããvue-cliã䜿çšããŸã
Vue.jsã®ã€ã³ã¹ããŒã«ã¯éåžžã«ç°¡åã§ãã
webpack
ãã³ãã¬ãŒãã§
vue-cli
ã䜿çšããäºå®ã§ãã Vueããã¥ã¢ã«ãåç
§ãããšã
vue-cli
ã€ã³ã¹ããŒã«ãšäœæ¥ç°å¢ã®æºåã«
vue-cli
ã䜿çšãããŠ
vue-cli
ããšãããããŸãã
# vue-cli $ npm install --global vue-cli # $ vue init webpack my-project # $ cd my-project $ npm install $ npm run dev
ã«ãŒããã£ã¬ã¯ããªã«
application
ãã©ã«ããŒãäœæããŠããããžã§ã¯ãã®äœæ¥ãç¶ããŸãã
vue-cli
äžã«ãã©ã«ããŒãäœæããããšã«ããããã®ã¹ããããã¹ãããã§ããŸãã ãã©ã«ããŒãäœæããªãããšã«ããå Žåã¯ããã®çš®é¡ã®ã³ãã³ããå®è¡ããŠãããžã§ã¯ãã«ååãä»ããå¿
èŠããããŸãã
vue init webpack name-of-your-project
application
ãã©ã«ããŒãäœæããåŸã®ãããžã§ã¯ãã¯æ¬¡ã®ããã«ãªããŸãã
ã³ãã³ãã©ã€ã³ã€ã³ã¿ãŒããªã¿ãŒã䜿çšããŠæ°ããäœæãããã©ã«ããŒã«ç§»åãã
vue-cli
ããŸã ã€ã³ã¹ããŒã«ãããŠããªãå Žåã¯ã次ã®ã³ãã³ããå®è¡ããŸãã
npm i
ãã®ã³ãã³ãã䜿çšãããšã
vue-cli
ã°ããŒãã«ã«ã€ã³ã¹ããŒã«ã§ãããããå®è¡ããããšã§ã©ã®ãã©ã«ããŒã«å
¥ããã¯é¢ä¿ãããŸããã
次ã®ã³ãã³ããåŒã³åºããŸãã
vue init webpack
ã³ãã³ãã¯
application
ããã¹ãããããã«ãã§ã«äœæããã
application
ãã©ã«ããŒã§å®è¡ãããããšãç解ãããããããããžã§ã¯ãåã¯ããã«ç€ºãããŠããªãããšã«æ³šæããŠãã ããã
äžèšã®ã³ãã³ããå®è¡ããŠãã³ãã¬ãŒããããŠã³ããŒããããšãäžé£ã®è³ªåã衚瀺ãããŸãã
å¿
èŠã«å¿ããŠããã®æ®µéã§ãããžã§ã¯ãã®ååã説æãäœæè
ã«é¢ããæ
å ±ãå€æŽã§ããŸãã ãã®è³æããéžè±ããªãããã«ãå³ã«ç€ºãããã«ä»ã®ãã¹ãŠãæ®ããŸãã
次ã«ã
application
ãã©ã«ããŒã«æ®ã£ããŸãŸãäŸåé¢ä¿ãã€ã³ã¹ããŒã«ããŠãããžã§ã¯ããéå§ããŸãã
npm i npm run dev
ããã§ãæšæºã®VueããŒãžãéè³ã§ããŸãã
Vueã¢ããªã±ãŒã·ã§ã³ãã¯ãªãŒã³ã¢ãããã
äžèŠãªæšæºèŠçŽ ãã¢ããªã±ãŒã·ã§ã³ããåé€ããŸãã ãããè¡ãã«ã¯ã
application/src/assets
ãã©ã«ããŒã«ç§»åããŠããã®ãã¡ã€ã«ã䜿çšããªãããã
logo.png
ãåé€ããŸãã 次ã«ã
application/src
ãã©ã«ããŒãã
App.vue
ã®ã«ãŒãã³ã³ããŒãã³ãã®ãã¡ã€ã«ãéãã次ã®ã³ãŒããã©ã°ã¡ã³ãã§è¡šããã圢åŒã«ããŸãã
<template> <div id="app"> <v-container> <router-view/> </v-container> </div> </template> <script> export default { name: 'app' } </script>
次ã«ãã«ãŒããã¯ãªã¢ããå¿
èŠããããŸãã ãããè¡ãã«ã¯ã
router
ãã©ã«ããŒã®
index.js
ãã¡ã€ã«ãéãã次ã®ãã©ãŒã ã«ç§»åããŸãã
import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) export default new Router({ routes: [ {} ] })
ã«ãŒããæ§é åããæ¹æ³ã¯å€æ°ãããŸããããããžã§ã¯ããè€éã«ããªãããã«ãã³ã³ããŒãã³ããã€ã³ããŒãããŠãã®ãã¡ã€ã«ã«ã«ãŒããèšå®ããã ãã§ãã
ããã§ãæšæºã¢ããªã±ãŒã·ã§ã³ã®ã¯ãªãŒãã³ã°ã®æåŸã®æ®µéã§ã
components
ãã©ã«ããŒãã
HelloWorld.vue
ãã¡ã€ã«ãåé€ããŸãã
äŸåé¢ä¿ã®ã€ã³ã¹ããŒã«
ã¢ããªã±ãŒã·ã§ã³ã®ããã³ããšã³ãã®éçºãéå§ããåã«ãããã«ããã€ãã®äŸåé¢ä¿ãã€ã³ã¹ããŒã«ããå¿
èŠããããŸãã 次ã®ã³ãã³ããå®è¡ããåã«ã
application
ãã©ã«ããŒã«ããããšã確èªããŸãã
npm i
次ã«ãéçºäŸåé¢ä¿ãã€ã³ã¹ããŒã«ããŸãã
npm i
axios
ã䜿çšããŠHTTPãªã¯ãšã¹ããåŠçããŸãã
vuetify
ãèŠèŠçãªã³ã³ããŒãã³ããšãã¡ãã·ã¥ããŒã¹ã®ã¬ã€ã¢ãŠãã䜿çšããæ©èœã«é¢å¿ããããŸãã
vue-cookie
ãæäœããã«ã¯ã
vue-cookie
ã©ã€ãã©ãªã䜿çšããŸãã
sass-loader
ããã³
node-sass
ã䜿çšãããšãSCSSã䜿çšã§ã
node-sass
ã
ã¢ããªã±ãŒã·ã§ã³ã®ããã³ããšã³ãã§éå§ãã
ãã¹ãŠã®æºå掻åãå®äºããã®ã§ãéçºãå§ããŸãã
components
ãã©ã«ããŒã«ç§»åããŠããã®äžã«
pages
ãã©ã«ããŒãäœæããŸããããã«
Authentication
ãã©ã«ããŒãäœæããŸãã ãã®ãã©ã«ããŒã«ãèªèšŒã«äœ¿çšããã³ã³ããŒãã³ããè¡šã
Authentication.vue
ãã¡ã€ã«ãäœæããå¿
èŠããããŸãã æçµçã«ã¯æ¬¡ã®ããã«ãªããŸãã
Authentication.vue
ãã¡ã€ã«ã«ã次ã®ã³ãŒããé
眮ããŸãã
<template> <h1>Auth!</h1> </template> <script> export default {} </script>
ãã®ã³ã³ããŒãã³ãã®æ¡åŒµã«ã€ããŠã¯åŸã»ã©èª¬æããŸãããããã§ã¯
router
ãã©ã«ããŒã«ç§»åããŠã«ãŒããæäœããŸãã
ãŸãã
Authentication
ã³ã³ããŒãã³ããã€ã³ããŒããããã®äœ¿çšã®ããã«ã«ãŒããæ§æããŸãã
import Vue from 'vue' import Router from 'vue-router' // Pages import Authentication from '@/components/pages/Authentication/Authentication' Vue.use(Router) export default new Router({ routes: [ { path: '/login', name: 'Authentication', component: Authentication } ] })
ãã®åŸãã¢ãã¬ã¹
httpïŒ// localhostïŒ8080 /ïŒ/ loginã«ã¢ã¯ã»ã¹ãããšããAuthïŒããšããç¢æã®ãã空çœããŒãžã衚瀺ãããŸãã ããã¯ãèªèšŒã«ãŒããæ©èœããŠããããšã瀺ããŠããŸãã
src
ãã©ã«ããŒãã
main.js
ãã¡ã€ã«ãéãã
main.js
ãš
vue-cookie
ãã€ã³ããŒãããŸãã
import VueCookie from 'vue-cookie' import Vuetify from 'vuetify' import('../node_modules/vuetify/dist/vuetify.min.css') Vue.use(VueCookie) Vue.use(Vuetify) Vue.config.productionTip = false
src
ãã©ã«ããŒãã
App.vue
ã³ã³ããŒãã³ãã«
App.vue
ã
App.vue
ãŸãããã ãŸãã
style
ã¿ã°ãæºåããå¿
èŠããããŸãã
script
ã¿ã°ãéããçŽåŸã«é
眮ã
script
ã
<style lang="scss"> </style>
src/assets
ãã©ã«ããŒã«ç§»åãã
styles.scss
ãã¡ã€ã«ãšãã®äžã®
styles.scss
ãã©ã«ããŒãäœæããŸãã ãã®ãã©ã«ããŒã§ã
_variables.scss
ããã³
_animations.scss
è¡šããã2ã€ã®éšåçãªãã³ãã¬ãŒããäœæã
_animations.scss
ã çµæã¯æ¬¡ã®æ§é ã«ãªããŸãã
_variables.scss
ãã¡ã€ã«ã§ã次ã®ãã©ã¡ãŒã¿ãŒãèšå®ããŸãã
// Colors $background-tint:
_animations.css
ãã¡ã€ã«ã§ã
bounceIn
ããã³
slideInFromLeft
説æãè¿œå ããŸãã
@keyframes bounceIn { to { animation-timing-function: cubic-bezier(.215, .61, .355, 1) } 0% { opacity: 0; transform: scale3d(.3, .3, .3) } 20% { transform: scale3d(1.1, 1.1, 1.1) } 40% { transform: scale3d(.9, .9, .9) } 60% { opacity: 1; transform: scale3d(1.03, 1.03, 1.03) } 80% { transform: scale3d(.97, .97, .97) } to { opacity: 1; transform: scaleX(1) } } @keyframes slideInFromLeft { from { transform: translateX(-2500px); opacity: 0 } 50% { transform: translateX(0); opacity: 1; } 70% { transform: translateX(-20px); } 90% { transform: translateX(10px); } to { transform: translateX(0); } }
éšåçãªãã¿ãŒã³ã
styles.scss
ã€ã³ããŒãã
styles.scss
ã
@import "./partials/variables"; @import "./partials/animations";
次ã«ã
assets
ãã©ã«ããŒã§ã
images
ãã©ã«ããŒãäœæããŸãã ããã«ãèæ¯ãšããŠäœ¿çšãããç»åãé
眮ã§ããŸãã
ããã§ã¯ããªããžããªã§ããã®è³æã§äœ¿çšãããŠããã€ã¡ãŒãžãèŠã€ããããšãã§ããŸãã
ã¢ããªã±ãŒã·ã§ã³ã®å€èŠ³ãã«ã¹ã¿ãã€ãºããŠã
App.vue
ãã¡ã€ã«ã®
App.vue
ãããã¯ã次ã®ãã¥ãŒã«ç§»åããŸãã
<style lang="scss"> @import "./assets/styles"; body { background: url('./assets/images/background.jpg') no-repeat center center fixed; &:after { content: ''; position: fixed; width: 100%; height: 100%; top: 0; left: 0; background-color: $background-tint; opacity: .3; z-index: -1; } } </style>
ããã§ã¯ãäºåã«æºåãããscssã¹ã¿ã€ã«ãã€ã³ããŒãããã¢ããªã±ãŒã·ã§ã³ã®åºå®èæ¯ç»åã®äœ¿çšãèšå®ããŸãã ã©ã®ããã€ã¹ã§ããã¢ããªã±ãŒã·ã§ã³ç»é¢ãã»ãŒåãã«ãªãããã«åªããŠããŸãã
body :after
æ¬äŒŒèŠçŽ ã®
body :after
ã«ã
$background-tint
å€æ°ã®å€ãæžã蟌ãããšã§
background-color
ãã©ã¡ãŒã¿ãŒãèšå®ããŸãã ããã«ãããããŒã³ã¿ã«ã©ãŒãã£ã«ã¿ãŒãèæ¯ç»åã«é©çšãããŸãã èæ¯ç»åã®ããŸããŸãªããªãšãŒã·ã§ã³ã®å€èŠ³ã次ã«ç€ºããŸãã
ã¹ã¿ã€ãªã³ã°ãšèæ¯ã®æäœã«é¢é£ãããã¹ãŠãã¢ããªã±ãŒã·ã§ã³ã®æ©èœã«åœ±é¿ãäžããããšã¯ãããŸããããããã£ãŠããããã®æé ãã¹ãããããããå¿
èŠã«å¿ããŠã¢ããªã±ãŒã·ã§ã³ãè£
食ãããã§ããŸãã
衚瀺é åã®ã¹ã±ãŒãªã³ã°ãšã¢ã€ã³ã³ã®èªã¿èŸŒã¿
ãã®æé ã«ãããã¢ãã€ã«ããã€ã¹ã§ã¢ããªã±ãŒã·ã§ã³ãæ£ãã衚瀺ãããããã«ãªããŸãã ããã«ãäœæ¥ã®ãã®æ®µéã§ããããªã¢ã«ãã¶ã€ã³ã®ã¹ã¿ã€ã«ã§ã¢ã€ã³ã³ãã¢ããããŒãããŸãã ããããã¹ãŠå®è¡ããã«ã¯ã
application
ãã©ã«ããŒã«ãã
index.html
ãã¡ã€ã«ã«ç§»åãã次ã®å
容ã
head
ã¿ã°ã«è¿œå ããŸãã
<meta name="viewport" content="initial-scale=1"> <link href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' rel="stylesheet">
èªèšŒã³ã³ããŒãã³ãã®éçº
å°ãªããšãéå±ãªãã¯ã€ãããŒãžãåãé€ããã¢ããªã±ãŒã·ã§ã³ãå°ãè£
食ããã®ã§ã
Authentication
ã³ã³ããŒãã³ãã®äœæ¥ãç¶ããŸãã
Authentication
ãã©ã«ããŒã«
index.js
ãã¡ã€ã«ãäœæããŸãã
å¿
èŠãªãã®ãã€ã³ããŒãããAPIãžã®ãã¹ãèšè¿°ããå®æ°ã宣èšããŸãã
import Axios from 'axios' import router from '@/router' const BudgetManagerAPI = `http://${window.location.hostname}:3001`
次ã«ãå¿
èŠãªã¡ãœãããå«ã
Authentication
ãªããžã§ã¯ããäœæããŸãã
export default { user: { authenticated: false } }
ãŠãŒã¶ãŒãèªèšŒãããŠãããã©ããã«é¢ããæ
å ±ãä¿åãã
user
ãšãããªããžã§ã¯ãã宣èšããããšã§ããã®ã³ã³ããŒãã³ãã®äœæ¥ãéå§ããŸãã
ããã§ã¯ãã¡ãœãããæžããŸãããã
import Axios from 'axios' import router from '@/router' const BudgetManagerAPI = `http://${window.location.hostname}:3001` export default { user: { authenticated: false }, authenticate (context, credentials, redirect) { Axios.post(`${BudgetManagerAPI}/api/v1/auth`, credentials) .then(({data: {token}}) => { context.$cookie.set('token', token, '1D') context.validLogin = true this.user.authenticated = true if (redirect) router.push(redirect) }).catch(({response: {data}}) => { context.snackbar = true context.message = data.message }) }, signup (context, credentials, redirect) { Axios.post(`${BudgetManagerAPI}/api/v1/signup`, credentials) .then(({data: {token}}) => { context.$cookie.set('token', token, '1D') context.validSignUp = true this.user.authenticated = true if (redirect) router.push(redirect) }).catch(({response: {data}}) => { context.snackbar = true context.message = data.message }) }, checkAuthentication () { const token = document.cookie if (token) this.user.authenticated = true else this.user.authenticated = false }, getAuthenticationHeader (context) { return `Bearer ${context.$cookie.get('token')}` } }
æåã®æ¹æ³ã¯3ã€ã®åŒæ°ã䜿çšããŸãã
context
ïŒããã¯Vueã®ã³ã³ããŒãã³ãã§ãã
credentials
ïŒããã¯ãŠãŒã¶ãŒåïŒ username
ïŒãšãã¹ã¯ãŒãïŒ password
ïŒã§ãã
redirect
ïŒããã«ãŠãŒã¶ãŒããªãã€ã¬ã¯ãããæ¹æ³ããããŸãã
ããã§Axiosã䜿çšããŠã
credentials
åŒæ°ãæž¡ãããšã«ããAPIãžã®POSTãªã¯ãšã¹ããå®è¡ããŸãã 次ã«ã
token
å€ã®ã¿ã«é¢å¿ããããããå¿ç
data
ãç Žæ£ãããã®å€ãCookieã«ä¿åãããã®ããŒã¿ã®æå¹æéã1æ¥ã«èšå®ããŸãã ãŸãã
validLogin
å€æ°ãš
user
ãªããžã§ã¯ãã®
authenticated
å€ã
true
ã«èšå®ããæåŸã«
redirect
åŒæ°ãããã¹ã«æ²¿ã£ãŠãŠãŒã¶ãŒã
redirect
ãŸãã
ãã以å€ã®å Žåã¯ã
snackbar
ãªããžã§ã¯ãã®
snackbar
ãã£ãŒã«ãã
true
ã«èšå®ããã¡ãã»ãŒãžã«ãšã©ãŒã¡ãã»ãŒãžãæžã蟌ã¿ãŸãã
2çªç®ã®æ¹æ³ã¯æåã®æ¹æ³ãšéåžžã«ãã䌌ãŠãããæ°ããã¢ã«ãŠã³ããäœæããããã«äœ¿çšããŸãã ãã®ã¡ãœãããšæåã®ã¡ãœããã®éãã¯ã䜿çšãããšã³ããã€ã³ãã«ãããŸãã
3çªç®ã®æ¹æ³ã¯ããŠãŒã¶ãŒãèªèšŒãããŠãããã©ããã確èªããããã«äœ¿çšãããŸãã
æåŸã®ã¡ãœããã§ã¯ã
Authorization
ããããŒãè¿ãããšãã§ããŸãã
ããã§ã
Authentication.vue
ãã¡ã€ã«ãéããŠã³ã³ããŒãã³ãã®äœæ¥ãç¶ããŸãã ããã§ã¯ãVuetifyããŒã«ã䜿çšããŸãã
<template> <div class="l-auth-container"> <div class="l-auth"> <v-form v-model="validLogin"> <v-text-field label="Username" v-model="credentials.username" prepend-icon="account_box" :rules="rules" required color="light-blue lighten-1"> </v-text-field> <v-text-field label="Password" v-model="credentials.password" prepend-icon="lock" :rules="rules" :append-icon="loginPasswordVisible ? 'visibility' : 'visibility_off'" :append-icon-cb="() => (loginPasswordVisible = !loginPasswordVisible)" :type="loginPasswordVisible ? 'text' : 'password'" color="light-blue lighten-1" required> </v-text-field> <v-btn flat color="light-blue lighten-1" @click.native="signUpVisible = true">Create account</v-btn> <v-btn color="light-blue lighten-1" @click.native="submitAuthentication()">Login</v-btn> </v-form> </div> <div class="l-signup" v-if="signUpVisible"> <v-form v-model="validSignUp"> <v-text-field label="Username" v-model="newUser.username" prepend-icon="account_box" :rules="rules" required color="light-blue lighten-1"> </v-text-field> <v-text-field label="Password" v-model="newUser.password" prepend-icon="lock" :rules="rules" :append-icon="signUpPasswordVisible ? 'visibility' : 'visibility_off'" :append-icon-cb="() => (signUpPasswordVisible = !signUpPasswordVisible)" :type="signUpPasswordVisible ? 'text' : 'password'" color="light-blue lighten-1" required> </v-text-field> <v-btn block color="light-blue lighten-1" @click.native="submitSignUp()">Sign Up</v-btn> </v-form> </div> <v-snackbar timeout="6000" bottom="bottom" color="red lighten-1" v-model="snackbar"> {{ message }} </v-snackbar> </div> </template>
l-auth-container
ãšããŠæ©èœããã¯ã©ã¹
l-auth-container
æã€
div
èŠçŽ ããããŸãã 次ã«ã
l-auth
ã¯ã©ã¹ãæã€å¥ã®
div
ããããŸããããã«ã¯ãå
¥åãã©ãŒã ãæŽçããããã®èŠçŽ ã®æ§é ãå«ãŸããŠããŸããç¹ã«ã
validLogin
å€æ°ã®ããŒã¿ã«ãã€ã³ãããã
v-form
èŠçŽ ã§ãã
å
éšã«ã¯ã
credentials
ããã®ããŒã¿ã«é¢é£ä»ãããã1察ã®çœ²åããã
v-text-field
å
¥åãã£ãŒã«ãããã
credentials
ïŒãã®ããŒã¿ã«ã€ããŠã¯åŸè¿°ããŸãïŒã ãã£ãŒã«ãã«ã¯
https://material.io/icons/ããååŸããã¢ã€ã³ã³ãæäŸãããå
¥åããã§ãã¯ããã«ãŒã«ããããŸãïŒåãã«ãŒã«ããããåãã«ãŒã«ãããããããžã§ã¯ããè€éã«ããŸããïŒãããã«ããããã®ãã£ãŒã«ãã¯äž¡æ¹ãšããã€ã³ãã£ã³ã°ã
2çªç®ã®å
¥åãã£ãŒã«ãã¯ãã¹ã¯ãŒãçšã§ãå
¥åãããŠãããã¹ã¯ãŒãããŠãŒã¶ãŒãèŠãããšãã§ãããã©ããã瀺ãã¢ã€ã³ã³ãæäŸãããŸãã ãã®ã¢ã€ã³ã³ã«ã¯ã³ãŒã«ããã¯ããããŸããããã¯ã
loginPasswordVisible
å€æ°ã®å€ã
true
ãã
false
ããŸãã¯ãã®éã«åãæ¿ããããšãã§ããç¢å°é¢æ°ã§ãã ãã®å€æ°ã
true
ã«èšå®ãããŠãã
true
ãå
¥åãã£ãŒã«ãã®
type
ãã©ã¡ãŒã¿ãŒã¯
text
ã«èšå®ãããããã§ãªãå Žåã¯
password
ã
æåŸã«ãæ°ããã¢ã«ãŠã³ããäœæããããã·ã¹ãã ã«å
¥ãããã®ãã©ãŒã ãéä¿¡ãããããããã«äœ¿çšãããã¿ã³ã®èª¬æããããŸãã
次ã®ã³ãŒãã¯ãã·ã¹ãã ã®ç»é²ãã©ãŒã ã®æ§é ã瀺ããŠããŸããããã¯ãå€æ°
signUpVisible
true
èšå®ãããŠããå Žåã«ã®ã¿è¡šç€ºãã
true
ã ãã®ãã©ãŒã ã®ããã€ã¹ã¯ããã°ã€ã³ãã©ãŒã ã®ããã€ã¹ã«äŒŒãŠããŸãããããã§ã¯æ°è¡ã®ã¿ãå€æŽãããŠããŸãã ç¹ã«ãããã§ã¯
loginPasswordVisible
ããã³ãã¿ã³ã¯ãªãã¯ãåŠçããå¥ã®ã¡ãœããã®ä»£ããã«å€æ°
signUpPasswordVisible
ã䜿çšãããŸãã
ããã«ãããã«
v-snackbar
ããããèªèšŒäžã«ã¡ãã»ãŒãžã衚瀺ããããã«äœ¿çšãããŸãã
次ã«ãåã
Authentication.vue
ãã¡ã€ã«ã§ãã³ã³ããŒãã³ãã¹ã¯ãªããã«ã€ããŠèª¬æããŸãã
<script> import Authentication from '@/components/pages/Authentication' export default { data () { return { snackbar: false, validLogin: false, validSignUp: false, signUpVisible: false, loginPasswordVisible: false, signUpPasswordVisible: false, rules: [ (value) => !!value || 'This field is required' ], credentials: { username: '', password: '' }, newUser: { username: '', password: '' }, message: '' } }, methods: { submitAuthentication () { Authentication.authenticate(this, this.credentials, '/') }, submitSignUp () { Authentication.signup(this, this.newUser, '/') } } } </script>
ãã®ãã¡ã€ã«å
ã§å®çŸ©ããã
authenticate
ã¡ãœãããå¿
èŠãªããããã¹ãŠã¯
Authentication
ãã©ã«ããŒãã
index.js
ãã¡ã€ã«ãã€ã³ããŒãããããšããå§ãŸããŸãã
次ã«ãã³ã³ããŒãã³ãããŒã¿ãæ ŒçŽããå€æ°ãèŠãŠã¿ãŸãããã
snackbar
ïŒã¡ãã»ãŒãžããŒã«äœ¿çšãããŸãã
validLogin
ïŒãã°ã€ã³ãã©ãŒã ã®æ€èšŒã«äœ¿çšãããŸãã
validSignUp
ïŒç»é²ãã©ãŒã ã®æ€èšŒã«äœ¿çšãããŸãã
signUpVisible
ïŒç»é²ãã©ãŒã ã®è¡šç€ºã«äœ¿çšãããŸãïŒ true
èšå®ãããŠããtrue
ïŒã
loginPasswordVisible
ïŒãŠãŒã¶ãŒããã°ã€ã³ãã©ãŒã ã«å
¥åããããã¹ã¯ãŒãã衚瀺ã§ãããã©ããã瀺ããŸãã
signUpPasswordVisible
ïŒç»é²ãã©ãŒã ã«å
¥åããããã¹ã¯ãŒãã衚瀺ã§ãããã©ããã瀺ããŸãã
rules
ïŒãã©ãŒã ãã£ãŒã«ãã«å
¥åãããããŒã¿ããã§ãã¯ããããã®ã«ãŒã«ã
credentials
ïŒãŠãŒã¶ãŒã®èªèšŒã«äœ¿çšããããã°ã€ã³ãã©ãŒã ã®ãã°ã€ã³ãã£ãŒã«ãã«ä»å ããããªããžã§ã¯ãã
newUser
ïŒã·ã¹ãã ã®ç»é²ãã©ãŒã ã®å
¥åãã£ãŒã«ãã«é¢é£ä»ãããããªããžã§ã¯ãã
message
ïŒèªèšŒäžã«ã¡ãã»ãŒãžã衚瀺ããããã«äœ¿çšãããŸãã
ãã®ã³ã³ããŒãã³ãã«ã¯ããã€ãã®ã¡ãœããããããŸãã
submitAuthentication
ã¡ãœããã¯ã
authenticate
ãã¡ã€ã«ãã
authenticate
ã¡ãœãããåŒã³åºããã³ã³ããã¹ããè³æ Œæ
å ±ãããã³ãªãã€ã¬ã¯ããã¹ãæž¡ããŸãã
submitSignUp
ã¡ãœãã
submitSignUp
ã
signup
ã¡ãœãããåŒã³åºãããã«äœ¿çšãããŸãã
ãããŠæåŸã«ãåã
Authentication.vue
ãã¡ã€ã«ã«é
眮ããå¿
èŠã®ããã³ã³ããŒãã³ãã¹ã¿ã€ãªã³ã°ã³ãŒãã瀺ããŸãïŒããã§ã¯ã空æ³ãèªç±ã«å€ããŠããããããã®ãèªç±ã«äœæã§ããŸãïŒã
<style lang="scss"> @import "./../../../assets/styles"; .l-auth { background-color: $background-color; padding: 15px; margin: 45px auto; min-width: 272px; max-width: 320px; animation: bounceIn 1s forwards ease; } .l-signup { background-color: $background-color; padding: 15px; margin: 45px auto; min-width: 272px; max-width: 320px; animation: slideInFromLeft 1s forwards ease; } </style>
ãã°ã€ã³ããŠæ°ãããŠãŒã¶ãŒãç»é²ããããã®ã³ã³ããŒãã³ãã次ã«ç€ºããŸãã
ããŒã ã³ã³ããŒãã³ãéçº
pages
ãã©ã«ããŒã«ç§»åããã³ã³ããŒãã³ããã¡ã€ã«
Home.vue
ãäœæããŸãã
çŸæç¹ã§ã¯ããã®ã³ã³ããŒãã³ãã®ãã³ãã¬ãŒãã«ã¯ã³ãŒãã以äžã«ç€ºãããŠããŸãããããã¹ãã¡ãã»ãŒãžã¯ããããããããŸããã
<template> <div> <h3>Hi! this is our App's Home</h3> <ul> <li v-if="users != null" v-for="user in users"> {{ user.username }} </li> </ul> </div> </template> <script> import Axios from 'axios' import Authentication from '@/components/pages/Authentication' const BudgetManagerAPI = `http://${window.location.hostname}:3001` export default { data () { return { users: [] } }, mounted () { this.getAllUsers() }, methods: { getAllUsers (context) { Axios.get(`${BudgetManagerAPI}/api/v1/users`, { headers: { 'Authorization': Authentication.getAuthenticationHeader(this) } }).then(({data}) => (this.users = data)) } } } </script>
ãã®ã³ã³ããŒãã³ãã¯ããã®ã·ãªãŒãºã®æ¬¡ã®ããŒãã§èª¬æããããŒã ããŒãžã®åºç€ã§ãã ãããŸã§ã®éãAPIãžã®GETãªã¯ãšã¹ããå®è¡ããAPIãããã°ã¡ãœããã䜿çšããŠç»é²æžã¿ã®ãã¹ãŠã®ãŠãŒã¶ãŒãååŸãããªã¯ãšã¹ãããããŒã§ããŒã¯ã³ãæž¡ããŸãã ãããã©ã®ããã«èŠãããã§ãïŒ
ããã²ãŒã·ã§ã³ä¿è·
router
ãã©ã«ããŒãã
index.js
ãã¡ã€ã«ãéããŸãã 以äžã«ãã©ã®ãããªãã©ãŒã ãæã¡èŸŒãå¿
èŠããããã瀺ããŸãã
import Vue from 'vue' import Router from 'vue-router' import * as Auth from '@/components/pages/Authentication' // Pages import Home from '@/components/pages/Home' import Authentication from '@/components/pages/Authentication/Authentication' Vue.use(Router) const router = new Router({ routes: [ { path: '/', name: 'Home', component: Home, meta: { requiredAuth: true } }, { path: '/login', name: 'Authentication', component: Authentication } ] }) router.beforeEach((to, from, next) => { if (to.meta.requiredAuth) { if (Auth.default.user.authenticated) { next() } else { router.push('/login') } } else { next() } }) export default router
ãã®ã³ãŒããæ€èšããŠãã ããã
import * as Auth from '@/components/pages/Authentication'
ãã®è¡ã§ã¯ã
Authentication
ã³ã³ããŒãã³ããã€ã³ããŒããããŠããããã
Authentication
ãã¡ã€ã«ãã€ã³ããŒãããŠ
Auth
ãšåŒã³ãŸãã
const router = new Router({ routes: [ { path: '/', name: 'Home', component: Home, meta: { requiredAuth: true } }, { path: '/login', name: 'Authentication', component: Authentication } ] })
ããã§ã¯ãåŸã§ããã²ãŒã·ã§ã³ã·ã¹ãã ã®ä¿è·ãäœæããããã«ã
Router
ãªããžã§ã¯ãã«ååãä»ããŸãã ãŸãã
Home
ã³ã³ããŒãã³ããžã®ãã¹ãè¿œå ããŸãã
meta.requiredAuth
ã¯
true
ã«ãªã
true
ã ããã¯ãèªèšŒãããŠããªããŠãŒã¶ãŒããã®ã³ã³ããŒãã³ãã«ã¢ã¯ã»ã¹ããããšãããšããã°ã€ã³ããŒãžã«ãªãã€ã¬ã¯ããããããšãæå³ããŸãã
router.beforeEach((to, from, next) => { if (to.meta.requiredAuth) { if (Auth.default.user.authenticated) { next() } else { router.push('/login') } } else { next() } })
ããã§ã¯ãããã²ãŒã·ã§ã³ã·ã¹ãã ãä¿è·ããŸãã ã€ãŸããã°ããŒãã«ãŠã©ããããã°ããã¯ãç»é²ã
true
ãããã䜿çšããŠãåã«ãŒããééããåã«
meta.requiredAuth
ãã©ã¡ãŒã¿ãŒã
true
meta.requiredAuth
ãŠãããã©ããã確èªã
true
ã ãã®å Žåã
Authentication
ãããŠãŒã¶ãŒãªããžã§ã¯ãã確èªããŸãã ãŠãŒã¶ãŒãèªèšŒãããªãå Žåããã°ã€ã³ããŒãžã«ãªãã€ã¬ã¯ãããŸãã
export default router
ãã®ã³ãã³ãã¯ãã«ãŒã¿ãŒããšã¯ã¹ããŒãããŸãã
ããã§ã
application
ãã©ã«ããŒã®
main.js
ãã¡ã€ã«ãéããŸãã ããã§ã¯ã
Authentication
ãã¡ã€ã«ãã€ã³ããŒããã
checkAuthentication
ã¡ãœãããåŒã³åºããŸãã
import Vuetify from 'vuetify' import Authentication from '@/components/pages/Authentication' import('../node_modules/vuetify/dist/vuetify.min.css') Vue.use(VueCookie) Vue.use(Vuetify) Vue.config.productionTip = false Authentication.checkAuthentication()
ããããªããã°ããŠãŒã¶ãŒãããŒãžããªããŒããããéããŠããåã³éããšããã°ã€ã³ããŒãžã«ãªãã€ã¬ã¯ããããŸãã
ãŸãšã
ä»æ¥ã¯ãVue.jsã¢ããªã±ãŒã·ã§ã³ã®äœææ¹æ³ãVueã³ã³ããŒãã³ãã®éçºæ¹æ³ãHTTPãªã¯ãšã¹ãã®å®è¡ãã¢ããªã±ãŒã·ã§ã³ã«ãŒãã®ä¿è·ã«ã€ããŠèª¬æããŸããã 次ã®éšåã§ã¯ãHomeã³ã³ããŒãã³ãã®æçµåã«çŠç¹ãåœãŠãã¢ããªã±ãŒã·ã§ã³ã®ã¯ã©ã€ã¢ã³ãéšåãšãµãŒããŒéšåã®éçºãç¶ç¶ããŸãã
芪æãªãèªè
ïŒ Vue.jsã«ç²ŸéããŠããå Žåã¯ãã©ã®ãããžã§ã¯ãã«äœ¿çšããããäœã«æºè¶³ããŠãããã«ã€ããŠæããŠãã ããã