vscode插件
clone 項目
我們這裏不講vue-element-admin,講的是vue-admin-template
配置跨域
跨域配置分爲兩種,一種是cors方式在 vue-config.js 配置 proxy 代理,另外一種是通過 nginx 配置反向代理,這裏我們用第一種,第二種 nginx 我還不會
Proxy
proxy: {
'/api': {
target: process.env.VUE_APP_BASE_API, // 你請求的第三方接口
changeOrigin: true, // 在本地會創建一個虛擬服務端,然後發送請求的數據,並同時接收請求的數據,這樣服務端和服務端進行數據的交互就不會有跨域問題
pathRewrite: {
// 路徑重寫,
'^/api': '' // 替換target中的請求地址
}
}
}
# just a flag
ENV = 'development'
# base api
# VUE_APP_BASE_API = '/dev-api'
VUE_APP_BASE_API = 'http://localhost:8080'
# npm 啓動端口號
port = 9528
# vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable,
# to control whether the babel-plugin-dynamic-import-node plugin is enabled.
# It only does one thing by converting all import() to require().
# This configuration can significantly increase the speed of hot updates,
# when you have a large number of pages.
# Detail: https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/babel-preset-app/index.js
VUE_CLI_BABEL_TRANSPILE_MODULES = true
跨域配置完了
後端接口
我們這裏的後端是java,使用的框架是springboot+springsecurity+jwt+redis
如果你的後臺跟我一樣,繼續往下看,登陸的時候可能會出現一個問題
參考博客: https://blog.csdn.net/qq_42977003/article/details/106016161
前後端分離登陸
因爲之前我寫請求的時候是直接把請求寫在頁面裏面,請求和響應都是在一起,但是 vue-admin-template 對axios做了封裝,例如我們這裏的登陸請求是寫在store裏面的,頁面調store的登陸,store調api的登陸請求,同時還有對請求和響應的攔截
request.js
import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
// create an axios instance
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
// withCredentials: true, // send cookies when cross-domain requests
timeout: 5000 // request timeout
})
// request interceptor
service.interceptors.request.use(
config => {
// do something before request is sent
if (store.getters.token) {
// let each request carry token
// ['X-Token'] is a custom headers key
// please modify it according to the actual situation
// config.headers['X-Token'] = getToken()
config.headers['Authorization'] = 'Bearer ' + getToken()
}
return config
},
error => {
// do something with request error
console.log(error) // for debug
return Promise.reject(error)
}
)
// response interceptor
service.interceptors.response.use(
/**
* If you want to get http information such as headers or status
* Please return response => response
*/
/**
* Determine the request status by custom code
* Here is just an example
* You can also judge the status by HTTP Status Code
*/
response => {
const res = response.data
// if the custom code is not 20000, it is judged as an error.
if (res.code !== 203) {
if (res.code === 202) {
Message({
message: res.message || 'Error',
type: 'error',
duration: 5 * 1000
})
}
if (res.code === 201) {
Message({
message: res.message || 'Error',
type: 'error',
duration: 5 * 1000
})
}
if (res.code === 204) {
Message({
message: res.message || 'Error',
type: 'error',
duration: 5 * 1000
})
}
// 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
if (res.code === 205) {
// to re-login
MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
confirmButtonText: 'Re-Login',
cancelButtonText: 'Cancel',
type: 'warning'
}).then(() => {
store.dispatch('user/resetToken').then(() => {
location.reload()
})
})
}
return Promise.reject(new Error(res.message || 'Error'))
} else {
return res
}
},
error => {
console.log('err' + error) // for debug
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
export default service
api的user.js
stored下的mosdules下的user.js
view下的login下的index.vue
基本上登陸要的東西都準備好了測試看看
看到這張圖,不難發現一套流程雖然執行下來了,但是頁面沒跳轉,又出現10個vue warn,心態炸了,我在網上找原因,沒找到,如果有大佬知道怎麼回事可以在下面評論區說一下!
前後端分離登陸二
之後用了另外一種方式在這裏就要感謝一下知乎的一個作者了
我們修改的是store下的modules下的user.js
import { login } from '@/api/user'
import { getToken, setToken } from '@/utils/auth'
const user = {
state: {
token: getToken(),
name: '',
avatar: ''
},
mutations: {
SET_TOKEN: (state, token) => {
state.token = token
},
SET_NAME: (state, name) => {
state.name = name
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
}
},
actions: {
// 登錄
Login({ commit }, userInfo) {
return new Promise((resolve, reject) => {
login(userInfo)
.then(response => {
console.log('store')
const tokenValue = response.jwtToken
setToken(tokenValue)
commit('SET_TOKEN', tokenValue)
resolve()
})
.catch(error => {
reject(error)
})
})
}
}
}
export default user
views下的login下的index.vue請求
handleLogin() {
const _this = this
_this.$refs.loginForm.validate(valid => {
if (valid) {
_this.loading = true
_this.$store
.dispatch('Login', this.loginForm)
.then(() => {
_this.loading = false
console.log('login')
_this.$router.push({ path: this.redirect || '/' })
})
.catch((msg) => {
_this.loading = false
})
} else {
console.log('error submit!!')
return false
}
})
}
總結
到這我們就告一段落,希望對您有幫助