vue-axios-router 基礎寫法用法 齊梟飛前端
阿新 • • 發佈:2019-02-09
router.js
import Vue from 'vue' import VueRouter from 'vue-router' import store from './store/store' import * as types from './store/types' import Index from './index.vue' import Repository from './repository.vue' import Login from './login.vue' Vue.use(VueRouter) const routes = [ { path: '/', name: '/', component: Index }, { path: '/repository', name: 'repository', meta: { requireAuth: true, }, component: Repository }, { path: '/login', name: 'login', component: Login } ]; // 頁面重新整理時,重新賦值token if (window.localStorage.getItem('token')) { store.commit(types.LOGIN, window.localStorage.getItem('token')) } const router = new VueRouter({ routes }); router.beforeEach((to, from, next) => { if (to.matched.some(r => r.meta.requireAuth)) { if (store.state.token) { next(); } else { next({ path: '/login', query: {redirect: to.fullPath} }) } } else { next(); } }) export default router;
多個請求 401 的情況,重定向到登入頁面 query 引數錯誤
http.js
import axios from 'axios' import store from './store/store' import * as types from './store/types' import router from './router' // axios 配置 axios.defaults.timeout = 5000 axios.defaults.baseURL = 'https://api.github.com' // http request 攔截器 axios.interceptors.request.use( config => { if (store.state.token) { config.headers.Authorization = `token ${store.state.token}` } return config }, err => { return Promise.reject(err) }, ) // http response 攔截器 axios.interceptors.response.use( response => { return response }, error => { if (error.response) { switch (error.response.status) { case 401: // 401 清除token資訊並跳轉到登入頁面 store.commit(types.LOGOUT) // 只有在當前路由不是登入頁面才跳轉 router.currentRoute.path !== 'login' && router.replace({ path: 'login', query: { redirect: router.currentRoute.path }, }) } } // console.log(JSON.stringify(error));//console : Error: Request failed with status code 402 return Promise.reject(error.response.data) }, ) export default axios
login.vue
<template> <div class="container"> <form class="login-form" novalidate @submit.stop.prevent="login"> <md-input-container md-has-password> <label>Github Personal Token(Press Enter)</label> <md-input type="password" v-model="token"></md-input> </md-input-container> </form> <md-button href="https://github.com/settings/tokens/new" target="_blank" class="md-raised md-primary">generate your token</md-button> </div> </template> <script type="application/ecmascript"> import * as types from './store/types' export default { name: '', data () { return { msg: '', token: '' } }, mounted(){ this.$store.commit(types.TITLE, 'Login'); }, methods: { login(){ if (this.token) { this.$store.commit(types.LOGIN, this.token) let redirect = decodeURIComponent(this.$route.query.redirect || '/'); this.$router.push({ path: redirect }) } } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style scoped lang='scss' rel="stylesheet/scss" type="text/css"> .login-form{ width: 400px; margin: 50px auto; } </style>
app.vue
<template>
<div id="app">
<md-toolbar class="black">
<div class="container">
<div class="left">
<a href="https://github.com" target="_blank">
<svg aria-hidden="true" class="octicon octicon-mark-github" height="32" version="1.1"
viewBox="0 0 16 16" width="32">
<path fill-rule="evenodd"
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path>
</svg>
</a>
<span class="md-title title">{{title}}</span>
</div>
<div class="right">
<a v-on:click="logout" class=" md-default" v-show="token">logout</a>
</div>
</div>
</md-toolbar>
<router-view>
</router-view>
</div>
</template>
<script>
import * as types from './store/types'
import {mapState} from 'vuex'
export default {
name: 'app',
data () {
return {
msg: 'Welcome to Your Vue.js App',
}
},
computed: mapState({
title: state => state.title,
token: state => state.token
}),
methods: {
logout(){
this.$store.commit(types.LOGOUT)
this.$router.push({
path: '/'
})
}
}
}
</script>
<style lang="scss">
@import "../node_modules/vue-material/dist/vue-material.css";
@import "assets/css.css";
@import "assets/icon.css";
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
.container {
width: 1000px;
margin: 0 auto;
}
.left {
float: left;
text-align: left;
}
.right{
float: right;
}
.md-toolbar .title {
vertical-align: text-top;
margin-left: 5px;
}
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
store.js
import Vuex from 'vuex'
import Vue from 'vue'
import * as types from './types'
Vue.use(Vuex);
export default new Vuex.Store({
state: {
user: {},
token: null,
title: ''
},
mutations: {
[types.LOGIN]: (state, data) => {
localStorage.token = data;
state.token = data;
},
[types.LOGOUT]: (state) => {
localStorage.removeItem('token');
state.token = null
},
[types.TITLE]: (state, data) => {
state.title = data;
}
}
})
type.js
export const LOGIN = 'login';
export const LOGOUT = 'logout';
export const TITLE = 'title'