1.背景
1.对应很多入门前端来说,进入到一个公司一般来说都只是负责项目的某一个模块,很少有机会轮到自己从0到1去搭建一个项目。一般都是项目组长负责创建好项目,对页面的基本结构做好架构,做对应的跨域处理,token管理,路由拦截,API封装,打包优化这些。我们只是简单的调接口,写一些业务性的代码,这不利于我们提高自己的技术。
2.创建项目
1.在一个空的文件夹中打开终端,运行命令:
vue create demo(demo为项目名)
2.安装elelment ui:
npm i element-ui -S
3.配置按需引入:
npm i babel-plugin-component -D
/*如项目有需要,怎可以安装echarts*/
npm i echarts --save
4.配置babel.config.js:
module.exports = {
presets:[
'@vue/cli-plugin-balbel/preset'
],
"pluguns":[
[
"component",
{
"libraryName":"element-ui",
"styleLibraryName":"theme-chalk"
}
]
]
}
5.main.js按需引入组件,并注册。
6.安装axios
npm i axios --save
3.配置代理处理跨域请求
1.在vue.config.js文件中进行相关配置,这是vue官方推荐的一个文件命名方式,当服务起来的时候会自动找这个文件,找到了之后会自动解析读取里面相关的配置。
module.exports = {
//关闭eslint
lintOnSave: false,
// 处理vue服务相关选项
devServer: {
// 项目运行起来后自动打开浏览器
opne: true,
// 配置代理
proxy: {
// 知识一个标识
'api': {
// target就是需要代理的服务器地址
target: 'http://www.chenji.store',
// ws => websocket (即时通讯,游戏)
// 相当于在前后端之间开启了一个通道 数据会实时在通道内进行传输
// 配置支持跨域
changeOrigin: true,
// 重写 防止原有的接口路径上也有一个api路径,导致有两个api
pathRewrite: {
'/api':'/'
}
}
},
// 配置全局sass
css:{
// 加载器
loaderOptions:{
sass: {
prependData:`@import "./src/common/css/global"`
}
}
},
// vue的打包优化
}
}
4.封装API
1.不建议把axios挂载带vue的原型上,因为每次new一个vue都会带上这个属性。
2.创建request文件夹,新建service.js文件:
// 引入axios,直接和后台接口打交道,统一处理所有接口(加token)
import axios from 'axios'
import vue from '../main.js'
function getTokenByLocal() {
let token = sessionStorage.getItem('token');
// 不使用cookie 1.cookie存的值大小有限定(几K) 2.cookie在服务端不安全,容易被攻击
const service = axios.create({
// 这里的/api和vue.config.js中的target中的服务器地址是一一对应的
baseURL: '/api',
// 请求超时时间
timeout: 5000
})
// 请求拦截
service.interceptors.request.use(
config => {
if(getTokenByLocal()) {
service.headers['token'] = getTokenByLocal()
// 使用cookie现在新版的谷歌浏览器会报错
// service.headers['cookie'] = 'xxx'
} else {
vue.$router.push('/login')
}
return config
},
error => {
return Promise.reject(error)
}
)
// 响应拦截
service.interceptors.response.use(
response => {
let res = response.data
// 要根据后端定义的code值做相应操作
if(res.code == 400) {
vue.$router.push('/login')
}
return Promise.resolve(res)
},
error => {
return Promise.reject(error)
}
)
}
// 默认导出service
export default service
3.在request文件夹下新建comon.js文件,处理get、post封装请求:
import servie from './service.js'
import service from './service.js'
// 耦合度低 => 复用性高
// 封装post请求
export function requestOfPost(url, data) {
return servie.post(url, data)
}
// 封装get请求
export function requestOfGet(url, data) {
return service.post(url, data)
}
// 添加其他类似请求
4.在request文件夹下新建url.js,用于集中管理api:
// 管理所有的接口url 如果项目中的接口较多,为了方便管理,也可以分模块分成多个urlXXX.js:
const url = {
// 例如登录注册相关
login: 'fengmang/login',
register:'fengmang/register',
getCode:'fengmang/getCode',
findPassword:'fengmang/findPassword'
}
export default url
5.在request文件夹中新建api.js文件,直接和api、业务打交道:
//直接与api打交道
import { requestOfPost, requestOfGet } from './common.js'
export function postRequest(url, data) {
return new Promose(
(resolve, reject) => {
requestOfPost(url, data).then(res => {
resolve(res)
}).catch(
error => {
reject(error)
})
})
}
export function getRequest(url, data) {
return new Promose(
(resolve, reject) => {
requestOfGet(url, data).then(res => {
resolve(res)
}).catch(
error => {
reject(error)
})
})
}
6.调用api,以登录为例:
<script>
import { postRequest } from "../request/api.js";
import url from "../request/url.js";
export default {
data() {
return {
account: "",
password: ""
};
},
methods: {
login() {
let data = {
account: this.account,
password: this.password
};
if (!this.account && !this.password) {
postRequest(url.login, data).then(res => {
if (res.code == 200) {
console.log(res);
sessionStorage.setItem('token',res.data.token)
setTimeout(() => {
this.$router.push('/home')
})
}
});
}
}
}
};
</script>