本文所用vue-cli是3.0版本的,所以首先需要创建一个vue.config.js文件,然后配置axios,就可以请求接口获取数据了。
一 简单实现前端调用后端接口:
1.main.js文件中:
import axios from 'axios'
Vue.prototype.$axios = axios
axios.defaults.baseURL = '请求地址';//后端开发环境地址
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';//配置请求头信息。
//axios.defaults.headers.common['accessToken'] = 'FA4C308D5E8F6409E01344ADDAEB4C71';
2.vue.config.js文件完整代码
module.exports = {
/* 部署生产环境和开发环境下的URL:可对当前环境进行区分,baseUrl 从 Vue CLI 3.3 起已弃用,要使用publicPath */
/* baseUrl: process.env.NODE_ENV === 'production' ? './' : '/' */
publicPath: process.env.NODE_ENV === 'production' ? '/public/' : './',
/* 输出文件目录:在npm run build时,生成文件的目录名称 */
outputDir: 'dist',
/* 放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录 */
assetsDir: "assets",
/* 是否在构建生产包时生成 sourceMap 文件,false将提高构建速度 */
productionSourceMap: false,
/* 默认情况下,生成的静态资源在它们的文件名中包含了 hash 以便更好的控制缓存,你可以通过将这个选项设为 false 来关闭文件名哈希。(false的时候就是让原来的文件名不改变) */
filenameHashing: false,
/* 代码保存时进行eslint检测 */
lintOnSave: true,
/* webpack-dev-server 相关配置 */
devServer: {
/* 自动打开浏览器 */
open: false,
/* 设置为0.0.0.0则所有的地址均能访问 */
host: '0.0.0.0',
port: 9528,
https: false,
hotOnly: false,
/* 使用代理 */
proxy: {
'/api': {
target: '请求地址',
secure: false, // 如果是https接口,需要配置这个参数
ws: true,//是否代理websockets
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
},
}
3.在login.vue中使用
this.$axios({
method: "post",
url: "/user/login",
contentType: "application/json;chart=utf-8",
dataType: "json",
data,
}).then((res) => {
if (res.data.status === "1") {
this.$Message.info("登录成功!");
this.logining = false;
window.sessionStorage.setItem("userSession", res.data.data.id);
window.sessionStorage.setItem("userName", res.data.data.userName);
this.$router.push({ path: "/open/default" });
} else {
this.$Message.info("登录失败!");
this.logining = false;
this.modelLogin.password = "";
}
});
以上 即可实现前端调用后端接口。
二 实现拦截器和路由登录拦截功能
以下为进阶版,将所有的接口调用放在一个user.js文件中(该文件处于http文件夹下)以后其他接口均可放在里面:
import axios from '../interceptors.js'
// 登录
export const login = (data) => {
return axios({
url: '/user/login',
method: 'post',
data
})
}
// 查看用户有没有登录
export const getSession = (data) => {
return axios({
url: '/user/getSession',
method: 'post',
data
})
}
Vue+axios(interceptors) 实现http拦截 + router路由拦截 (双拦截)!!!(论文中可写,可见https://www.jianshu.com/p/115b4c79a75d)
首先建文件夹http 文件夹下简历一个文件interceptors.js:
/*拦截器*/
import axios from 'axios'
import Vue from 'vue'
import {
Message,
LoadingBar
} from 'view-design'
Vue.prototype.HOST = '/api'
// Vue.prototype.$http = axios
Vue.prototype.$axios = axios
axios.defaults.baseURL = 'http://localhost:8080/c';//后端开发环境地址
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';//配置请求头信息
// 超时时间
axios.defaults.timeout = 12000
// http请求拦截器
axios.interceptors.request.use(config => {
LoadingBar.start();
return config
}, error => {
LoadingBar.error();
Message.error({
message: '加载超时'
})
return Promise.reject(error)
})
// http响应拦截器
axios.interceptors.response.use(data => { // 响应成功关闭loading
LoadingBar.finish();
return data
}, error => {
LoadingBar.error();
Message.error({
message: '加载失败'
})
return Promise.reject(error)
})
export default axios
main.js文件不需要再引入axios了。(以上初级版是在main.js中引入的)
在需要使用接口的vue文件中如此用:
import { login } from '../http/api/user'
login()
{
const { userName, password } = this.modelLogin;
if (!userName) {
this.$Message.info("用户名不能为空");
return;
}
if (!password) {
this.$Message.info("密码不能为空");
return;
}
this.clearLocalStorage();
this.logining = true;
let data = {
userName: this.modelLogin.userName,
password: this.modelLogin.password,
};
login(data).then(res => {
if (res.data.status === "1") {
this.$Message.info("登录成功!");
this.logining = false;
window.localStorage.setItem("userSession", res.data.data.id);
window.localStorage.setItem("userName", res.data.data.userName);
this.$router.push({ path: "/open/default" });
} else {
this.$Message.info("登录失败!");
this.logining = false;
this.modelLogin.password = "";
}
})
.catch(() => {
this.logining = false;
})
}
登录路由拦截功能(某些页面需登录才可以看):
router文件夹下的index.js文件中:
import Vue from 'vue'
import Router from 'vue-router'
import Home from '../components/Home.vue'
import Login from '../components/Login.vue'
Vue.use(Router)
const router = new Router({
routes: [{
path: '/',
meta: {
requireAuth: false, // 添加该字段,为true表示进入这个路由是需要登录的
},
component: Home,
redirect: '/open/default'
},
{
path: '/open/default', //到时候地址栏会显示的路径
meta: {
requireAuth: true, // 添加该字段,为true表示进入这个路由是需要登录的
},
name: 'Home',
component: Home // Home是组件的名字,这个路由对应跳转到的组件。。注意component没有加“s”.
},
{
path: '/open/Login',
meta: {
requireAuth: false,
},
name: 'Login',
component: Login
}
],
mode: "hash"
})
router.beforeEach((to, from, next) => {
if (to.meta.requireAuth) { // 判断是否需要登录权限
if (localStorage.getItem('userSession')) { // 判断是否登录
next()
} else { // 没登录则跳转到登录界面
next({
path: '/open/Login',
query: {
redirect: to.fullPath
}
})
}
} else {
next()
}
})
export default router
以上即可实现路由登录检查;
三 解决 Vue 重复点击相同路由,出现 Uncaught (in promise) NavigationDuplicated: Avoided redundant navigation 问题
只需要在以上router文件夹的index.js中增加:
const VueRouterPush = Router.prototype.push
Router.prototype.push = function push (to) {
return VueRouterPush.call(this, to).catch(err => err)
}