vue项目常用配置

新建好vue项目后, 还需要配置一些常用的配置, 例如常用文件夹, 工具等;

格式化配置

eslint设置

使用prettier格式工具时, 可能会出现一些, 不能用单(双)引号, 不能用分号等提示, 可以在.eslintrc.js中rules:使用以下配置去掉

rules: {
    "no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
    "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
    "prettier/prettier": "off",
    "no-undef": 0,
    "no-unused-vars": "off",
    "vue/no-unused-vars": "off",
    "vue/no-unused-components": "off",
},

style的SASS (SCSS)设置

  1. 安装SASS (SCSS) 用于生成css工具类,和less差不多
npm i -D sass sass-loader
  1. 在/src/assets/scss文件夹下创建两个文件,varibale.scss(公共变量)文件用来存变量(写上颜色,字体,背景的属性等配置文件),styleUtil.scss用来定义工具类。
  1. 在 varibale.scss 中定义变量
    变量
    声明变量的语法是:$ + 变量名 + :+ 变量值;如下
$color:red; //声明变量 $color

默认变量
默认变量只需要在变量值后加上 !default , 用来设置默认值 ,对默认变量进行重新声明可以实现覆盖默认值;如

$color:red !default; //声明默认变量 $color
$color:purple; //根据需求覆盖默认变量
.father01 {
   color:$color;
}

区分全局变量和局部变量

$height:200px; //全局变量声明不在大花括号内
$bgcolor:blue;
body {
   .father01 {  //嵌套
      width:$width;
      height:$height;
      $border:1px solid red; //局部变量是声明在元素内的
      border: $border;
      $bgcolor:purple; //全局变量和局部变量名一致时,调用局部变量进行覆盖
      background-color: $bgcolor;
   }
}

变量嵌套引用:即字符串插值,需要使用 #{} 来进行包裹

$left:left;
.father02 {
   width: 300px;
   height:300px;
   border:$border; //使用全局变量
border-#{$left}:2px solid purple; //使用字符串插值之前必须先声明
}

变量计算

$left:left;
.father02 {
   width: 300px;
   height:300px;
   border:$border; //使用全局变量
border-#{$left}:2px solid purple; //使用字符串插值之前必须先声明
}

·继承
继承 .class 使用 @extend

.container {
   color:purple;
   border:2px dashed purple;
}
.myText {
   @extend .container; //这里将继承.container类的所有样式
   font-size: 22px;
}

重复代码块,使用混合@mixin命令定义,以及使用@include调用该mixin

@mixin normalStyle {
   //使用@mixin命令定义可重复使用的代码块
   width:300px;
   height:100px;
   color:black;
   background-color:lightblue;
}
.container {
   @include normalStyle;
   //使用@include 命令引用@mixin定义的代码块
}

在使用@mixin和@include时,传入参数和默认值

@mixin normalStyle($width,$height,$color,$defaultValue:orange) {
   width:$width;
   height:$height;
   color:$color;
   background-color:$defaultValue;
}
.container {
   @include normalStyle(300px,100px,green,lightgray);
}

SCSS使用编程式方法

.container {
   p {
      @if 1+1<3 {
         border:1px solid blue;
      } @else {
         border:1ps dashed palevioletred;
      }
   }
}

for循环
在sass中的@for循环有两种方式:
①@for i from <start> through <end> ②@fori from <start> to <end>
其中$i表示变量,start表示开始值,end表示结束值;
through表示包括end这个数值;to表示不包括end这个数值;

//for 循环
@for $i from 1 to 5 {
   .item-#{$i} {
      border:#{$i}px solid;
   }
}
//while 循环
$m:8;
@while $m > 0 {
   .items-#{$m} {
      width:2em*$m;
   }
   $m:$m - 2 ;
}
//这里可以对$m进行运算 让它每次都减去2
//each 语法
@each $item in class01,class02 { //$item就是遍历了in关键词后面的类名列
   .#{$item} {
      background-color:purple;
   }
}

更多查看http://www.taodudu.cc/news/show-3611324.html?action=onClick

  1. 在 style.scss 中定义工具类

  2. 在main.js入口文件中引入工具类

// 工具样式SASS(类似于less)
import './assets/scss/style.scss'
  1. 在 /src/views/ArticleView.vue 文件中使用工具类,并通过SCSS语法规则编写css可以进行嵌套层级

<style lang="scss">
.page-article {
  .article-body {
    img {
      max-width: 100%;
      height: auto;
    }
  }
  .icon-back {
    font-size: 1.5rem;
  }
}

新建常用文件夹

在src路径下,新建文件夹: utils, api.

  • utils: 存放工具类
  • api: 存放接口
  • manager: 管理类

utils文件夹

存放工具, 新建一些常用工具类, 详细解释在下面:


utils

request.js: 网络请求工具, 就是网络请求封装

安装axios

npm install axios --save

在根目录创建项目的配置文件envconfig.js

// 项目名称
const projectName = 'wechat'
// 项目版本
const projectVersion = '4.4.4'

// develop 开发环境服务器
const developServiceBaseUrl = 'http://192.168.10.215:7777'
// product 发布环境服务器
const productServiceBaseUrl = 'https://gate1.thedoc.cn:8080'
// product 发布环境域名(线上域名如: baidu), 判断使用哪个服务器用
const productDomainName = 'wx.thedoc.cn'

const envconfig = {
  projectName: projectName,
  projectVersion: projectVersion,
  developServiceBaseUrl: developServiceBaseUrl,
  productServiceBaseUrl: productServiceBaseUrl,
  productDomainName: productDomainName
}

export default envconfig

request.js代码

import envconfig from '../../envconfig.js'
// 引入axios
import axios from 'axios'
import store from '@/store'

// baseurl, 默认开发环境
let baseUrl = envconfig.developServiceBaseUrl

// 根据网址环境, 判断使用哪个服务器
if (window.location.hostname === envconfig.productDomainName) {
  // 如果是正式环境, 就替换为线上服务器
  baseUrl = envconfig.productServiceBaseUrl
}

// 创建请求
const service = axios.create({
  // 服务器
  baseURL: baseUrl,
  // 设置超时时间
  timeout: 1000 * 10
})

// request请求拦截器
service.interceptors.request.use(
  config => {
    // 设置请求项目的名称
    config.headers.projectname = envconfig.projectName
    // 设置请求项目的版本
    config.headers.projectversion = envconfig.projectVersion;

    // 设置请求项目的token
    console.log('store.user.token');
    console.log(store.getters['user/token']);
    store.dispatch('user/token', '7')
    console.log(store.getters['user/token']);

    if (store.getters['user/token']) {
      config.headers.token = store.getters['user/token'];
    }
    return config;
  },
  error => {
    console.log(error);
    return Promise.reject(error)
  }
)

// response响应拦截器
service.interceptors.response.use(
  response => {
    const res = response.data
    if (!res) {
      return Promise.reject(new Error({
        errorMsg: '网络异常, 请重试...'
      }))
    } else if (res.code === 0) {
      return Promise.resolve(res)
    } else if (res.code === 1) {
      return Promise.reject(res)
    } else if (res.code === 2) {
      return Promise.reject(res)
    }
  },
  error => {
    return Promise.reject(error)
  }
)

export default service

使用
在api.js中

import request from '@/utils/request'
import qs from 'qs'
/* 获取验证码 */
export function phloginCode (params) {
  return request({
    url: '/user/phlogincode/',
    method: 'post',
    data: qs.stringify(params)
  })
}

dateTimeUtil.js: 时间工具, 包括年, 月, 日, 时间的获取, 转化等一系列相关常用操作

安装moment

npm install moment --save

使用

import Moment from "moment";


// 按指定时间获取时间戳  默认获取当前时间时间戳
// dateStr 需要转化为时间戳的时间, 格式为 "YYYY-MM-DD", 
export function dateTimestamp(dateStr) {
  let stamp = new Date().getTime();
  if (dateStr) {
    stamp = new Date(dateStr).getTime();
  }
  return stamp;
}

// 时间戳转化为指定日期格式 默认转化为格式为 'YYYY-MM-DD hh:mm'
// timestamp: 需要格式化的时间戳, 
// formatter: 需要转化成的格式, 
export function dateFormatterTimestamp(timestamp, formatter) {
  let format = 'YYYY-MM-DD hh:mm:ss';
  if (formatter) {
    format = formatter;
  }
  const stamp = new Date(timestamp);
  const date = Moment(stamp).format(format);
  return date;
}

// 将时间秒数, 转化为几小时几分几秒
export function dateSecondsChangeToHours(seconds) {
  // 需要转换的时间秒数量, 将字符串转换为数字
  const secondsValue = parseInt(seconds); 
  // 天个数
  let day = 0; // 分
  // 小时个数
  let hour = 0; // 分
  // 分钟数
  let minute = 0; // 小时
  // 秒个数
  let second = 0; // 天
  // 秒数转化为分钟数
  if (secondsValue > 60) {
    // 如果秒数大于60秒, 计算有多少分钟
    minute = secondsValue / 60;
    // 计算剩余的秒数
    second = secondsValue % 60;
    // 继续将分转化为小时
    if (minute > 60) {
      // 如果分钟数大于60秒, 计算有多少小时
      hour = minute / 60;
      // 计算剩余的分钟数
      minute = minute % 60;
      // 继续将小时转化为天
      if (hour > 24) {
        // 大于24小时
        day = hour / 24;
        hour = hour % 24;
      }
    }
  } else {
    second = secondsValue;
  }
  let result = "";
  // // 秒加0格式问题
  // if (second < 9) {
  //   second = "0" + second;
  // }
  // // 分加0格式问题
  // if (minute < 9) {
  //   minute = "0" + second;
  // }
  // // 小时加0格式问题
  // if (hour < 9) {
  //   hour = "0" + second;
  // }
  // // 天加0格式问题
  // if (day < 9) {
  //   day = "0" + second;
  // }
  result = day + "天" + hour + "小时" + minute + "分钟" + second + '秒';
  return result;
}

// 根据出生日期(生日)计算年龄, 出生日期格式为 1970-01-01
export function getAgeFromBirthday(birthday) {
  let age = 0
  if (birthday) {
    // 格式化时间格式
    if (birthday.search('.') != -1) {
      birthday = birthday.replace(/\./g, "-")
      console.log(birthday)
    }
    const birthdayArray = birthday.split('-');
    const nowDate = new Date();
    const today = [nowDate.getFullYear(), nowDate.getMonth() + 1, nowDate.getDate()];
    const ageArray = today.map((val, index) => {
      return val - Number(birthdayArray[index]);
    })
    if (ageArray[2] < 0) {
      const lastMonth = new Date(today[0], today[1], 0);
      ageArray[1]--;
      ageArray[2] += Number(lastMonth.getDate);
    }
    if (ageArray[1] < 0) {
      ageArray[0]--;
      ageArray[1] += 12;
    }
    age = ageArray[0] + 1;
  }
  return age;
}


  • randomUtil.js: 随机工具, 包括获取随机数, 随机字符等一系列相关随机获取
// num: 随机字符串的个数, 默认是1, strArray需要随机的字符串数组
export function randomStr(strArray, num) {
  // 定义默认字符串范围
  let chatArray = ["q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "a", "s", "d", "f", "g", "h", "j", "k", "l", "z", "x", "c", "v", "b", "n", "m", "A", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "A", "S", "D", "F", "G", "H", "J", "K", "L", "Z", "X", "C", "V", "B", "N", "M", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
  // 如果传入了指定的字符串, 则随机范围改成传入的
  if (strArray && strArray.length) {
    chatArray = strArray;
  }
  let length = 1;
  if (num && num >= 1) {
    length = num;
  }
  let result = "";
  for (let i = 0; i < length; i++) {
    const index = Math.floor(Math.random() * 1000) % chatArray.length;
    result += chatArray[index];
  }
  return result;
}
  • checkUtil.js: 校验工具, 包括身份证校验, 手机号校验, 位数校验, 等一系列相关校验
// 校验工具, 身份证, 手机号

// 校验身份证号 idCard: 身份证字符串
export function checkIdCard (idCard) {
  //15位和18位身份证号码的正则表达式
  let regIdCard =
    /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/;
  //如果通过该验证,说明身份证格式正确,但准确性还需计算
  if (regIdCard.test(idCard)) {
    if (idCard.length == 18) {
      //将前17位加权因子保存在数组里
      let idCardWi = new Array(
        7,
        9,
        10,
        5,
        8,
        4,
        2,
        1,
        6,
        3,
        7,
        9,
        10,
        5,
        8,
        4,
        2
      ); 
      let idCardY = new Array(1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2); //这是除以11后,可能产生的11位余数、验证码,也保存成数组
      let idCardWiSum = 0; //用来保存前17位各自乖以加权因子后的总和
      for (let i = 0; i < 17; i++) {
        idCardWiSum += idCard.substring(i, i + 1) * idCardWi[i];
      }
      let idCardMod = idCardWiSum % 11; //计算出校验码所在数组的位置
      let idCardLast = idCard.substring(17); //得到最后一位身份证号码
      //如果等于2,则说明校验码是10,身份证号码最后一位应该是X
      if (idCardMod == 2) {
        if (idCardLast == "X" || idCardLast == "x") {
          return true;
        } else {
          return false;
        }
      } else {
        //用计算出的验证码与最后一位身份证号码匹配,如果一致,说明通过,否则是无效的身份证号码
        if (idCardLast == idCardY[idCardMod]) {
          return true;
        } else {
          return false;
        }
      }
    }
  } else {
    return false;
  }
}

// 校验手机号 phone手机号字符串
export function checkPhone (phone) {
  //15位和18位身份证号码的正则表达式
  let regPhone = /^[1]([3-9])[0-9]{9}$/;
  //如果通过该验证,说明身份证格式正确,但准确性还需计算
  if (regPhone.test(phone)) {
    return true;
  } else {
    return false;
  }
}

api文件夹

api按照功能或者模块进行分类

  • login.js: 包含与登录, 登出相关的接口
import request from '@/utils/request'
import qs from 'qs'
/* 获取验证码 */
export function phloginCode (params) {
  return request({
    url: '/user/phlogincode/',
    method: 'post',
    data: qs.stringify(params)
  })
}
  • api.js: 可以放自己想要的接口(或者另建js文件)
    image.png

vuex 分类

router 分类

新建常用工具

  • js-cookie
    安装
npm install js-cookie --save

使用
在需要的文件引入

import Cookies from "js-cookie"
Cookies.set('name', 'value');
  • vant
    安装
npm i vant@latest-v2 -S

使用
由于项目中使用到的vant组件比较多, 所以我们可以单独建立一个vant.js文件进行引入, 然后再统引入到main.js中
vant.js

// 按需全局引入 vant组件
import Vue from "vue";

import {
    Button,
    List,
    Cell,
    Tabbar,
    TabbarItem,
    Sidebar,
    SidebarItem,
    CellGroup,
    Icon,
    AddressList,
    SwitchCell,
    Area,
    Popup,
    Tab,
    Tabs,
    Sticky,
    Collapse,
    CollapseItem,
    Checkbox,
    CheckboxGroup,
    TreeSelect,
    Picker,
    Overlay,
    Image as VanImage,
    Empty,
    PullRefresh,
    ImagePreview,
    Form,
    Field,
    Radio,
    RadioGroup,
    Tag,
    Stepper,
    Swipe,
    SwipeItem,
    DatetimePicker,
    Loading,
    Search,
    Badge,
    Dialog,
    ActionSheet,
    IndexBar,
    IndexAnchor,
    Uploader
} from "vant";
Vue.use(ActionSheet);
Vue.use(Dialog);
Vue.use(Badge);
Vue.use(Search);
Vue.use(Button);
Vue.use(Cell).use(CellGroup);
Vue.use(List);
Vue.use(Tabbar).use(TabbarItem);
Vue.use(Sidebar).use(SidebarItem);
Vue.use(Icon);
Vue.use(AddressList).use(SwitchCell);
Vue.use(Area).use(Popup);
Vue.use(Tab);
Vue.use(Tabs);
Vue.use(Sticky);
Vue.use(Collapse);
Vue.use(CollapseItem);
Vue.use(Checkbox);
Vue.use(CheckboxGroup);
Vue.use(TreeSelect);
Vue.use(Picker);
Vue.use(Overlay);
Vue.use(VanImage);
Vue.use(Empty);
Vue.use(PullRefresh);
Vue.use(ImagePreview);
Vue.use(Form);
Vue.use(Field);
Vue.use(Radio);
Vue.use(RadioGroup);
Vue.use(Tag);
Vue.use(Stepper);
Vue.use(Swipe);
Vue.use(SwipeItem);
Vue.use(DatetimePicker);
Vue.use(Loading);
Vue.use(IndexBar);
Vue.use(IndexAnchor);
Vue.use(Uploader);

main.js

import "./utils/vant";

安装element-ui

npm i element-ui -S

使用
新建elementui.js

import Vue from "vue";
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
// 挂载
Vue.use(ElementUI);

main.js

import "./utils/element-ui";
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容

  • 前言 接触vue框架也有一个多月的时间了,整理下之前做过的一个小demo,主要是熟悉vue全家桶技术,界面布局模仿...
    视觉派Pie阅读 26,538评论 20 285
  • vue-cli3项目搭建配置以及性能优化项目初始化 注意:安装前请确保有安装node.js,并且node>=8.9...
    O蚂蚁O阅读 1,300评论 0 1
  • 一、概念介绍 Vue.js和React.js分别是目前国内和国外最火的前端框架,框架跟类库/插件不同,框架是一套完...
    刘远舟阅读 1,057评论 0 0
  • 一、新建项目 使用 vue-cli3 构建一个初始的Vue项目:Cli3 官方文档 以下配置是我在项目中常用的,大...
    world_7735阅读 1,519评论 1 40
  • 前言 日常的开发中,我们大部分时间可能迭代需求或是修改bug,如果不是公司初始员工或是公司不重视项目重构,很难接触...
    喜欢未来你的我阅读 676评论 0 0