CLI4搭建项目

本文详细介绍了如何使用Vue CLI4搭建项目,包括安装脚手架、创建Vue项目,以及后续的配置,如抽离路由代码、设置Vuex、封装axios、配置路由导航守卫、引入reset.css、添加环境变量、构建命令、动态API地址、工具方法、全局过滤器和vue.config.js的定制等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Vue CLI4

1-安装脚手架vue-cli4
  • @vue/cli
2-新建Vue项目
  • vue create project_name

  • 默认选择使用了VuexVue-Router,对于业务项目来说,这两个插件是必备的。

3.1-抽出单独routes代码
  • src/router/index.js
    在这里插入图片描述
    在这里插入图片描述
  • src/router/routes.js
    在这里插入图片描述
3.2-store

项目刚开始时,Vuex配置保持不变,等到项目状态管理复杂之后,在考虑进行模块的分割。

  • src/store/index.js
    在这里插入图片描述
3.3-eslint
  • rc: run-command

  • .eslintrc.js
    在这里插入图片描述
    在这里插入图片描述


  • 在这里插入图片描述

3.4-封装axios
  • src/http(api/services)/service.js
import axios from 'axios';

const baseURL = process.env.API_URL;
const service = axios.create({
    baseURL: baseURL || 'https://www.baidu.com',
    // 请求超时时间(ms)
    timeout: 5000
});
/* 请求拦截器 */
service.interceptors.request.use(
    config => {
        // 在发送请求之前做些什么
        return config;
    },
    error => {
        // 对请求错误做些什么
        return Promise.reject(error);
    }
);
/* 响应拦截器 */
service.interceptors.response.use(
    response => {
        // 对响应数据做些什么
        return response;
    },
    error => {
        // 对响应错误做些什么
        return Promise.reject(error);
    }
);

export default {
    /* 封装POST方法 */
    post(url, data = {}) {
        // 请求发出前可以进行一些处理
        return service.post(url, data).then(res => {
            // 对请求返回值进行一些处理
            return res;
        }, err => {
            return Promise.reject(err);
        });
    },
    /* 封装GET方法 */
    get(url, params) {
        // 请求发出前做一些处理
        return service({
            method: 'get',
            url: url,
            params
        }).then(
            res => {
                return res;
            },
            err => {
                return Promise.reject(err);
            }
        );
    }
};
  • main.js添加api
    1引入
    在这里插入图片描述
    2加到vue原型
    在这里插入图片描述
3.5-设置路由全局导航守卫
  • src/router/index.js
    在这里插入图片描述
  • scrollBehavior
3.6-引入reset.css文件
  • src/styles/reset.css
html,
body,
div,
span,
button,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
a,
em,
img,
strong,
b,
u,
i,
dl,
dt,
dd,
ol,
ul,
li,
form,
label,
table,
tbody,
thead,
tr,
th,
td {
    margin: 0;
    padding: 0;
    border: 0;
}

html,
body {
    height: 100%;
}

ol,
ul {
    list-style: none;
}

img {
    border: 0;
    vertical-align: middle;
}

.clearfix:after {
    clear: both;
    content: '';
    display: block;
}

.clearfix .left {
    float: left;
}

.clearfix .right {
    float: right;
}

.clearfix .over {
    overflow: hidden;
    display: block;
    height: 100%;
}

.flex {
    display: flex;
}

.flex .auto {
    flex: 1;
}

.cursor {
    cursor: pointer;
}
  • src/App.vue
    在这里插入图片描述
3.7-添加环境文件

在这里插入图片描述

3.8-添加打包命令

在这里插入图片描述

3.8-根据不同环境动态获取api地址
  • src/config/index.js
    在这里插入图片描述
  • src/http(api)/axios.js
    在这里插入图片描述
3.9-添加工具方法
  • src/utils/index.js
/* 手机机型和环境判断 start */
export function isWechat() {
    const ua = window.navigator.userAgent.toLowerCase();
    return ua.match(/MicroMessenger/i) === 'micromessenger';
}
export function isAlipay() {
    const ua = window.navigator.userAgent.toLowerCase();
    return ua.match(/AlipayClient/i) === 'alipayclient';
}
export function isAndroid() {
    const ua = window.navigator.userAgent.toLowerCase();
    return ua.indexOf('android') > -1;
}
export function isiOS() {
    const ua = window.navigator.userAgent;
    return !!ua.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
}
/* 手机机型和环境判断 end */
/* 获取url上的参数 start */
export function GetUrlParam() {
    var name, value;
    var str = location.href; // 取得整个地址栏
    var num = str.indexOf('?');
    str = str.substr(num + 1); // 取得所有参数   stringvar.substr(start [, length ]

    var arr = str.split('&'); // 各个参数放到数组里
    for (var i = 0; i < arr.length; i++) {
        num = arr[i].indexOf('=');
        if (num > 0) {
            name = arr[i].substring(0, num);
            value = arr[i].substr(num + 1);
            this[name] = value;
        }
    }
}
/* 获取url上的参数 end */

/**
 * 格式化时间
 * @param {any} time
 * 时间对象或字符串
 * @param {string} cFormat
 * 自定义日期格式y|m|d|h|i|s|a对应年月日时分秒星期
 * 例如'{m}/{d} {h}/{i}' 默认 '{y}-{m}-{d} {h}:{i}:{s}'
 * @return {string}
 * 格式化后的时间
 */
export function parseTime(time, cFormat) {
    if (arguments.length === 0) {
        return null;
    }
    const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}';
    let date;
    // 时间对象 直接赋值
    if (typeof time === 'object') {
        date = time;
    } else {
    // 10位时间戳也就是单位为s的时间戳 转13位 ms
        if (('' + time).length === 10) time = parseInt(time) * 1000;
        // 转时间对象
        date = new Date(time);
    }
    // 获取年月日时分秒星期
    const formatObj = {
        y: date.getFullYear(),
        m: date.getMonth() + 1,
        d: date.getDate(),
        h: date.getHours(),
        i: date.getMinutes(),
        s: date.getSeconds(),
        a: date.getDay()
    };
    const timeStr = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    // 遍历格式 替换成具体的时间
        let value = formatObj[key];
        // Note: getDay() returns 0 on Sunday
        if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value]; }
        // 补零
        if (result.length > 0 && value < 10) {
            value = '0' + value;
        }
        return value || 0;
    });
    return timeStr;
}
/* 获取指定url上的参数 start */
export function GetAssignUrlParam(url) {
    var name, value;
    var str = url; // 取得整个地址栏
    var num = str.indexOf('?');
    str = str.substr(num + 1); // 取得所有参数   stringvar.substr(start [, length ]

    var arr = str.split('&'); // 各个参数放到数组里
    for (var i = 0; i < arr.length; i++) {
        num = arr[i].indexOf('=');
        if (num > 0) {
            name = arr[i].substring(0, num);
            value = arr[i].substr(num + 1);
            this[name] = value;
        }
    }
}

export function priceFormat(price) {
    let value = Math.round(parseInt(price)) / 100;
    const s = value.toString().split('.');

    if (s.length === 1) {
        value = value.toString() + '.00';
        return value;
    }
    if (s.length > 1) {
        if (s[1].length < 2) {
            value = value.toString() + '0';
        }
        return value;
    }
}
  • src/utils/validate.js

(https://github.com/Yourbones/vue-project/commit/cd286215642b4e6665a42212adc9eb9f0eeae418)

3.10-添加全局过滤器
  • src/filter.js
// 全局过滤器
// 全局 filters

import Vue from 'vue';
import moment from 'moment';

// 地址拼接
Vue.filter('address', function (data) {
    return data.province + data.city + data.district;
});
// 详情地址拼接
Vue.filter('addressDetail', function (data) {
    console.log(data);
    if (data.province) {
        return data.province + data.city + data.district + data.detailAddress;
    } else {
        return '';
    }
});

// 时间转换
Vue.filter('timestr', function (value) {
    if (value) { return moment(value).format('YYYY-MM-DD HH:mm:ss'); } else { return ''; }
});

// 价格除 100 展示
Vue.filter('price', function (value) {
    return value / 100;
});
// 礼品活动状态码
Vue.filter('activeStatus', function (value) {
    const mapObj = {
        '00': '未知状态',
        11: '待平台审核',
        12: '平台审核失败',
        21: '银行提交资料失败',
        22: '银行绑卡失败',
        30: '绑卡成功等待签约',
        31: '签约失败',
        32: '开通条码付失败',
        40: '开通成功'
    };
    return mapObj[value];
});
// 订单状态
Vue.filter('orderStatus', function (val) {
    const mapObj = {
        1: '待支付',
        2: '待发货',
        3: '待签收',
        4: '已完成',
        5: '已关闭',
        6: '已退款'
    };
    return mapObj[val];
});
// 付款方式
Vue.filter('payStatus', function (val) {
    const mapObj = {
        1: '微信支付',
        2: '支付宝支付',
        3: '余额支付'
    };
    return mapObj[val];
});
// 订单的付款状态
Vue.filter('orderPayStatus', function (val) {
    const mapObj = {
        1: '未付款',
        2: '已付款',
        3: '已付款',
        4: '已付款',
        5: '未付款',
        6: '已付款'
    };
    return mapObj[val];
});
// 商户类型
Vue.filter('detailType', function (val) {
    const mapObj = {
        1: '个体工商户',
        2: '企业商户',
        3: '小微商户'
    };
    return mapObj[val];
});
// 单据状态
Vue.filter('renderpayApproval', function (val) {
    const mapObj = {
        0: '待审批',
        1: '审批通过',
        2: '审批不通过'
    };
    return mapObj[val];
});
// 售后方式
Vue.filter('afterSaleStatus', function (val) {
    const mapObj = {
        0: '退款中',
        1: '退款成功',
        2: '退款失败',
        3: '退款申请中',
        4: '退款关闭'
    };
    return mapObj[val] || '无需售后';
});
// 商品规格拼接展示
Vue.filter('skuString', function (val) {
    const data = JSON.parse(val);
    let skuString = '';
    if (data.length > 0) {
        data.forEach(ele => {
            skuString = skuString + ' ' + ele.specValue;
        });
    }
    return skuString;
});

// 等级
Vue.filter('level', function (val) {
    const mapObj = {
        1: '陌生人',
        2: '普通用户',
        3: '金牌会员',
        4: '铂金会员',
        5: '荣耀会员'
    };
    return mapObj[val];
});

// 优惠券状态
Vue.filter('couponStatus', function (val) {
    const mapObj = {
        1: '未发布',
        2: '进行中',
        3: '已过期'
    };
    return mapObj[val];
});

// 数组转为字符串
Vue.filter('ArrartoString', function (val, type) {
    return val && val.join(type);
});
3.11-添加vue.config.js配置文件
  • vue.config.js
    在这里插入图片描述
  • css-loader
    在这里插入图片描述
  • devServer
    在这里插入图片描述在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值