美文网首页vue
【进化指南】从vue-cli2到vue-cli3

【进化指南】从vue-cli2到vue-cli3

作者: oo高学吟 | 来源:发表于2018-11-12 16:06 被阅读3185次

    CLI 2和CLI 3第一个区别是npm包的包名,CLI 3并没有沿用CLI 2的vue-cli,而是另起为@vue/cli。创建项目方面也发生了变化,CLI 2 可以选择根据模板初始化项目,而CLI 3并未重新开发模板,如果开发者想要像CLI 2一样使用模板初始化项目,可全局安装一个桥接工具@vue/cli-init。


    安装 vue-cli3

    如果已经安装过vue-cli2,按以下指令卸载:

     npm uninstall vue-cli -g
    

    安装vue-cli3:

    npm install -g @vue/cli
    

    Vue CLI 3 和旧版使用了相同的 vue 命令,所以 Vue CLI 2 (vue-cli) 被覆盖了。如果你仍然需要使用旧版本的 vue init 功能,你可以全局安装一个桥接工具:

    npm install -g @vue/cli
    

    你可以使用 vue serve 和 vue build 命令对单个 *.vue 文件进行快速原型开发,不过这需要先额外安装一个全局的扩展:

    npm install -g @vue/cli-service-global
    

    创建 vue项目

    vue create hello-world
    

    创建时建议选择手动去勾选配置,带*建议勾选:

    1. (*)Babel (转换es6)
    2. (*)router (路由)
    3. (*)vuex
    4. (*)less
    5. linter / formatter (一个语法规则和代码风格的检查工具,可以检测出你代码中潜在的问题,可以保证写出语法正确和风格统一的代码),lint有两种检查时机,一是用户保存文件的时候,二是用户提交文件到git的时候。选择Lint on save。
      1. ESLint with error prevention only —— 只检测错误。
      2. ESLint + Airbnb config —— 几乎涵盖了JavaScript的各个方面。
      3. ESLint + Standard config —— 自带linter和自动代码纠正,自动格式化代码。
      4. ESLint + Prettier —— 统一整个团队的代码风格。
    6. 把Babel、ESLint等配置信息全放在package.json文件里呢,还是单独文件管理? => 单独管理。

    ++这样创建出来的项目结构里,比起cli2,少了build和config文件,更为简洁易懂。++


    载入插件

    • 使用图形化界面

      在你安装好了CLI 3的前提下,执行 vue ui 命令 ,会自动在浏览器打开图形界面。

      先导入项目,再搜索要装的插件,直接安装即可,安装好的插件,在\src\plugins目录下统一管理,在 main.js 中只需要引入 plugins文件即可。

    • 按需引入

      借助插件 babel-plugin-import可以实现按需加载组件,减少文件体积。首先安装,并在文件 .babelrc 中配置:

      ps: 这里以iview为例子~

      npm install iview --save
      npm install babel-plugin-import --save-dev
      
      // .babelrc
      {
        "plugins": [
            ["import", {
              "libraryName": "iview",
              "libraryDirectory": "src/components"
            }]
        ]
      }
      // 找不到 .babelrc,在babel.config.js中配置
      module.exports = {
        plugins: [
          ['import', {
            libraryName: 'iview',
            libraryDirectory: 'src/components'
          }]
        ]
      };
      
      //main.js
      import 'iview/dist/styles/iview.css';
      
      // 再按需引入
      import { Button, Table } from 'iview';
      Vue.component('Button', Button);
      Vue.component('Table', Table);
      

    环境变量配置

    npm run serve => process.env.NODE_ENV = 'development'

    npm run build => process.env.NODE_ENV = 'production'

    1. package.json中
    "scripts": {
        "serve": "vue-cli-service serve",
        "test": "vue-cli-service build --mode test",
        "production": "vue-cli-service build --mode production",
        "build": "vue-cli-service build"
    }
    
    1. 根目录下新建文件.env.==test== 内容:
    NODE_ENV = 'test'
    
    1. src/utils下新建一个文件setBaseUrl.js
    let baseUrl = "";   //这里是一个默认的url,可以没有
    switch (process.env.NODE_ENV) { 
                            => 根据NODE_ENV来判断当前环境
        case 'test':
            baseUrl = "https://test-tobet.io"  //测试服务器的请求url
            break
        case 'production':
            baseUrl = "https://tobet.io"   //生产环境url
            break
        default:
            baseUrl = '/api'   //'/api'为vue.config.js配置
    }
    
    export default baseUrl;
    
    1. main.js中
    import axios from 'axios';
    import baseUrl from '@/utils/setBaseUrl'
    axios.defaults.baseURL = baseUrl;
    
    1. 配置本地请求地址

      在根目录下新建vue.config.js(会自动记载)

    module.exports = {
      baseUrl: process.env.NODE_ENV === 'production' ? '/' : '/',
    
      devServer: {
        proxy: {
            将 setBaseUrl.js 里的 baseUrl 匹配过来
                || 
            '/api': {
                target: 'http://192.168.0.88:8080',   // 需要请求的地址
                changeOrigin: true,  // 是否跨域
                pathRewrite: {
                    '^/api': '/'  // 替换target中的请求地址,也就是说,在请求的时候,
                                  // url用'/proxy'代替'http://ip.taobao.com'
                }
            }
        },  // 配置多个代理
      }
    };
    

    vue+Axios 使用拦截器

    Axios是基于Promise机制实现的异步的链式请求框架。当短时间内重复发起同一个请求时,例如搜索推荐列表,需要将上一个请求直接取消掉再发起下一个请求,一来可以减少网络请求的消耗,二来防止上一个请求的返回过慢而覆盖了应有的返回结果。这里我们就可以使用拦截器。

    Axios的配置文件中如下:

    import Vue from 'vue'
    import axios from 'axios';
    import urlParams from '../utils/setBaseUrl' //不同环境的请求地址配置
    
    const constant = {};
    constant.env = process.env;
    constant.url = urlParams;
    
    axios.defaults.baseURL = urlParams.baseUrl;
    axios.defaults.withCredentials = true;
    axios.defaults.timeout = 30000;
    
    
    let pending = []; //声明一个数组用于存储每个ajax请求的取消函数和ajax标识
    let cancelToken = axios.CancelToken;
    let removePending = (ever) => {
        for(let p in pending){
            if(pending[p].u === ever.url + '&' + ever.method) { //当当前请求在数组中存在时执行函数体
                pending[p].f(); //执行取消操作
                pending.splice(p, 1); //把这条记录从数组中移除
            }
        }
    }
    
    //http request 拦截器
    axios.interceptors.request.use(
        config => {
          config.data = JSON.stringify(config.data);
          config.headers = {
            'Content-Type':'application/json' //application/x-www-form-urlencoded
          }
          // ------------------------------------------------------------------------------------
          removePending(config); //在一个ajax发送前执行一下取消操作
          config.cancelToken = new cancelToken((c)=>{
             // 这里的ajax标识我是用请求地址&请求方式拼接的字符串,当然你可以选择其他的一些方式
             pending.push({ u: config.url + '&' + config.method, f: c });  
          });
          // -----------------------------------------------------------------------------------------
          return config;
        },
        error => {
          return Promise.reject(error);
        }
    );
    
    //http response 拦截器
    axios.interceptors.response.use(
        response => {
          // console.log(response);
          // ------------------------------------------------------------------------------------------
          removePending(response.config);  //在一个ajax响应后再执行一下取消操作,把已经完成的请求从pending中移除
          // -------------------------------------------------------------------------------------------
          if(response.data.errCode ==2){
            router.push({
              path:"/login",
              querry:{redirect:router.currentRoute.fullPath}//从哪个页面跳转
            })
          }
          return response;
        },
        error => {
          return Promise.reject(error)
        }
    )
    
    Vue.prototype.$axios = axios;
    

    动态图片加载

    动态图片加载不出来的原因:静态资源是直接被webpack copy到对应的静态资源文件夹下,所以根本原因就在于,用了动态路径的图片,webpack将它认作为一个模块打包了,路径错乱,所以404

    解决:

    Vue.prototype.$baseUrl = process.env.BASE_URL;
    <img :src ="$baseUrl + 'img/xxx.png'" />
    

    reference:

    i__May : https://www.jianshu.com/p/f8430536059a (简书)

    相关文章

      网友评论

        本文标题:【进化指南】从vue-cli2到vue-cli3

        本文链接:https://www.haomeiwen.com/subject/ovscfqtx.html