提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔
文章目錄
- 1.分析登錄流程
- 1.1傳統思路是登錄校驗通過之后,直接調用接口,獲取token之后,跳轉到主頁
- 1.2vue-element-admin模板的登錄思路:
- 2. Vuex中用戶模塊的實現
- 2.1代碼位置src/store/modules/user.js
- 2.1.1導出Vuex子模塊-聲明一個狀態token
- 2.1.2實現token的Vue數據持久化
- 2.1.3實現登錄的action方法
- 2.1.4在登錄組件中調用該action方法 代碼位置 src/views/login/index.vue
- 2.1.5注意:因為user模塊導出的時候namespaced為true,所以我們調用action的時候要加上模塊名稱如user/login
- 3.Vue-cli代理解決跨域
- 3.1請求模塊-axios封裝-跨域-區分環境
- 3.2跨域問題解決才能考慮其他內容的開發
- 3.2.1為什么會有跨域
- 3.2.2直接使用前端向后端發請求(后端沒有開啟cors)
- 3.2.1.1瀏覽器的同源策略會直接限制后端返回的數據給到前端。因為項目是前后端分離的,前端一個服務,后端一個服務,后端不開cors只能前端另想辦法了。
- 3.2.2代理是怎么解決跨域的?
- 前端不能直接請求后端服務,中間服務剛好和我們的前端服務同源,前端和中間服務可以通信,而中間服務是node,node后臺向后端發請求是不受同源策略影響的,因為同源策略只針對瀏覽器!!!,這樣就解決了問題,將前端的請求代理給了后端接口。
- 具體怎么做?
- 跨域有開發環境跨域和生產環境跨域,我們最后上線的時候要考慮生產環境跨域,目前只需要考慮開發環境。
- 配置文件可以直接配置代理 vue.config.js
- 注意:要去掉before這個選項,這個是mock數據,會影響到我們的請求,并且修改完成之后要重啟服務。
- 4.axios封裝
- 5.環境區分
- Vue代碼中NODE_ENV之外,所有的變量必須以VUE_APP_開頭
- 6.登錄聯調
- 目前登錄功能只剩下紅色的部分
- 首先封裝登錄的API請求-代碼位置(src/api/user.js)
- Vuex中的用戶模塊調用登錄接口(src/store/modules/user.js)
- 登錄成功后,跳轉到主頁(scr/views/login/index.vue)
- 區分不同環境的數據-代碼位置(src/views/login/index.vue)
- 開發環境為了便利,將用戶的賬戶信息和密碼都默認寫在了頁面上,但是真正的項目我們需要把手機號和密碼抹去
- 7.主頁權限驗證-鑒權
- 當前項目用戶是否有權限訪問主頁,要考慮當前有沒有token, 如果有token, 用戶還想去登錄頁,我們可以直接去主頁-這個就是免登錄功能。有token的情況下,直接到主頁。
- 訪問主頁-有token放過,沒有token跳到登錄頁
- 訪問登錄-有token跳到主頁,沒有token放過
- src/pemission.js
1.分析登錄流程
1.1傳統思路是登錄校驗通過之后,直接調用接口,獲取token之后,跳轉到主頁
1.2vue-element-admin模板的登錄思路:
- 首先校驗登錄表單通過
- 調用Vuex提供的登錄的action
- 登錄的Action中去調用接口
- 登錄接口如果成功執行,會返回token
- 利用Vuex的特性,將token共享的到Vuex中,這樣Vuex就統一管理了token,別的地方想要使用,直接通過Vuex就可以
- 登錄接口會調用單獨封裝的請求模塊(api)
- 請求模塊中又會使用到axios封裝的請求工具
- 而請求工具又要考慮區分 開發環境和生產環境的問題
- 請求時還要考慮前后分離項目產生的跨域問題,要使用代理解決跨域
2. Vuex中用戶模塊的實現
2.1代碼位置src/store/modules/user.js
2.1.1導出Vuex子模塊-聲明一個狀態token
const state = {token:null
}
const mutations = {};
const actions = {};
export default{namespaced:true,state,mutations,actions
}
2.1.2實現token的Vue數據持久化
import {getToken,setToken,removeToken } from '@/utils/auth'
const state = {token:getToken(),//從緩存中讀取初始值
}
const mutations = {setToken(state,token){state.token = token//同步到緩存setToken(token) },removeToken(state){//刪除Vuex的tokenstate.token = null;removeToken() }
}
export default{namespaced:true,//開啟命名空間state,mutations,actions
}
2.1.3實現登錄的action方法
const actions = {//context上下文,傳入參數async login(context,data){console.log(data)//todo:調用登錄接口const token = await login(data);//返回一個token context.commit('setToken',token) }
}
2.1.4在登錄組件中調用該action方法 代碼位置 src/views/login/index.vue
export default{methods:{login(){this.$refs.form.validate((isok)=>{if(isok){this.$store.dispatch("user/login",this.loginForm)} }) } }
}
2.1.5注意:因為user模塊導出的時候namespaced為true,所以我們調用action的時候要加上模塊名稱如user/login
3.Vue-cli代理解決跨域
3.1請求模塊-axios封裝-跨域-區分環境
3.2跨域問題解決才能考慮其他內容的開發
3.2.1為什么會有跨域
3.2.2直接使用前端向后端發請求(后端沒有開啟cors)
3.2.1.1瀏覽器的同源策略會直接限制后端返回的數據給到前端。因為項目是前后端分離的,前端一個服務,后端一個服務,后端不開cors只能前端另想辦法了。
3.2.2代理是怎么解決跨域的?
前端不能直接請求后端服務,中間服務剛好和我們的前端服務同源,前端和中間服務可以通信,而中間服務是node,node后臺向后端發請求是不受同源策略影響的,因為同源策略只針對瀏覽器!!!,這樣就解決了問題,將前端的請求代理給了后端接口。
具體怎么做?
跨域有開發環境跨域和生產環境跨域,我們最后上線的時候要考慮生產環境跨域,目前只需要考慮開發環境。
配置文件可以直接配置代理 vue.config.js
devServer:{port:port,open:true,overlay:{warnings:false,errors:true },proxy:{'/api':{target:'https://' } }
}
注意:要去掉before這個選項,這個是mock數據,會影響到我們的請求,并且修改完成之后要重啟服務。
4.axios封裝
-
完成了代理跨域,就可以考慮axios的封裝了
-
axios封裝主要封裝做哪些
-
基礎地址,超時時間
-
請求攔截器-統一注入token
-
響應攔截器-解構數據-處理異常
-
axios的基礎功能
-
位置 src/utils/request.js
import axios from 'axios'
import store from '@/store'
const service = axios.create({baseURL:'/api',timeout:1000,
})
service.interceptors.request.use((config)=>{//注入token//this.$store.getters//store.getters.token =>請求頭里面if(store.getters.token){config.headers.Authorization = `Bearer ${store.getters.token}`}return config
},(error)=>{//失敗執行promisereturn Promise.reject(error)
})
//響應攔截器
service.interceptors.response.use((response)=>{const {data,message,success} = response.data;//默認json格式if(success){return data}else{Message({type:'error',message})return Promise.reject(new Error(message))}
},async(error)=>{Message({type:'error',message:error.message})return Promise.reject(error)
})
export default service
5.環境區分
Vue代碼中NODE_ENV之外,所有的變量必須以VUE_APP_開頭
6.登錄聯調
目前登錄功能只剩下紅色的部分
首先封裝登錄的API請求-代碼位置(src/api/user.js)
import request from '@/utils/request'
export function login(data){return request({url:'/sys/login',method:'post',data})
}
Vuex中的用戶模塊調用登錄接口(src/store/modules/user.js)
const actions = {//context上下文,傳入參數async login(context,data){console.log(data);const token = await login(data)//返回一個token context.commit('setToken',token)}
}
登錄成功后,跳轉到主頁(scr/views/login/index.vue)
methods:{login(){this.$refs.form.validate((isok)=>{if(isok){await this.$store.dispatch('user/login',this.loginForm)//Vuex中的action 返回的promise//跳轉主頁this.$router.push('/')}})}
}
區分不同環境的數據-代碼位置(src/views/login/index.vue)
開發環境為了便利,將用戶的賬戶信息和密碼都默認寫在了頁面上,但是真正的項目我們需要把手機號和密碼抹去
export default{name:'Login',data(){return{loginForm:{mobile:process.env.NODE_ENV === 'development'? '13800000002':'',password:process.env.NODE_ENV === 'development'?'123456':'',isAgree:process.env. NODE_ENV === 'development'}} }
}
7.主頁權限驗證-鑒權
當前項目用戶是否有權限訪問主頁,要考慮當前有沒有token, 如果有token, 用戶還想去登錄頁,我們可以直接去主頁-這個就是免登錄功能。有token的情況下,直接到主頁。
訪問主頁-有token放過,沒有token跳到登錄頁
訪問登錄-有token跳到主頁,沒有token放過
src/pemission.js
import router from '@/router'
import nprogress from 'nprogress'
import 'nprogress/nprogress.css'
import store from '@/store'
//前置守衛
const whiteList = ['/login','/404']
router.beforeEach(async(to,from,next)=>{nprogress.start()if(store.getters.token){//存在tokenif(to.path === '/login'){//跳轉到主頁next('/');//并沒有執行后置守衛nprogress.done()}else{next()//放行}}else{//沒有tokenif(whiteList.includes(to.path)){next()}else{next('/login')//中轉到登錄頁 nprogress.done() }}
})
//后置守衛
router.afterEach(()=>{nprogress.done()
})