vue-cli2.x项目的创建及配置

2,327 阅读4分钟

前言

适用于vue2.x,基于vue-cli脚手架

环境准备

node安装

  1. 官网下载并安装node.js,默认安装npm
  2. 安装淘宝镜像cnpm

npm install -g cnpm --registry=https://registry.npm.taobao.org

  1. 安装webpack

npm install webpack -g

  1. 安装vue-cli脚手架(旧版本,最新的需要另外安装@vue/cli-init才能按照2.x的方式初始化工程)

初始化项目

进入项目目录,

vue init webpack projectName

可以选择初始化工程时安装依赖或者先初始化。工程创建完成,进入工程根目录,使用npm run dev启动工程,在浏览器窗口输入localhost:8080/#/,出现下面的页面就表示创建成功了。

项目目录


build:构建脚本目录

  • build.js ==> 生产环境构建脚本
  • check-versions.js ==> 检查npm,node.js版本
  • utils.js ==> 构建相关工具方法
  • vue-loader.conf.js ==> 配置了css加载器以及编译css之后自动添加前缀
  • webpack.base.conf.js ==> webpack基本配置
  • webpack.dev.conf.js ==> webpack开发环境配置
  • webpack.prod.conf.js ==> webpack生产环境配置

config:项目配置

  • dev.env.js ==> 开发环境变量
  • prod.env.js ==> 生产环境变量
  • index.js ==> 项目配置文件

node_modules: npm加载的项目依赖模块 rc:这里是我们要开发的目录

  • assets:资源目录,放置一些图片或者公共js、公共css。这里的资源会被webpack构建
  • components:组件目录,存放组件
  • router:前端路由,路由路径写在index.js
  • App.vue:根组件
  • main.js:入口js文件

static:静态资源目录,如图片、字体等。不会被webpack构建


babelrc:babel编译参数


editorconfig:代码格式


gitignore:git上传需要忽略的文件配置


postcssrc.js:转换css的工具


index.html:首页入口文件,可以添加一些 meta 信息等


package.json:npm包配置文件,定义了项目的npm脚本,依赖包等信息 README.md:项目的说明文档,markdown 格式

集成第三方UI框架(以element-ui为例)

安装element-ui

npm install element-ui -S

在main.js文件中引入

  • 全局引入
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
  • 按需引入

安装sass/less

npm install --save-dev css-loader
npm install --save-dev sass-loader
npm install --save-dev style-loader

//sass-loader依赖于node-sass
npm install --save-dev node-sass

配置loaders

rules:[
    ....
    {
        test: /\.sass$/,
        loaders: ['style', 'css', 'sass']
    }
]

配置本地代理(解决接口跨域问题)

  • config/index.js文件对proxyTable进行配置
proxyTable: {
      '/api': {           // 配置后台代理
        target: 'http://192.168.37.56:8090', //接口的域名ip
        secure: false, //https需要配置的参数
        pathRewrite: {
          '^/api': '' //代替target中的地址
        },
        changeOrigin: true //跨域需要配置的参数
      },
      "/socket": {       // 配置webSocket
        target: 'http://192.168.37.56:8090',
        secure: false,
        pathRewrite: {
          '^/socket': ''
        },
        changeOrigin: true,
        ws: true
      },
    },
  • config/index.js的配置参数
'use strict'
const path = require('path')

module.exports = {
  // 开发环境
  dev: {
    assetsSubDirectory: 'static', // 编译输出的二级目录
    assetsPublicPath: '/',  // 编译发布的根目录,可配置为资源服务器域名或CDN域名
    proxyTable: {}, // 配置后台代理
    host: 'localhost', // 运行测试页面的域名ip
    port: 8080,  // 运行测试页面的端口
    autoOpenBrowser: false, // 项目运行时是否自动打开浏览器
    errorOverlay: true, // 浏览器错误提示
    notifyOnErrors: true, // 跨平台错误提示
    poll: false, // 使用文件系统获取文件改动的通知devServer.watchOptions
    devtool: 'cheap-module-eval-source-map', // 增加调试,该属性为原始源代码
    cacheBusting: true, // 使缓存失效
    cssSourceMap: true // 代码压缩后bug定位将非常困难,引入SourceMap记录压缩前后的位置信息记录,当产生错误时直接定位到压缩前的位置
  },
  // 生产环境
  build: {
    index: path.resolve(__dirname, '../dist/index.html'), // 编译输入的index.html文件
    assetsRoot: path.resolve(__dirname, '../dist'), // 编译输出的静态资源路径(项目打包时的文件)
    assetsSubDirectory: 'static', // 编译输出的二级目录
    assetsPublicPath: '/', // 编译发布的根目录,可配置为资源服务器域名或CDN域名
    productionSourceMap: true, // 是否开启cssSourceMap
    devtool: '#source-map', // 增加调试,该属性为原始源代码
    productionGzip: false, // 是否开启gzip
    productionGzipExtensions: ['js', 'css'], // 需要使用gzip压缩文件的扩展名
    bundleAnalyzerReport: process.env.npm_config_report // 打包分析
  }
}

基于axios封装网络请求工具

  1. 安装axios
npm install axios --save-dev
  1. 网络请求工程化管理目录
-services
    ---request.js //封装axios
    ---api.js //封装业务接口方法

  1. request.js
import axios from "axios";
import store from "@/store";
import { Message } from "element-ui";
let router = import("@/router");

/**
*创建axios实例
*/
axios.defaults.baseURL = "/api";
axios.defaults.headers.post["Content-Type"] = "application/json;charset=UTF-8";
axios.defaults.headers["X-Requested-With"] = "XMLHttpRequest";
axios.defaults.headers["Cache-Control"] = "no-cache";
axios.defaults.headers["pragma"] = "no-cache";

let source = axios.CancelToken.source();

//请求添加token
axios.interceptors.request.use(request => {
    request.headers["demo-auth"] = store.state.loginInfo ? store.state.loginInfo.userId : ""; 
    // 已将userId保存在store中
    return request;
})

//切换页面取消请求
axios.interceptors.request.use(request => {
    request.cancelToken = source.token;
    return request;
});
router.then(lib => {
    lib.default.beforeEach((to, from, next) => {
        source.cancel()
        source = axios.CancelToken.source();
        next()
    })
})

//登录过期跳转
axios.interceptors.response.use(response => {
    let data = response.data;
    if (
        [10002].includes(data.ret)
    ) {
        router.then(lib => lib.default.push({ name: "login" })); // 跳转到登录页面
        Message.warning(data.msg);
    }
    return response;
})

//返回值解构
axios.interceptors.response.use(response => {
    let data = response.data;
    let isJson = (response.headers["content-type"] || "").includes("json");
    if (isJson) {
        if (data.code === 200) {
            return Promise.resolve({
                data: data.data,
                msg: data.msg,
                code: data.code,
            });
        }
        return Promise.reject(
            data.msg ||
            "网络错误"
        );
    } else {
        return data;
    }
}, err => {
    let isCancel = axios.isCancel(err);
    if (isCancel) {
        return new Promise(() => { });
    }
    return Promise.reject(
        err.response.data &&
        err.response.data.msg ||
        "网络错误"
    );
})

export function post(url, data, otherConfig) {
    return axios.post(url, data, otherConfig);
}

export function get(url, data, otherConfig) {
    return axios.get(url, { params: data, ...otherConfig });
}

/**
*get,post,单个请求,多个请求,带有超时时间的请求
*/
  1. api.js
  • 可以采用两层管理model+service(面向对象封装)
export function xxx() {
    return request.get();
}
export function xxx() {
    return request.post();
}