搭建vue项目的基本架构
目录
1.安装vue-cli
具体步骤参考这一篇博文
2.修改开发环境和线上环境的配置
修改资源引用的配置路径
config/index.js 1
assetsPublicPath: './'
build/utils.js 1
2
3
4
5return ExtractTextPlugin.extract({ use: loaders, fallback: 'vue-style-loader', publicPath:'../../' //<--注意此处路径 })
具体原因请参考这里
解决开发模式下的跨域问题
config/index.js 1
2
3
4
5
6
7
8
9
10proxyTable: { '/apitest': { //跨域接口请求标记 target: 'https://cnodejs.org/api/v1', // 开发环境下需要跨域请求接口的域名 secure: false, // 如果是https接口,需要配置这个参数 changeOrigin: true, // 如果接口跨域,需要进行这个参数配置 pathRewrite: { '^/apitest': '' //把域名换成target,代理域名为空,请注意,pathRewrite下的代理域名一定要设置为空,否则会出现请求接口404的问题 } } }
build/webpack.dev.conf.js 1
2
3
4
5plugins: [ new webpack.DefinePlugin({ API_HOST:'"/apitest"' //设置全局变量 注意单双引号 }) ]
build/webpack.prod.conf.js 1
2
3
4
5plugins: [ new webpack.DefinePlugin({ API_HOST:'"https://cnodejs.org/api/v1"' //设置线上环境的全局变量 }) ]
build/webpack.dev.build.conf.js 1
2
3
4
5plugins: [ new webpack.DefinePlugin({ API_HOST:'"https://cnodejs.org/api/v1"' //设置开发环境的全局变量 }) ]
详情请参考这里增加开发/测试环境的打包配置
通常一个项目需要多个环境进行开发测试,开发环境下请求的域名和线上环境请求的域名是不一样的,为方便分别打包线上环境和开发/测试环境,我们需要修改下打包配置。
很简单,直接复制一份build/build.js文件,重命名为build/build-dev.js,然后修改成如下配置:
build/build-dev.js 1
2
3
4
5
6... process.env.NODE_ENV = 'development' ... const webpackConfig = require('./webpack.dev.build.conf') const spinner = ora('building for development...') ...
修改package.json文件,在scripts脚本内增加
"build-dev": "node build/build-dev.js"
打包时,运行
npm run build-dev
,打包出来的文件是开发模式下;运行npm run build
,打包的则是线上环境的文件。
3.引入babel-polyfill,兼容低版本浏览器
npm i babel-polyfill --save-dev
- 引入
最好在
import Vue from 'vue'
之前引入main.js 1
import "babel-polyfill";
4.开启gzip
具体请看这一篇博文
5.线上环境使用cdn
具体请看这一篇博文
此外,再新建一份index.dev.html
,内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>vue-base</title>
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
修改配置文件
1
2
3
4
5
6
7
8
...
new HtmlWebpackPlugin({
filename: process.env.NODE_ENV === 'production'
? 'index.html'
: config.build.index,
template: 'index.dev.html',
...
}),
1
2
3
4
5
6
...
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.dev.html',
inject: true
}),
1
2
3
4
5
6
7
8
9
10
...
externals: {
'vue': 'Vue',
'vuex': 'Vuex',
'vue-router': 'VueRouter',
'axios': 'axios'
},
plugins: [
...
]
6.路由按需加载,使用热更新
增加--hot
,如下:
1
2
3
4
5
...
"scripts": {
"dev": "webpack-dev-server --inline --progress --hot --config build/webpack.dev.conf.js",
...
},
import
路由的方式改成const HelloWorld = r => require.ensure([], () => r(require('@/components/HelloWorld')), 'HelloWorld')
就可以实现按需加载了
7.引入sass
具体请看这里
8.使用vuex
- 安装vuex
npm i vuex --save
- 构建store目录结构
在src
文件夹下,新建一个store
文件夹,目录结构如下:
+-- store
| +-- index.js //入口文件
| +-- actions.js
| +-- getters.js
| +-- mutations.js
| +-- rootState.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import Vue from 'vue';
import Vuex from 'vuex';
import * as actions from './actions';
import * as mutations from './mutations';
import * as getters from './getters';
import state from './rootState';
if (process.env.NODE_ENV === 'development') {
Vue.use(Vuex)
}
const store = new Vuex.Store({
state,
getters,
actions,
mutations
})
export default store;
1
2
3
4
5
6
export const recordTop = ({ commit }) => {
commit({
type: 'getTop', //对应mutation.js中的getTop方法
top: 100
});
};
1
export const top = state => state.top;
1
2
3
export const getTop = (state, payload) => {
state.top = payload.top;
}
1
2
3
4
const state = {
top: 0
}
export default state;
1
2
3
4
5
6
7
8
9
10
...
import store from './store/index';
...
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
9.使用axios
安装axios
npm i axios --save
封装http请求
在src
文件夹下,新建一个service
文件夹,目录结构如下:
+-- service
| +-- http.js
| +-- request.js
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
import axios from 'axios'
import qs from 'qs'
export function Get(url, data) {
return new Promise((resolve, reject) => {
axios.get(url, {
params: data
}).then((res) => {
if (res) {
if (res.status == 200) {
if (res.data.status == 1) {
resolve(res.data.data);
} else {
reject(res.data.msg);
}
} else {
reject(res);
}
}
}).catch((res) => {
reject(res);
});
});
}
export function Post(url, data) {
return new Promise((resolve, reject) => {
axios.post(url, qs.stringify(data)).then((res) => {
if (res) {
if (res.status == 200) {
if (res.data.status == 1) {
resolve(res.data.data);
}
else {
reject(res.data.msg);
}
} else {
reject(res);
}
}
}).catch((res) => {
reject(res);
});
});
}
export function PostFlie(url, data) {
return new Promise((resolve, reject) => {
//根据data对象生成FormData对象
var temp = new FormData();
for (var t in data) {
temp.append(t, data[t]);
}
axios.post(url, temp).then((res) => {
if (res.status == 200) {
resolve(res.data.data);
} else {
reject(res);
}
}).catch((res) => {
reject(res);
});
})
}
1
2
3
4
5
6
7
import { Get, Post } from './http'
//举例
export function Request() {
return Post(API_HOST + '/request', {});
}
3. 添加axios拦截器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
...
import axios from 'axios'
...
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
总结
+-- store
| +-- index.js
| +-- actions.js
| +-- getters.js
| +-- mutations.js
| +-- rootState.js
+-- service
| +-- http.js
| +-- request.js
+-- router
| +-- index.js
+-- util
| +-- toast.js
+-- views
| +-- page1.vue
+-- components
| +-- toast.vue
+-- assets
| +-- sass
| +-- normalize.scss
| +-- img
以上,一个基本的项目结构就完成了。
日后想要新建一个vue项目,可以直接用这个项目