准备
-
vue:前端框架必不可少
-
vue-cli:vue脚手架工具
-
element:基于vue2.0的组件库
-
ECharts:可视化图表库
-
axios:基于promise的HTTP库
-
vue-devtools:chrome浏览器插件,开发调试使用
-
fastmock:接口模拟,生成演示数据
1.1使用vue-cli搭建项目
2.2安装vuex、axios、element
$ npm install axios --save
$ npm install element-ui --save
$ npm install vuex --save
3.3配置element
- main.js添加配置:
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
// element
import ElementUI from "element-ui";
import "element-ui/lib/theme-chalk/index.css";
//sotre
import store from "./store";
Vue.config.productionTip = false
Vue.use(ElementUI);
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>',
render: h => h(App)
})
4.4配置vuex
src文件夹下面新建store文件夹,新建store.js(文件夹及文件名随便起),并添加一个user模块。
index.js
import Vue from 'vue';
import Vuex from 'vuex';
import user from './modules/user/user';
Vue.use(Vuex);
export default new Vuex.Store({
modules: {
user
}
});
user.js
import storage from '@/utils/storage'
const state = {
token: "",
userName: ""
};
const getters = {
get_token(state) {
return state.token || storage.get("token") || null;
}
};
const mutations = {
set_token(state, token) {
state.token = token;
storage.set('token', token);
},
del_token(state) {
state.token = "";
storage.remove("token");
},
set_userName(state, userName) {
state.userName = userName;
}
};
export default {
state,
getters,
mutations
};
上面用到一个localStorage工具类,utils文件夹下创建storage.js。
storage.js
var storage = {
set(key, value) {
localStorage.setItem(key, JSON.stringify(value));
},
get(key) {
return JSON.parse(localStorage.getItem(key));
},
remove(key) {
localStorage.removeItem(key);
}
}
export default storage;
5.5配置axios
src文件夹下面新建一个utils文件夹存放工具类。新建一个http.js封装axios。
http.js
import axios from "axios";
import {
Message
} from "element-ui";
import store from "@/store";
//创建axios
const service = axios.create({
//这里baseURL就是配置的开发环境或是线上环境地址
baseURL: process.env.API_ROOT,
timeout: 20000 //请求超时
});
//request拦截
//请求拦截主要作用是验证请求是否合法,会带有用户token
service.interceptors.request.use(
config => {
let token = store.state.user.token;
if (token) {
config.headers["token"] = token;
}
return config;
},
err => {
console.log(err);
Promise.reject(err);
}
);
//respone拦截
//响应拦截主要是对返回做统一处理
service.interceptors.response.use(
response => {
let res = response.data;
let {
code,
data,
message
} = res;
if (code !== 200) {
Message({
message: message,
type: "error",
duration: 5 * 1000
});
if (code === 403) {
console.log("token过期");
}
return false;
} else {
//这里吧错误响应不再返回到页面,直接统一处理掉,只有正确的返回才会被接收并做下一步处理
return data;
}
},
err => {
//这里处理服务端错误
console.log("err" + err);
Message({
message: err.message,
type: "error",
duration: 5 * 1000
});
return Promise.reject(err);
}
);
export default service;
6.6fast-mock
申请一个fastmock账号
- 新建一个项目,并创建一个接口
/user/login
将fastmock提供的接口根地址放到项目config文件夹下dev.env.js文件中
dev.env.js
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
API_ROOT:'"https://www.fastmock.site/mock/xxx/vue-api"'
})
7.7创建api
src文件夹下创建api文件夹,并添加一个user.js文件。
user.js
import service from "@/utils/http";
export function login({
username,
password
}) {
return service({
url: "/user/login",
method: "post",
data: {
username,
password
}
});
}
8.8接口测试
<template>
<div id="app">
<button @click="userLogin">登陆</button>
</div>
</template>
<script>
import { login } from '@/api/user.js'
export default {
name: 'App',
data() {
return {
loginForm: {
username: "chenjy",
password: 123456
}
}
},
methods:{
async userLogin(){
let res = await login(this.loginForm);
console.log(res);
this.$store.commit("set_token", res.token);
this.$store.commit("set_userName", res.userName);
}
}
}
</script>
<style>
</style>
- 第二次请求可以发现header携带了我们前面手动塞进去的token