目录

1.安装vue-cli

具体步骤参考这一篇博文

2.修改开发环境和线上环境的配置

  1. 修改资源引用的配置路径

    config/index.js
    1
    assetsPublicPath: './'
    
    build/utils.js
    1
    2
    3
    4
    5
    return ExtractTextPlugin.extract({
        use: loaders,
        fallback: 'vue-style-loader',
        publicPath:'../../' //<--注意此处路径
    })
    

    具体原因请参考这里

  2. 解决开发模式下的跨域问题

    config/index.js
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    proxyTable: {
          '/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
    5
    plugins: [
        new webpack.DefinePlugin({
          API_HOST:'"/apitest"' //设置全局变量 注意单双引号
        })
    ]
    
    build/webpack.prod.conf.js
    1
    2
    3
    4
    5
    plugins: [
        new webpack.DefinePlugin({
          API_HOST:'"https://cnodejs.org/api/v1"' //设置线上环境的全局变量
        })
    ]
    
    build/webpack.dev.build.conf.js
    1
    2
    3
    4
    5
    plugins: [
        new webpack.DefinePlugin({
          API_HOST:'"https://cnodejs.org/api/v1"' //设置开发环境的全局变量
        })
    ]
    

    详情请参考这里

  3. 增加开发/测试环境的打包配置

    通常一个项目需要多个环境进行开发测试,开发环境下请求的域名和线上环境请求的域名是不一样的,为方便分别打包线上环境和开发/测试环境,我们需要修改下打包配置。

    很简单,直接复制一份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,兼容低版本浏览器

  1. npm i babel-polyfill --save-dev
  2. 引入 最好在import Vue from 'vue'之前引入
    main.js
    1
    import "babel-polyfill";
    

4.开启gzip

具体请看这一篇博文

5.线上环境使用cdn

具体请看这一篇博文

此外,再新建一份index.dev.html,内容如下:

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>

修改配置文件
build/webpack.dev.build.conf.js
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',
      ...
    }),
build/webpack.dev.conf.js
1
2
3
4
5
6
...
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'index.dev.html',
      inject: true
    }),
build/webpack.prod.conf.js
1
2
3
4
5
6
7
8
9
10
...
  externals: {
    'vue': 'Vue',
    'vuex': 'Vuex',
    'vue-router': 'VueRouter',
    'axios': 'axios'
  },
  plugins: [
      ...
  ]

6.路由按需加载,使用热更新

增加--hot,如下:

package.json
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

  1. 安装vuex
    npm i vuex --save
  2. 构建store目录结构
    src文件夹下,新建一个store文件夹,目录结构如下:
  +-- store
  |   +-- index.js //入口文件
  |   +-- actions.js
  |   +-- getters.js
  |   +-- mutations.js
  |   +-- rootState.js

store/index.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;
store/actions.js
1
2
3
4
5
6
export const recordTop = ({ commit }) => {
  commit({
    type: 'getTop',     //对应mutation.js中的getTop方法
    top: 100
  });
};
store/getters.js
1
export const top = state => state.top;
store/mutations.js
1
2
3
export const getTop = (state, payload) => {
  state.top = payload.top;
}
store/rootState.js
1
2
3
4
const state = {
    top: 0
}
export default state;
3. 引入
main.js
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

  1. 安装axios
    npm i axios --save

  2. 封装http请求
    src文件夹下,新建一个service文件夹,目录结构如下:

  +-- service
  |   +-- http.js
  |   +-- request.js

service/http.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);
          });
      })
  }
  
service/request.js
1
2
3
4
5
6
7
import { Get, Post } from './http'

  //举例
  export function Request() {
      return Post(API_HOST + '/request', {});
  }
  

3. 添加axios拦截器
main.js
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项目,可以直接用这个项目