摘要
随着vue-cli脚手架的升级,vue-cli2.0版本与vue-cli3.0+版本搭建出来的vue项目也有了一些变化,下面是整理的个人从脚手架升级到vue项目创建的一个过程。
- 本项目还会融合
axios
请求封装,可运行实测; - 接口统一管理,以及调用方式使用;
- 环境区分(开发、生产、预生产、测试);
升级vue脚手架
- 全局卸载旧版本脚手架(已升级可忽略)
1
2npm uninstall vue-cli -g 或
yarn remove vue-cli -g - node安装最近的版本(不必是最新),我本机安装版本
v12.16.1
- 安装最新的vue-cli
1
npm install -g @vue/cli
- 查看是否已经安装成功
1
vue --version 或 vue -V //查看版本号
注意:vue-cli2.0升级后(3.0+以上)如果你还需要遗产vue init功能,可以安装一个全局桥,这样你就可以继续运行你的vue-cli2.X版本的项目以及通过之前的vue init webpack '项目名'
来创建项目了,命令行如下:
1 | npm install -g @vue/cli-init |
创建项目
开始创建
vue create '项目名称'
default
是使用默认配置(在这里我们选择Vue 2版本)Manually select features
是自定义配置
这里选择自定义配置,然后回车下一步选择配置(自定义配置),上下箭头选择空格键确认
*
好代表选中,回车键下一步(此处根据自己项目需要可进行选择安装,也可后续自己安装)
是否使用history
模式来创建路由,这里选择否,后期可更改
css预处理这里选择的第一项
您希望Babel, ESLint 配置的存放位置,我们选择在专用的配置文件中1
2In dedicated config files //在专用的配置文件中
In package.json //在package.json
Save this as a preset for future projects?(y/N) (是否保存配置 我们可以选择Y ,保存后下次构建项目的时候就可以直用这次的配置构建项目)项目创建好后
1
2cd '项目目录' //进入项目根目录
npm run serve //运行项目然后在浏览器输入
http://localhost:8080
,就可以看到运行界面了项目修改
环境配置
根目录创建环境配置文件以及
vue.config.js
配置文件1
vue-cli-service build --mode production //--mode后面跟的是创建的配置文件的名字
.env.development文件
1
2
3
4
5# just a flag 开发环境(默认)
ENV = 'development'
# base api
VUE_APP_BASE_API = '/dev-api'.env.production文件
1
2
3
4
5# just a flag 线上环境(打包)
ENV = 'production'
# base api
VUE_APP_BASE_API = '/prod-api'vue.config.js文件,改配置文件中的代理配置是为后面本地测试接口时使用,不然会跨域
配置详情可参考vue-cli1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25// Vue.config.js
module.exports = {
publicPath: '/', //基本路径
outputDir: 'dist', //构建时的输出目录
assetsDir: 'static', //放置静态资源的目录
indexPath: 'index.html', //html的输出路径
productionSourceMap: false, // 生产环境是否生成 sourceMap 文件
devServer: {
open: true,
proxy: {
'/dev-api': {
target: 'http://api.yckindergarten.com.cn',//设置你调用的接口域名和端口号 别忘了加http
changeOrigin: true,
pathRewrite:{
'^/dev-api':''//这里理解成用‘/api’代替target里面的地址,后面组件中我们掉接口时直接用api代替
//比如我要调用'http://40.00.100.133:3002/user/login',直接写‘/api/user/login’即可
}
}
// '/foo': {
// target: '<other_url>'
// }
//...
}
}
}axios封装配置
安装
axios
、element-ui
输入命令npm install --save element-ui
引入项目打开main.js
文件1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18import Vue from 'vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
Vue.use(ElementUI)
console.log(process.env.VUE_APP_BASE_API)//测试可查看输出当前环境
new Vue({
router,//路由
store,//状态管理
render: h => h(App)
}).$mount('#app')安装
axios
、qs
命令行输入命令npm install --save axios qs
在src文件夹下新建http目录,并在http目录下创建三个文件
config.js独立的数据请求配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22// 接口配置文件
export default {
//请求方式
method: 'post',
// 基础url前缀
baseURL: process.env.VUE_APP_BASE_API,//取环境文件中定义的地址
// 请求头信息
headers: {
'Content-Type': 'application/json;charset=UTF-8',
'Content-Type': 'application/x-www-form-urlencoded',
'Appid': '123456',
'Token': ''
},
// 参数
data: {},
// 设置超时时间
timeout: 10000,
// 携带凭证
withCredentials: false,
// 返回数据类型
responseType: 'json'
}instance.js请求axios封装、拦截、处理文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156// axios 封装、拦截、统一请求处理
import axios from 'axios' //安装后引入
import config from './config.js' //引入配置文件
import qs from 'qs' //序列化数据请求
export default function $axios(options) {
return new Promise((resolve, reject) => {
const instance = axios.create({
baseURL: config.baseURL,
headers: {},
transformResponse: [function (data) { }]
})
// request 拦截器
instance.interceptors.request.use(
config => {
// Tip: 1
// 请求开始的时候可以结合 vuex 开启全屏的 loading 动画
// Tip: 2
// 带上 token , 可以结合 vuex 或者重 localStorage
// if (store.getters.token) {
// config.headers['X-Token'] = getToken() // 让每个请求携带token--['X-Token']为自定义key 请根据实际情况自行修改
// } else {
// // 重定向到登录页面
// }
// Tip: 3
// 根据请求方法,序列化传来的参数,根据后端需求是否序列化
if (config.method.toLocaleLowerCase() === 'post'
|| config.method.toLocaleLowerCase() === 'put'
|| config.method.toLocaleLowerCase() === 'delete') {
config.data = qs.stringify(config.data)
}
// console.log(config.data);
return config
},
error => {
// 请求错误时做些事(接口错误、超时等)
// Tip: 4
// 关闭loadding
console.log('request:', error)
// 1.判断请求超时
if (error.code === 'ECONNABORTED' && error.message.indexOf('timeout') !== -1) {
console.log('根据你设置的timeout/真的请求超时 判断请求现在超时了,你可以在这里加入超时的处理方案')
// return service.request(originalRequest);//例如再重复请求一次
}
// 2.需要重定向到错误页面
const errorInfo = error.response
console.log(errorInfo)
if (errorInfo) {
// error =errorInfo.data//页面那边catch的时候就能拿到详细的错误信息,看最下边的Promise.reject
const errorStatus = errorInfo.status; // 404 403 500 ... 等
// router.push({
// path: `/error/${errorStatus}`
// })
}
return Promise.reject(error) // 在调用的那边可以拿到(catch)你想返回的错误信息
}
)
// response 拦截器
instance.interceptors.response.use(
response => {
let data;
// IE9时response.data是undefined,因此需要使用response.request.responseText(Stringify后的字符串)
if (response.data == undefined) {
data = response.request.responseText
} else {
data = response.data
}
// console.log(response);
// 根据返回的code值来做不同的处理(和后端约定)
switch (data.code) {
case '':
break;
default:
}
// 若不是正确的返回code,且已经登录,就抛出错误
// const err = new Error(data.description)
// err.data = data
// err.response = response
// throw err
return data
},
err => {
if (err && err.response) {
switch (err.response.status) {
case 400:
err.message = '请求错误'
break
case 401:
err.message = '未授权,请登录'
break
case 403:
err.message = '拒绝访问'
break
case 404:
err.message = `请求地址出错: ${err.response.config.url}`
break
case 408:
err.message = '请求超时'
break
case 500:
err.message = '服务器内部错误'
break
case 501:
err.message = '服务未实现'
break
case 502:
err.message = '网关错误'
break
case 503:
err.message = '服务不可用'
break
case 504:
err.message = '网关超时'
break
case 505:
err.message = 'HTTP版本不受支持'
break
default:
}
}
console.error(err)
// 此处我使用的是 element UI 的提示组件
// Message.error(`ERROR: ${err}`);
return Promise.reject(err) // 返回接口返回的错误信息
}
)
//请求处理
instance(options)
.then((res) => {
resolve(res)
return false
})
.catch((error) => {
reject(error)
})
// 处理结束
})
}api.js接口公共管理文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17// api接口统一管理
import axios from './instance'
// 将所有的接口统一起来便于维护
// 空气质量接口
export const airQuality = (data) => {
return axios({
url: '/util/getAirData',
method: 'POST',
data,
// handle:true
})
}
// 默认全部导出
// export default {
// airQuality
// }使用,可以在main.js中直接导入,使用时,this.$api.airQuality()
1
2import api from './http/api.js' //引入接口文件
Vue.prototype.$api = api; //挂载调用
1
2
3
4
5this.$api.airQuality(data).then((res)=>{
console.log(JSON.stringify(res));
}).catch((err)=>{
console.log(err);
});此方式使用时,项目运行是会一次性加载api文件中的所有接口
方式二,使用时引入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27<template>
</template>
<script>
import { airQuality } from "@/http/api.js"; //引入使用的接口
export default {
data() {
return {
};
},
created() {
this.airQuality(); //调用接口
},
methods: {
airQuality() {
var data = {};
airQuality(data).then((res) => {
console.log(JSON.stringify(res));
});
}
},
};
</script>
<style scoped>
</style>结束:至此项目成功配置完毕,执行启动命令,打包命令测试环境输出对应,运行成功,其中如有错误还望大家多多指出,谢谢!
github项目地址github项目地址
vue-cli2.0与vue3.0+创建出的项目具体有什么不一样,本篇中暂未详细说明