vue-cli4.0搭建vue项目
张渊 Lv2

摘要

随着vue-cli脚手架的升级,vue-cli2.0版本与vue-cli3.0+版本搭建出来的vue项目也有了一些变化,下面是整理的个人从脚手架升级到vue项目创建的一个过程。

  • 本项目还会融合axios请求封装,可运行实测;
  • 接口统一管理,以及调用方式使用;
  • 环境区分(开发、生产、预生产、测试);

    升级vue脚手架

  • 全局卸载旧版本脚手架(已升级可忽略)
    1
    2
    npm 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 是自定义配置
    这里选择自定义配置,然后回车下一步
    image

  • 选择配置(自定义配置),上下箭头选择空格键确认*好代表选中,回车键下一步(此处根据自己项目需要可进行选择安装,也可后续自己安装)
    image
    是否使用history模式来创建路由,这里选择否,后期可更改
    image
    css预处理这里选择的第一项
    image
    您希望Babel, ESLint 配置的存放位置,我们选择在专用的配置文件中

    1
    2
    In dedicated config files //在专用的配置文件中
    In package.json //在package.json

    image
    Save this as a preset for future projects?(y/N) (是否保存配置 我们可以选择Y ,保存后下次构建项目的时候就可以直用这次的配置构建项目)
    image

  • 项目创建好后

     
    1
    2
    cd '项目目录' //进入项目根目录
    npm run serve //运行项目

    image

  • 然后在浏览器输入http://localhost:8080,就可以看到运行界面了

    项目修改

    环境配置

  • 根目录创建环境配置文件以及vue.config.js配置文件
    image

    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-cli

    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
    // 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封装配置

  • 安装axioselement-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
    18
    import 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')
  • 安装 axiosqs 命令行输入命令 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
    2
    import api from './http/api.js' //引入接口文件
    Vue.prototype.$api = api; //挂载

    调用

    1
    2
    3
    4
    5
    this.$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+创建出的项目具体有什么不一样,本篇中暂未详细说明

 评论
评论插件加载失败
正在加载评论插件
由 Hexo 驱动 & 主题 Keep
本站由 提供部署服务
总字数 12.9k 访客数 访问量