今天來加強我們昨天的頁面,讓他更生動且可以對API操作。我已經建好簡陋API用來開發前端,之後會再統一結構發出來。
首先是我們Store,直接初始化我們會用到的方法,其實主要就是USER DATA以及ERRORS,所以操作也圍繞著他們。
登入成功後,是會將登錄資料存在本地localstorage,就可以保持登入了。
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
user: null,
errors: []
},
mutations: {
// 收到設置User data
SET_USER_DATA (state, userData) {
// 設置state
state.user = userData
// 並設置在localstorage達到自動登入
localStorage.setItem('user', JSON.stringify(userData))
// 設置在每一次axoios的header Authorization 為 Bearer XXXXTOKEN
axios.defaults.headers.common['Authorization'] = `Bearer ${userData.token}`
},
CLEAR_USER_DATA (state) {
// 清除本地端user資料防止loggedIn再讀取到
localStorage.removeItem('user')
// reload這個頁面 重置所有vue檔案
location.reload()
},
SET_ERROR_DATA (state, error) {
// 設置state
state.errors.push({
id: state.errors.length,
content: error
})
setTimeout(() => {
state.errors.reverse()
state.errors.pop()
state.errors.reverse()
}, 2000)
}
},
actions: {
pushError ({ commit }, credentials) {
commit('SET_ERROR_DATA', credentials)
},
// 組建呼叫此register credentials就是我們帶入的data
register ({ commit }, credentials) {
// 回傳axios此一回傳 可用then串起來
return axios.post('//localhost:3000/register', credentials)
},
login ({ commit }, credentials) {
// 回傳axios此一回傳 可用then串起來
return axios.post('//localhost:3000/login', credentials).then(
// 回來的資料就commit到mutations修改state
({ data }) => {
commit('SET_USER_DATA', data)
}
)
},
updateUserInfo ({ commit, state }) {
return axios.post('//localhost:3000/userInfo', state.user).then(
({ data }) => {
commit('SET_USER_DATA', data)
}
)
},
// 登出方法
logout ({ commit }) {
commit('CLEAR_USER_DATA')
}
},
// 創造一個Getter取值
getters: {
loggedIn: state => {
// 判斷是否有user 確定是否為登入狀態
return !!state.user
},
userInfo: state => {
return state.user
}
}
})
我把錯誤訊息提示直接放在APP.vue,並直接讀store內的errors並渲染。有搭配transition-group做到動畫。
APP.vue
...以上省略
<div class="errorBlock"
v-if="true">
<transition-group name="list"
tag="div">
<span v-for="(error, index) in this.$store.state.errors"
:key="index">
{{error.content}}
</span>
</transition-group>
</div>
...以下省略
登入頁面主要就是登錄,判斷是否為空,並把錯誤訊息加入到vuex,並由errorBlock顯示。
export default {
data () {
return {
email: '',
password: ''
}
},
methods: {
login () {
if (!this.email || !this.password) {
this.$store.dispatch('pushError', '欄位不能為空')
} else {
this.$store.dispatch('login', {
email: this.email,
password: this.password
})
.then(() => {
this.$router.push({ name: 'gamelist' })
}, (err) => {
this.$store.dispatch('pushError', err.response.data.error)
})
.catch(err => {
this.$store.dispatch('pushError', err.response.data.error)
})
}
}
}
}
那我們還期待在登錄的時候,只要本地有資料就將使用者資料塞入vuex,這樣即可達成自動登入,且如果有任何401錯誤,就登出把資料清除。
new Vue({
router,
store,
created () {
// 自動登錄 取出localstorage
const userString = localStorage.getItem('user')
// 如果有東西的話
if (userString) {
// 轉成json
const userData = JSON.parse(userString)
// 設置vuex store
this.$store.commit('SET_USER_DATA', userData)
// axios 如果有任何錯誤發生 (更改自己的localstorage導致dashboard等等其他出錯)
// 401是未授權
axios.interceptors.response.use(
response => response,
error => {
// 401就登出
if (error.response.status === 401) {
this.$store.dispatch('logout')
}
return Promise.reject(error)
}
)
}
},
render: h => h(App)
}).$mount('#app')
不得不說今天發文非常的趕,光是寫API就花了一點時間,明天再將API整理並把前端整理好了!