前端搭建vue项目的流程以及相关的封装

vue3.0项目搭建:

一、环境配置

1、在根目录下新建一个开发环境文件(.env.development)和一个生产环境文件(.env.production)

.env.development

NODE_ENV = 'development'

//必须以VUE_APP_开头
VUE_APP_ENV = 'development'

====================================

.env.production

NODE_ENV ='production'

//必须以VUE_APP_开头
VUE_APP_ENV = 'production'


2、在src目录下新建一个config文件夹,下面建三个文件,分别是:index.js、env.development.js、env.production.js

index.js

const config = require('./env.'+ process.env.VUE_APP_ENV)

module.exports = config

==============================================================

env.development.js

module.exports = {
	title:'本地环境',
	baseApi:'http://www.xxx.com'
}

=======================================

env.production.js

module.exports = {
	title:'生产环境',
	baseApi:'http://www.xxx.com'
}

=======================================

3、此时我们可以根椐npm run dev 和 npm run build 分别可以拿到测试和生产的接口域名,所以统一封装
   请求axios请求接口。
   在src目录下新建一个util文件夹,下面新建一个request.js文件
  
request.js

import axios from 'axios'
import {baseApi} from './../config'

const service = axios.create({
    baseURL: baseApi,
    withCredentials: false,
    timeout: 5000
})

// request拦截器 request interceptor
service.interceptors.request.use(config => {
    console.log('config',config)
    return config
},error => {
    console.log(error);
    return Promise.reject(error)
})


// respone拦截器
service.interceptors.response.use(response => {
    const res = response.data
    if(res.status && res.status !== 200) {
        return Promise.reject(res)
    } else {
        return Promise.resolve(res)
    }
},error =>{
    return Promise.reject(error)
})
export default service

==================================================

4、在util目录下新建http.js,这里统一封装一下请求:

import request from './request.js'

export default{
	get(url,method='get'){
		request({
			url,
			method
		})
	},
	
	post(url,method='post',data){
		return request({
			url,
			method,
			data
		})
	}
}

====================================================

5、在src目录下新建一个api文件夹,在下面建一个home.js,这里统一写请求接口:

import $ from '../util/http'

export const getUser = ()=>{
	return $.get('/user')
}

====================================================

6、然后在组件页面中使用:

import {getUser} from './../api/home'

export default{
	created(){
		getUser().then(res=>{
			console.log(res)
		})
	}
}

=====================================================

二、配置跨域

在根目录下新建一个文件vue.config.js

const path = require('path')
const resolve = dir => path.join(__dirname, dir)
module.exports = {
  publicPath: './', // 署应用包时的基本 URL。 vue-router hash 模式使用
  outputDir: 'dist', //  生产环境构建文件的目录
  assetsDir: 'static', //  outputDir的静态资源(js、css、img、fonts)目录
  lintOnSave: false, //eslint 检测
  productionSourceMap: false, // 如果你不需要生产环境的 source map,可以将其设置为 false 以加速生产环境构建。
  devServer: {
    port: 9527, // 端口
    open: false, // 启动后打开浏览器
    overlay: {
      //  当出现编译器错误或警告时,在浏览器中显示全屏覆盖层
      warnings: false,
      errors: true
    },
    proxy: {
      //配置跨域
      '/api': {
          target: "https://test.xxx.com",
          // ws:true,
          changOrigin:true,
          pathRewrite:{
              '^/api':'/'
          }
      }
    }
  },
  chainWebpack:(config)=>{
    config.resolve.alias
    .set('@', resolve('src'))
    .set('assets', resolve('src/assets'))
    .set('api', resolve('src/api'))
    .set('views', resolve('src/views'))
    .set('components', resolve('src/components'))
  }
}

===========================================================

// 引入axios
import axios from 'axios';

// 创建axios实例
const httpService = axios.create({
    // url前缀-'https://some-domain.com/api/'
    baseURL: process.env.BASE_API, // 需自定义
    // 请求超时时间
    timeout: 3000 // 需自定义
});

// request拦截器
httpService.interceptors.request.use(
    config => {
        // 根据条件加入token-安全携带
        if (true) { // 需自定义
            // 让每个请求携带token
            config.headers['User-Token'] = '';
        }
        return config;
    }, 
    error => {
        // 请求错误处理
        Promise.reject(error);
    }
)

// respone拦截器
httpService.interceptors.response.use(
    response => {
        // 统一处理状态
        const res = response.data;
        if (res.statuscode != 1) { // 需自定义
            // 返回异常
            return Promise.reject({
                status: res.statuscode,
                message: res.message
            });
        } else {
            return response.data;
        }
    },
    // 处理处理
    error => {
         if (error && error.response) {
            switch (error.response.status) {
                case 400:
                    error.message = '错误请求';
                    break;
                case 401:
                    error.message = '未授权,请重新登录';
                    break;
                case 403:
                    error.message = '拒绝访问';
                    break;
                case 404:
                    error.message = '请求错误,未找到该资源';
                    break;
                case 405:
                    error.message = '请求方法未允许';
                    break;
                case 408:
                    error.message = '请求超时';
                    break;
                case 500:
                    error.message = '服务器端出错';
                    break;
                case 501:
                    error.message = '网络未实现';
                    break;
                case 502:
                    error.message = '网络错误';
                    break;
                case 503:
                    error.message = '服务不可用';
                    break;
                case 504:
                    error.message = '网络超时';
                    break;
                case 505:
                    error.message = 'http版本不支持该请求';
                    break;
                default:
                    error.message = `未知错误${error.response.status}`;
            }
        } else {
            error.message = "连接到服务器失败";
        }
        return Promise.reject(error);
    }
)

/*网络请求部分*/

/*
 *  get请求
 *  url:请求地址
 *  params:参数
 * */
export function get(url, params = {}) {
    return new Promise((resolve, reject) => {
        httpService({
            url: url,
            method: 'get',
            params: params
        }).then(response => {
            resolve(response);
        }).catch(error => {
            reject(error);
        });
    });
}

/*
 *  post请求
 *  url:请求地址
 *  params:参数
 * */
export function post(url, params = {}) {
    return new Promise((resolve, reject) => {
        httpService({
            url: url,
            method: 'post',
            data: params
        }).then(response => {
            resolve(response);
        }).catch(error => {
            reject(error);
        });
    });
}

/*
 *  文件上传
 *  url:请求地址
 *  params:参数
 * */
export function fileUpload(url, params = {}) {
    return new Promise((resolve, reject) => {
        httpService({
            url: url,
            method: 'post',
            data: params,
            headers: { 'Content-Type': 'multipart/form-data' }
        }).then(response => {
            resolve(response);
        }).catch(error => {
            reject(error);
        });
    });
}

export default {
    get,
    post,
    fileUpload
}


=============================================================================

vue cli3中使用postcss-pxtorem进行适配

下载依赖:
npm install postcss-pxtorem -D


新建一个rem.js的文件,在main.js中引用。
// 蓝湖上设计稿自定义为375px 测量值直接写入即可
(function() {
  const baseSize = 16; // 32
  function setRem() {
    const scale = document.documentElement.clientWidth / 375; // 750
    document.documentElement.style.fontSize =
      baseSize * Math.min(scale, 2) + "px";
  }

  window.onresize = function() {
    setRem();
  };
})();


在根目录下新建一个postcss.config.js
module.exports = {
  plugins: {
    // 兼容浏览器,添加前缀
    autoprefixer: {
      overrideBrowserslist: [
        "Android 4.1",
        "iOS 7.1",
        "Chrome > 31",
        "ff > 31",
        "ie >= 8",
        "last 10 versions", // 所有主流浏览器最近10版本用
      ],
      grid: true,
    },
    "postcss-pxtorem": {
      rootValue: 16, //结果为:设计稿元素尺寸/16,比如元素宽320px,最终页面会换算成 20rem
      propList: ["*"], //是一个存储哪些将被转换的属性列表,这里设置为['*']全部,假设需要仅对边框进行设置,可以写['*', '!border*']
      unitPrecision: 5, //保留rem小数点多少位
      //selectorBlackList: ['.radius'],  //则是一个对css选择器进行过滤的数组,比如你设置为['fs'],那例如fs-xl类名,里面有关px的样式将不被转换,这里也支持正则写法。
      replace: true, //这个真不知到干嘛用的。有知道的告诉我一下
      mediaQuery: false, //媒体查询( @media screen 之类的)中不生效
      minPixelValue: 12, //px小于12的不会被转换
    },
  },
};

// 蓝湖上设计稿自定义为375px 测量值直接写入即可 若设计稿为750px 则rootValue: 32


=======================================================================================

JS计算两个时间戳相差月数、天数、时数、分钟、秒数

function humandate(time1, time2) {
  //var time1 = Date.parse(new Date()) / 1000;
  var s = time1 - time2;
  if (s < 0) {
    s = Math.abs(s);
  }
  if (s > 31536000) {
    return formatDate(new Date(time2 * 1000));
  } else if (s > 2592000) {
    return parseInt(s / 2592000) + '月';
  } else if (s > 86400) {
    return parseInt(s / 86400) + '天';
  } else if (s > 3600) {
    return parseInt(s / 3600) + '小时';
  } else if (s > 60) {
    return parseInt(s / 60) + '分钟';
  } else {
    return parseInt(s) + '秒';
  }
}

exports.humandate = humandate;


引入:
const { humandate } = require('../../utils/humandate.js');

humandate('开始时间戳', '结束时间戳')
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值