前端常用方法

一:对比2个数组不同
1.JSON.Stringfy(a)===JSON.Stringfy(b)
2. this._.isEqualWith(this.fileList, this.initFileList, (a, b) => {
return a.fileInfoId === b.fileInfoId
}) 判断2个数组某一个单一对应的值进行比对

二:vue获取接口里面获取对应的属性赋值给data
const arrList = [‘portfolioAccountList’, ‘custodianAccountInfo’, ‘files’, ‘applyFiles’, ‘sealFiles’, ‘activeAccountList’]
for (const item of arr) {
if (!arrList.includes(item)) {
this.$set(this.detailInfo, item, res[item])
}
三:对比2个对象不同
lodash
isEqual(a,b)
四:获取后端数据,得到自己想要的字段。
1.第一种
const arr = [‘formTypeName’, ‘uploadDateTime’, ‘fileName’, ‘fileId’, ‘uploadUserName’, ‘priceDay’, ‘uploadTypeName’, ‘directives’, ‘id’, ‘memo’, ‘accountName’, ‘planType’, ‘planTypeName’]

    for (const i of arr) {
      this.detailsInfo[i] = res[i]     }

2:第二种 解构赋值
const { formTypeName, uploadDateTime, fileName, fileId, uploadUserName, priceDay, uploadTypeName, directives, id, memo, accountName, planType, planTypeName } = res
this.detailsInfo = {
formTypeName,
uploadDateTime,
fileName,
fileId,
id,
uploadUserName,
priceDay,
uploadTypeName,
accountName,
planType,
planTypeName,
memo: memos
}

五:后端返回数据字符串,前端进行分割处理。
memos = memo.split(‘\r\n’).map(item => {
return ·\xa0${item}
})
六:常用的正则。
1: rules: [{ pattern: /^1[3-9][0-9]{9}KaTeX parse error: Expected 'EOF', got '}' at position 28: …'请输入正确的"移动电话"' }̲], 2: r…/, message: ‘请输入正确的"邮政编码"’ }]
5: (/^(-)(\d+).(\d{2}).$/, ‘$1$2.$3’),保留2位小数,只能输入一个小数点。

// 常用的正则规则
// eslint-disable-next-line
export const regExpConfig = {
  IDcard: /^[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{3}([0-9]|X)$/, // 身份证
  mobile: /^1([3|4|5|7|8|])\d{9}$/, // 手机号码
  telephone: /^(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}$/, // 固定电话
  num: /^[0-9]*$/, // 数字
  phoneNo: /(^1([3|4|5|7|8|])\d{9}$)|(^(\(\d{3,4}\)|\d{3,4}-|\s)?\d{7,14}$)/, // 电话或者手机
  policeNo: /^[0-9A-Za-z]{4,10}$/, // 账号4-10位数字或字母组成
  pwd: /^[0-9A-Za-z]{6,16}$/, // 密码由6-16位数字或者字母组成
  isNumAlpha: /^[0-9A-Za-z]*$/, // 字母或数字
  isAlpha: /^[a-zA-Z]*$/, // 是否字母
  isNumAlphaCn: /^[0-9a-zA-Z\u4E00-\uFA29]*$/, // 是否数字或字母或汉字
  isPostCode: /^[\d\-]*$/i, // 是否邮编
  isNumAlphaUline: /^[0-9a-zA-Z_]*$/, // 是否数字、字母或下划线
  isNumAndThanZero: /^([1-9]\d*(\.\d+)?|0)$/, // 是否为整数且大于0/^[1-9]\d*(\.\d+)?$/
  isNormalEncode: /^(\w||[\u4e00-\u9fa5]){0,}$/, // 是否为非特殊字符(包括数字字母下划线中文)
  isTableName: /^[a-zA-Z][A-Za-z0-9\#\$\_\-]{0,29}$/, // 表名
  isInt: /^-?\d+$/, // 整数
  isTableOtherName: /^[\u4e00-\u9fa5]{0,20}$/, // 别名
  // isText_30: /^(\W|\w{1,2}){0,15}$/, // 正则
  // isText_20: /^(\W|\w{1,2}){0,10}$/, // 正则
  isText_30: /^(\W|\w{1}){0,30}$/, // 匹配30个字符,字符可以使字母、数字、下划线、非字母,一个汉字算1个字符
  isText_50: /^(\W|\w{1}){0,50}$/, // 匹配50个字符,字符可以使字母、数字、下划线、非字母,一个汉字算1个字符
  isText_20: /^(\W|\w{1}){0,20}$/, // 匹配20个字符,字符可以使字母、数字、下划线、非字母,一个汉字算1个字符
  isText_100: /^(\W|\w{1}){0,100}$/, // 匹配100个字符,字符可以使字母、数字、下划线、非字母,一个汉字算1个字符
  isText_250: /^(\W|\w{1}){0,250}$/, // 匹配250个字符,字符可以使字母、数字、下划线、非字母,一个汉字算1个字符
  isNotChina: /^[^\u4e00-\u9fa5]{0,}$/, // 不为中文  IDcard: /^[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{3}([0-9]|X)$/, // 身份证
  IDcardAndAdmin: /^(([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{3}([0-9]|X))|(admin))$/, // 身份证或者是admin账号
  IDcardTrim: /^\s*(([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{3}([0-9]|X))|(admin))\s*$/, // 身份证
  num1: /^[1-9]*$/, // 数字
  companyNO: /^qqb_[0-9a-zA-Z_]{1,}$/, // 公司人员账号
  imgType: /image\/(png|jpg|jpeg|gif)$/, // 上传图片类型
  isChina: /^[\u4e00-\u9fa5]{2,8}$/,
  isNozeroNumber: /^\+?[1-9]\d*$/, // 大于零的正整数
  float: /^\d+(\.?|(\.\d+)?)$/, // 匹配正整数或者小数 或者0.这个特殊值
}

七,前端不设置宽高,水平垂直居中的几种方法:

1、flex

大家的第一反应,可能就是 flex 了。因为它的写法够简单直观,兼容性也没什么问题。是手机端居中方式的首选。

<div class="wrapper flex-center">
    <p>horizontal and vertical</p>
</div>
.wrapper {
    width: 300px;
    height: 300px;
    border: 1px solid #ccc;
}
.flex-center {
    display: flex;
    justify-content: center;
    align-items: center;
}
利用到了 2 个关键属性:justify-content 和 align-items,都设置为 center,即可实现居中。

需要注意的是,一定要把这里的 flex-center 挂在父级元素,才能使得其中 唯一的 子元素居中。

2、flex + margin

这是 flex 方法的变种。父级元素设置 flex,子元素设置 margin: auto;。可以理解为子元素被四周的 margin “挤” 到了中间。

<div class="wrapper">
    <p>horizontal and vertical</p>
</div>
.wrapper {
    width: 300px;
    height: 300px;
    border: 1px solid #ccc;
    display: flex;
}
.wrapper > p {
    margin: auto;
}
3、transform + absolute

这个组合,常用于图片的居中显示。

<div class="wrapper">
    <img src="test.png">
</div>
.wrapper {
    width: 300px;
    height: 300px;
    border: 1px solid #ccc;
    position: relative;
}
.wrapper > img {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
}
当然,也可以将父元素 wrapper 的相对定位,移入子元素 img 中,替换掉绝对定位。效果是一样的。

4、table-cell

利用 table 的单元格居中效果展示。与 flex 一样,需要写在父级元素上。

<div class="wrapper">
    <p>horizontal and vertical</p>
</div>
.wrapper {
    width: 300px;
    height: 300px;
    border: 1px solid #ccc;
    display: table-cell;
    text-align: center;
    vertical-align: middle;
}
5、absolute + 四个方向的值相等

使用绝对定位布局,设置 margin:auto;,并设置 top、left、right、bottom 的 值相等即可(不一定要都是 0)。

<div class="wrapper">
    <p>horizontal and vertical</p>
</div>
.wrapper {
    width: 300px;
    height: 300px;
    border: 1px solid #ccc;
    position: relative;
}
.wrapper > p {
    width: 170px;
    height: 20px;
    margin: auto;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
}
这种方法一般用于弹出层,需要设置弹出层的宽高。

6、writing-mode

这个方法可以改变文字的显示方向,比如让文字的显示变为垂直方向。

<div class="wrapper">
    <div class="wrapper-inner">
        <p>horizontal and vertical</p>
    </div>
</div>
.wrapper {
    width: 300px;
    height: 300px;
    border: 1px solid #ccc;
    writing-mode: vertical-lr;
    text-align: center;
}
.wrapper > .wrapper-inner {
    writing-mode: horizontal-tb;
    display: inline-block;
    text-align: center;
    width: 100%;
}
.wrapper > .wrapper-inner > p {
    display: inline-block;
    margin: auto;
    text-align: left;
}
兼容性上还有些小瑕疵,但大部分浏览器,包括手机端已支持 writing-mode 的写法了。

7、grid

像表格一样,网格布局让我们能够按行或列来对齐元素。然而在布局上,网格比表格更可能做到或更简单。

<div class="wrapper">
    <p>horizontal and vertical</p>
</div>
.wrapper {
    width: 300px;
    height: 300px;
    border: 1px solid #ccc;
    display: grid;
}
.wrapper > p {
    align-self: center;
    justify-self: center;
}
但它在兼容性上不如 flex,特别是 IE 浏览器,只支持 IE10 及以上。

8::after

伪元素也能用来实现居中么?感觉还是挺神奇的,看下面这个例子:

<div class="wrapper">
    <img src="test.png">
</div>
.wrapper {
    width: 300px;
    height: 300px;
    border: 1px solid #ccc;
    text-align: center;
}
.wrapper::after {
    content: '';
    display: inline-block;
    vertical-align: middle;
    height: 100%;
}
.wrapper > img {
    vertical-align: middle;
}
水平方向很好理解。垂直方向,可以理解为 ::after 把 img 往下拉到了中间。

9::before

另一种是配合 font-size: 0; 共同施展的魔法。

<div class="wrapper">
    <img src="test.png">
</div>
.wrapper {
    width: 300px;
    height: 300px;
    border: 1px solid #ccc;
    text-align: center;
    font-size: 0;
}
.wrapper::before {
    display: inline-block;
    vertical-align: middle;
    font-size: 14px;
    content: '';
    height: 100%;
}
.wrapper > img {
    vertical-align: middle;
    font-size: 14px;
}
font-size: 0; 的神秘之处在于,可以消除标签之间的间隙。另外,因为伪元素搭配的,都是最基础的 CSS 写法,所以不存在兼容性的风险。

七,css 左右不舍宽高,中间自适应
参考博客
八:css解决高度塌陷

1.将父元素的高度设置固定值

2.开启BFC(块格式化上下文)

        (1)设置元素浮动

        (2)设置元素为inline-block

        (3)将元素的overflow设置为hidden (推荐该方法)

        (4)设置元素绝对定位

3.直接在高度他闲的父元素最后家空白标签<div>

4.通过after伪类

        clearfix::after{

                content:" ";

                display:block;

                clear:both;

        }

既可以解决高度塌陷又可以解决父子内外边距重叠

        .clearfix:before,

        .clearfix:after{

                content:" ";

                display:table;

                clear:both;

        }

九 css伪类元素及其用法:
具体详解
十:css选择器优先级
权重之和,和越大,越优先,和一样,后者覆盖前者。!important(权重:无穷)>内联式(即行内样式)(1000)>id选择器(100)>类选择器、伪类选择器、属性选择器(10)>标签选择器和伪元素选择器;(1)>通用选择器、相邻兄弟选择器(+)、兄弟选择器(~)、子选择器(>)(0)>继承(了解)>默认(了解)
1、css 属性 !important v-deep:

2、内联式(即行内样式)
<元素 style=" 属性:属性值; "></元素> // 权重1000
3、id选择器
#id名{ 属性:属性值;} // 权重100
4、类选择器、伪类选择器、属性选择器
.类名{ 属性:属性值;} // 权重10

元素:hover { 属性:属性值; }

input[type="text"]{ 属性:属性值; }
具体举例如:
input[type="text"]
{
    width:150px;
    background-color:yellow;
}
5、标签选择器和伪元素选择器;
标签 { 属性:属性值;} // 权重1

// 伪元素选择器:例如:
::after, ::before, ::fist-inline, ::selection等
::after { 属性:属性值; }
6、通用选择器、相邻兄弟选择器(+)、兄弟选择器(~)、子选择器(>*{ 属性:属性值;} // 权重0

 h1+p{ // 相邻兄弟选择器(+)
            color:red;
        }

  h1 ~ p{ //兄弟选择器(~)
        color:red;
    }

html > body table + ul {margin-top:20px;} //子选择器(>)

十一:ajax请求应该放在哪个生命周期?
mounted,因为js是单线程,ajax异步获取数据

十二:导出xlsx

export const changeExport = (res, name) => {
    //res:后端返回文件流 name:'文件名字'
    const aEle = document.createElement('a') // 创建a标签
    const href = window.URL.createObjectURL(res) // 创建下载的链接
    aEle.href = href
    aEle.download = `${name}.xlsx` // 下载后文件名
    document.body.appendChild(aEle)
    aEle.click() // 点击下载
    document.body.removeChild(aEle) // 下载完成移除元素
    window.URL.revokeObjectURL(href)
}
//后台系统可直接使用
// 名字脱敏 只展示姓 后面展示**
export function anonymizedName(val) {
    const reg = /(?<=.)./g
    return val.replace(reg, '*')
}

十三:日历,带农历按周一到周日排列

<div class="week-wrapper text-[#969798] mb-[4px]">
    <div class="week-item"></div>
    <div class="week-item"></div>
    <div class="week-item"></div>
    <div class="week-item"></div>
    <div class="week-item"></div>
    <div class="week-item"></div>
    <div class="week-item"></div>
  </div>
  <div class="month-day-wrapper">
    <div v-for="(day, index) in days" :key="index" class="day-item" @click="handleDay(day)">
      <!-- day.isToday ? '今天' :  -->
      <div class="text-[10px] text-center">
        {{ day.dateText }}
      </div>
      <!-- <div class="text-center text-[10px]" :class="day.selected ? 'text-[#fff]' : 'text-[#969798]'">
        {{ day.chineseDateText }}
      </div> -->
    </div>
    <!-- v-if="isMonth" -->

    <div v-for="(item, indexx) in 7 - (days.length % 7)" :key="indexx" class="day-item"></div>
  </div>
import { toLunar } from '../../calendar/utils.js'
export default {
  data() {
    return {
      days: [], // 当前月的所有日期的数据集合
      currentDateText: '', // 头部标题年月
      currentDate: '', // 初始化时为当前日期
      showPicker: false,
      isMonth: true,
      selectedObj: {
        dateText: ''
      },
      // 周末所用日期
      weekDay: '',
      weekDays: '',
      currentFirstDates: ''
    }
  },
  mounted() {
    this.currentDate = new Date()
    this.initPickers()
  },
  methods: {
    chineseNumber(num, month) {
      let dateHash = ['', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十']
      let res = ''
      if (num === 1) {
        res = month
      } else if (num <= 10) {
        res = '初' + dateHash[num]
      } else if (num > 10 && num < 20) {
        res = '十' + dateHash[num - 10]
      } else if (num === 20) {
        res = '二十'
      } else if (num > 20 && num < 30) {
        res = '廿' + dateHash[num - 20]
      } else if (num === 30) {
        res = '三十'
      }
      return res
    },
    open() {
      this.showPicker = true
    },
    confirm() {
      this.getSelectedDay()
    },
    cancle() {
      this.showPicker = false
    },
    getSelectedDay() {
      for (let i = 0; i < this.days.length; i++) {
        if (this.days[i].selected) return this.days[i]
      }
    },
    /**
     * 日历点击事件,更新点击选中状态
     * @param {Object} day
     */
    handleDay(day) {
      if (!day.date) return
      for (let i = 0; i < this.days.length; i++) {
        this.days[i].selected = day.dateText === this.days[i].dateText
      }
      this.selectedObj = day
      this.updateTitle(day)
    },
    /**
     * 更新标题年月
     * @param {Object} day
     */
    updateTitle(day) {
      this.currentDateText = this.getDateText(day.date)
    },
    /**
     * 设置日历标题
     * @param {Object} day
     */
    getDateText(day) {
      return day.getFullYear() + '年' + (day.getMonth() + 1) + '月'
    },
    /**
     * 转换成周几
     * @param {Object} day
     */
    getWeekText(day) {
      let weekVal = day.getDay()
      let weekText = ''
      switch (weekVal) {
        case 0:
          weekText = '日'
          break
        case 1:
          weekText = '一'
          break
        case 2:
          weekText = '二'
          break
        case 3:
          weekText = '三'
          break
        case 4:
          weekText = '四'
          break
        case 5:
          weekText = '五'
          break
        case 6:
          weekText = '六'
          break
      }
      return '周' + weekText
    },
    /**
     * 计算某个月的天数
     * @param {Object} month
     */
    getMonthDaysLength(day, month) {
      day.setMonth(month)
      day.setDate(0)
      return day.getDate()
    },
    /**
     * 根据日期对象计算当前月份1日为星期几,
     * 从而计算日期数组开始需要添加几个空数据
     * @param {Object} day
     */
    getEmptyDays(day) {
      return new Date(day.setDate(1)).getDay() - 1
    },
    /**
     * 根据传入的day对象获取当前月的所有日期数据
     * @param {Object} day
     */
    getPickerData(day) {
      let that = this
      let arr = []
      let emptyLength = this.getEmptyDays(day)

      for (let i = 0; i < emptyLength; i++) {
        arr.push({}) // 根据当前月份1号是星期几向往数组里添加空数据
      }
      // let month = day.getMonth() + 1
      let month = that.currentDate.getMonth() + 1
      let daysLength = this.getMonthDaysLength(day, month) // 计算当前月份一共有多少天
      for (let a = 0; a < daysLength; a++) {
        let obj = {}

        if (that.selectedObj.dateText == '') {
          obj = {
            date: new Date(day.setDate(a + 1)), // Date类型的日期数据
            dateText: a + 1, // 用于显示的日期
            isToday: new Date().toDateString() === new Date(day.setDate(a + 1)).toDateString(), // 是否是今天
            selected: new Date().toDateString() === new Date(day.setDate(a + 1)).toDateString(), // 设置今天为选中状态
            chineseDateText: toLunar(day.getFullYear(), month, a + 1).day
          }
        } else {
          obj = {
            date: new Date(day.setDate(a + 1)), // Date类型的日期数据
            dateText: a + 1, // 用于显示的日期
            isToday: new Date().toDateString() === new Date(day.setDate(a + 1)).toDateString(), // 是否是今天
            selected:
              that.selectedObj.dateText === a + 1 &&
              that.selectedObj.chineseDateText === toLunar(day.getFullYear(), month, a + 1).day, // 设置今天为选中状态
            chineseDateText: toLunar(day.getFullYear(), month, a + 1).day
          }
        }

        arr.push(obj)
      }
      return arr
    },
    initPicker() {
      this.days = this.getPickerData(this.currentDate) // 默认当前日期初始化日历
    },
    // 回到今天
    initPickers() {
      this.currentDate = new Date()
      this.selectedObj = {
        dateText: ''
      }
      this.days = this.getPickerData(new Date()) // 默认当前日期初始化日历
    }
  }
}
// toLunar开始
var MIN_YEAR = 1891

var MAX_YEAR = 2100

var lunarInfo = [
  [0, 2, 9, 21936],
  [6, 1, 30, 9656],
  [0, 2, 17, 9584],
  [0, 2, 6, 21168],
  [5, 1, 26, 43344],
  [0, 2, 13, 59728],

  [0, 2, 2, 27296],
  [3, 1, 22, 44368],
  [0, 2, 10, 43856],
  [8, 1, 30, 19304],
  [0, 2, 19, 19168],
  [0, 2, 8, 42352],

  [5, 1, 29, 21096],
  [0, 2, 16, 53856],
  [0, 2, 4, 55632],
  [4, 1, 25, 27304],
  [0, 2, 13, 22176],
  [0, 2, 2, 39632],

  [2, 1, 22, 19176],
  [0, 2, 10, 19168],
  [6, 1, 30, 42200],
  [0, 2, 18, 42192],
  [0, 2, 6, 53840],
  [5, 1, 26, 54568],

  [0, 2, 14, 46400],
  [0, 2, 3, 54944],
  [2, 1, 23, 38608],
  [0, 2, 11, 38320],
  [7, 2, 1, 18872],
  [0, 2, 20, 18800],

  [0, 2, 8, 42160],
  [5, 1, 28, 45656],
  [0, 2, 16, 27216],
  [0, 2, 5, 27968],
  [4, 1, 24, 44456],
  [0, 2, 13, 11104],

  [0, 2, 2, 38256],
  [2, 1, 23, 18808],
  [0, 2, 10, 18800],
  [6, 1, 30, 25776],
  [0, 2, 17, 54432],
  [0, 2, 6, 59984],

  [5, 1, 26, 27976],
  [0, 2, 14, 23248],
  [0, 2, 4, 11104],
  [3, 1, 24, 37744],
  [0, 2, 11, 37600],
  [7, 1, 31, 51560],

  [0, 2, 19, 51536],
  [0, 2, 8, 54432],
  [6, 1, 27, 55888],
  [0, 2, 15, 46416],
  [0, 2, 5, 22176],
  [4, 1, 25, 43736],

  [0, 2, 13, 9680],
  [0, 2, 2, 37584],
  [2, 1, 22, 51544],
  [0, 2, 10, 43344],
  [7, 1, 29, 46248],
  [0, 2, 17, 27808],

  [0, 2, 6, 46416],
  [5, 1, 27, 21928],
  [0, 2, 14, 19872],
  [0, 2, 3, 42416],
  [3, 1, 24, 21176],
  [0, 2, 12, 21168],

  [8, 1, 31, 43344],
  [0, 2, 18, 59728],
  [0, 2, 8, 27296],
  [6, 1, 28, 44368],
  [0, 2, 15, 43856],
  [0, 2, 5, 19296],

  [4, 1, 25, 42352],
  [0, 2, 13, 42352],
  [0, 2, 2, 21088],
  [3, 1, 21, 59696],
  [0, 2, 9, 55632],
  [7, 1, 30, 23208],

  [0, 2, 17, 22176],
  [0, 2, 6, 38608],
  [5, 1, 27, 19176],
  [0, 2, 15, 19152],
  [0, 2, 3, 42192],
  [4, 1, 23, 53864],

  [0, 2, 11, 53840],
  [8, 1, 31, 54568],
  [0, 2, 18, 46400],
  [0, 2, 7, 46752],
  [6, 1, 28, 38608],
  [0, 2, 16, 38320],

  [0, 2, 5, 18864],
  [4, 1, 25, 42168],
  [0, 2, 13, 42160],
  [10, 2, 2, 45656],
  [0, 2, 20, 27216],
  [0, 2, 9, 27968],

  [6, 1, 29, 44448],
  [0, 2, 17, 43872],
  [0, 2, 6, 38256],
  [5, 1, 27, 18808],
  [0, 2, 15, 18800],
  [0, 2, 4, 25776],

  [3, 1, 23, 27216],
  [0, 2, 10, 59984],
  [8, 1, 31, 27432],
  [0, 2, 19, 23232],
  [0, 2, 7, 43872],
  [5, 1, 28, 37736],

  [0, 2, 16, 37600],
  [0, 2, 5, 51552],
  [4, 1, 24, 54440],
  [0, 2, 12, 54432],
  [0, 2, 1, 55888],
  [2, 1, 22, 23208],

  [0, 2, 9, 22176],
  [7, 1, 29, 43736],
  [0, 2, 18, 9680],
  [0, 2, 7, 37584],
  [5, 1, 26, 51544],
  [0, 2, 14, 43344],

  [0, 2, 3, 46240],
  [4, 1, 23, 46416],
  [0, 2, 10, 44368],
  [9, 1, 31, 21928],
  [0, 2, 19, 19360],
  [0, 2, 8, 42416],

  [6, 1, 28, 21176],
  [0, 2, 16, 21168],
  [0, 2, 5, 43312],
  [4, 1, 25, 29864],
  [0, 2, 12, 27296],
  [0, 2, 1, 44368],

  [2, 1, 22, 19880],
  [0, 2, 10, 19296],
  [6, 1, 29, 42352],
  [0, 2, 17, 42208],
  [0, 2, 6, 53856],
  [5, 1, 26, 59696],

  [0, 2, 13, 54576],
  [0, 2, 3, 23200],
  [3, 1, 23, 27472],
  [0, 2, 11, 38608],
  [11, 1, 31, 19176],
  [0, 2, 19, 19152],

  [0, 2, 8, 42192],
  [6, 1, 28, 53848],
  [0, 2, 15, 53840],
  [0, 2, 4, 54560],
  [5, 1, 24, 55968],
  [0, 2, 12, 46496],

  [0, 2, 1, 22224],
  [2, 1, 22, 19160],
  [0, 2, 10, 18864],
  [7, 1, 30, 42168],
  [0, 2, 17, 42160],
  [0, 2, 6, 43600],

  [5, 1, 26, 46376],
  [0, 2, 14, 27936],
  [0, 2, 2, 44448],
  [3, 1, 23, 21936],
  [0, 2, 11, 37744],
  [8, 2, 1, 18808],

  [0, 2, 19, 18800],
  [0, 2, 8, 25776],
  [6, 1, 28, 27216],
  [0, 2, 15, 59984],
  [0, 2, 4, 27424],
  [4, 1, 24, 43872],

  [0, 2, 12, 43744],
  [0, 2, 2, 37600],
  [3, 1, 21, 51568],
  [0, 2, 9, 51552],
  [7, 1, 29, 54440],
  [0, 2, 17, 54432],

  [0, 2, 5, 55888],
  [5, 1, 26, 23208],
  [0, 2, 14, 22176],
  [0, 2, 3, 42704],
  [4, 1, 23, 21224],
  [0, 2, 11, 21200],

  [8, 1, 31, 43352],
  [0, 2, 19, 43344],
  [0, 2, 7, 46240],
  [6, 1, 27, 46416],
  [0, 2, 15, 44368],
  [0, 2, 5, 21920],

  [4, 1, 24, 42448],
  [0, 2, 12, 42416],
  [0, 2, 2, 21168],
  [3, 1, 22, 43320],
  [0, 2, 9, 26928],
  [7, 1, 29, 29336],

  [0, 2, 17, 27296],
  [0, 2, 6, 44368],
  [5, 1, 26, 19880],
  [0, 2, 14, 19296],
  [0, 2, 3, 42352],
  [4, 1, 24, 21104],

  [0, 2, 10, 53856],
  [8, 1, 30, 59696],
  [0, 2, 18, 54560],
  [0, 2, 7, 55968],
  [6, 1, 27, 27472],
  [0, 2, 15, 22224],

  [0, 2, 5, 19168],
  [4, 1, 25, 42216],
  [0, 2, 12, 42192],
  [0, 2, 1, 53584],
  [2, 1, 21, 55592],
  [0, 2, 9, 54560]
]

//是否闰年

function isLeapYear(year) {
  return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0
}

//天干地支年

function lunarYear(year) {
  var gan = ['庚', '辛', '壬', '癸', '甲', '乙', '丙', '丁', '戊', '己']
  var zhi = ['申', '酉', '戌', '亥', '子', '丑', '寅', '卯', '辰', '巳', '午', '未']
  var str = year.toString().split('')
  return gan[str[3]] + zhi[year % 12]
}

//生肖年

function zodiacYear(year) {
  var zodiac = ['猴', '鸡', '狗', '猪', '鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊']
  return zodiac[year % 12]
}

//公历月份天数
//@param year 阳历-年
//@param month 阳历-月
function solarMonthDays(year, month) {
  var FebDays = isLeapYear(year) ? 29 : 28
  var monthHash = ['', 31, FebDays, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  return monthHash[month]
}

//农历月份天数
function lunarMonthDays(year, month) {
  var monthData = lunarMonths(year)
  return monthData[month - 1]
}

//农历月份天数数组

function lunarMonths(year) {
  var yearData = lunarInfo[year - MIN_YEAR]
  var leapMonth = yearData[0]
  var bit = (+yearData[3]).toString(2)
  var months = []
  for (var i = 0; i < bit.length; i++) {
    months[i] = bit.substr(i, 1)
  }

  for (var k = 0, len = 16 - months.length; k < len; k++) {
    months.unshift('0')
  }
  months = months.slice(0, leapMonth === 0 ? 12 : 13)
  for (var i = 0; i < months.length; i++) {
    months[i] = +months[i] + 29
  }
  return months
}

//农历每年的天数

//@param year 农历年份

function lunarYearDays(year) {
  var monthArray = lunarYearMonths(year)
  var len = monthArray.length
  return monthArray[len - 1] === 0 ? monthArray[len - 2] : monthArray[len - 1]
}

//
function lunarYearMonths(year) {
  var monthData = lunarMonths(year)
  var res = []
  var temp = 0
  var yearData = lunarInfo[year - MIN_YEAR]
  var len = yearData[0] === 0 ? 12 : 13
  for (var i = 0; i < len; i++) {
    temp = 0
    for (var j = 0; j <= i; j++) {
      temp += monthData[j]
    }
    res.push(temp)
  }
  return res
}

//获取闰月

//@param year 农历年份

function leapMonth(year) {
  var yearData = lunarInfo[year - MIN_YEAR]
  return yearData[0]
}

//计算农历日期与正月初一相隔的天数
function betweenLunarDays(year, month, day) {
  var yearMonth = lunarMonths(year)
  var res = 0
  for (var i = 1; i < month; i++) {
    res += yearMonth[i - 1]
  }
  res += day - 1
  return res
}

//计算2个阳历日期之间的天数
//@param year 阳历年
//@param month
//@param day
//@param l_month 阴历正月对应的阳历月份
//@param l_day 阴历初一对应的阳历天

function betweenSolarDays(year, month, day, l_month, l_day) {
  var time1 = new Date(year + '-' + month + '-' + day).getTime()
  var time2 = new Date(year + '-' + l_month + '-' + l_day).getTime()
  return Math.ceil((time1 - time2) / 24 / 3600 / 1000)
}

//根据距离正月初一的天数计算阴历日期
//@param year 阳历年
//@param between 天数
function lunarByBetween(year, between) {
  var lunarArray = {}
  var yearMonth = []
  var t = 0
  var e = 0
  var leapMonthVal = 0
  var m = ''
  if (between === 0) {
    t = 1
    e = 1
    m = '正月'
  } else {
    year = between > 0 ? year : year - 1
    yearMonth = lunarYearMonths(year)
    leapMonthVal = leapMonth(year)
    between = between > 0 ? between : lunarYearDays(year) + between
    for (var i = 0; i < 13; i++) {
      if (between === yearMonth[i]) {
        t = i + 2
        e = 1
        break
      } else if (between < yearMonth[i]) {
        t = i + 1
        e = between - (yearMonth[i - 1] ? yearMonth[i - 1] : 0) + 1
        break
      }
    }
    m =
      leapMonthVal !== 0 && t === leapMonthVal + 1
        ? '闰'.chineseMonth(t - 1)
        : chineseMonth(leapMonthVal !== 0 && leapMonthVal + 1 < t ? t - 1 : t)
  }
  lunarArray.lunarDate = year + '-' + t + '-' + e // 年月日
  lunarArray.repetMonth = leapMonthVal //闰几月
  lunarArray.yearType = lunarYear(year) // 天干地支年
  lunarArray.animal = zodiacYear(year) // 生肖年
  lunarArray.month = m // 月份
  lunarArray.day = chineseNumber(e, m) // 日
  return lunarArray
}

//中文月份
function chineseMonth(month) {
  var monthHash = [
    '',
    '正月',
    '二月',
    '三月',
    '四月',
    '五月',
    '六月',
    '七月',
    '八月',
    '九月',
    '十月',
    '冬月',
    '腊月'
  ]
  return monthHash[month]
}

//中文日期
function chineseNumber(num, month) {
  var dateHash = ['', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十']
  var res = ''
  if (num === 1) {
    res = month
  } else if (num <= 10) {
    res = '初' + dateHash[num]
  } else if (num > 10 && num < 20) {
    res = '十' + dateHash[num - 10]
  } else if (num === 20) {
    res = '二十'
  } else if (num > 20 && num < 30) {
    res = '廿' + dateHash[num - 20]
  } else if (num === 30) {
    res = '三十'
  }
  return res
}

//转换农历
export function toLunar(year, month, day) {
  var yearData = lunarInfo[year - MIN_YEAR]
  if (year === MIN_YEAR && month <= 2 && day <= 9) {
    return [1891, 1, 1, '辛卯', '兔', '正月', '初一']
  }
  return lunarByBetween(year, betweenSolarDays(year, month, day, yearData[1], yearData[2]))
}

//转换公历
//@param year 阴历-年
//@param month 阴历-月,闰月处理:例如如果当年闰五月,那么第二个五月就传六月,相当于阴历有13个月
//@param date 阴历-日

export function toSolar(year, month, day) {
  var yearData = lunarInfo[year - MIN_YEAR]
  var between = betweenLunarDays(year, month, day)
  var ms = new Date(year + '-' + yearData[1] + '-' + yearData[2]).getTime()
  var s = ms + between * 24 * 60 * 60 * 1000
  var d = new Date()
  d.setTime(s)
  year = d.getFullYear()
  month = d.getMonth() + 1
  day = d.getDate()
  return [year, month, day]
}
// toLunar开始

```javascript
css 文件
* {
  box-sizing: border-box;
}

.window-backdrop {
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
}

.window-wrapper {
  width: 80%;
  min-width: 300px;
  max-width: 800px;
  padding: 10px 15px;
  background: #fff;
  border-radius: 10px;
  border: 1px #000 solid;
}

.week-wrapper {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: bold;

  .week-item {
    font-size: 10px;
    flex: 14.2857%;
    text-align: center;
  }
}

.today-date-text {
  display: flex;
  height: 50px;
  align-items: center;
  justify-content: space-between;
  line-height: 100%;
  padding: 0 20px;

  .text-button {
    font-size: 16px;
    color: #000;
  }

  .arrow-img {
    height: 30px;
    width: 30px;
  }

  .today-date {
    font-size: 18px;
    font-weight: bold;
  }
}

.month-day-wrapper {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;

  .day-item,
  .day-item-actived {
    flex: 14.2857%;
    margin-bottom: 4.5px;
    font-size: 10px;
    cursor: pointer;
    overflow: hidden;
    font-weight: normal;

    .chinese-date-text {
      text-align: center;
      color: #fff;
    }
  }
  .date-text {
    text-align: center;
    color: #343538;
  }
  .day-item {
    color: #343538;
  }

  .day-item-actived {
    padding: 4px;
    color: #fff;
    background: #2875dd;
    border-radius: 50%;
  }
}

十四:深拷贝

export const deepClone = (obj) => {
    if (obj === null || typeof obj !== 'object') {
        return obj
    }
    if (obj instanceof Date) {
        return new Date(obj.getTime())
    }
    if (obj instanceof Array) {
        return obj.reduce((arr, item, i) => {
            arr[i] = deepClone(item)
            return arr
        }, [])
    }
    if (obj instanceof Object) {
        return Object.keys(obj).reduce((newObj, key) => {
            newObj[key] = deepClone(obj[key])
            return newObj
        }, {})
    }
}

十五:递归清除数组每个元素下的children为空的数组,避免渲染多余

export const clearAllChildren = (items, childrenName) => {
    for (let i = 0; i < items.length; i++) {
        const item = items[i]
        // 当前对象存在children
        if (item && item[childrenName]) {
            // children为空数组时删除
            if (item[childrenName].length === 0) {
                delete item[childrenName]
            } else {
                // 递归当前children数组
                clearAllChildren(item[childrenName], childrenName)
            }
        }
    }
    return items
}

十六:echarts 初始化展示默认当前月份信息

 echartsExtmp.setOption(option)
 //dataIndex 随便赋值你想要展示的哪条数据
 setTimeout(function () {
                echartsExtmp.dispatchAction({
                    type: 'showTip',
                    seriesIndex: 0, // 显示第几个series
                    dataIndex: 2, // 显示第几个数据
                })
            })

十七:这个是为了实现el-cascader 点击父级自动勾选子级但是后端传数据只传最外层

props:{  multiple: true,//可多选
         checkStrictly: false, //父级勾选状态影响子级,true为单选状态
         emitPath: false,}
         //handleActiveItemChange 数据el-cascader @change方法 'mycascader'就是获取vue DOM的方法
  handleActiveItemChange() {
            this.$nextTick(() => {
                if (this.$refs['mycascader'][0].getCheckedNodes().length > 0) {
                    let a = this.$refs['mycascader'][0].getCheckedNodes() //获取到选中值的node数据
                    let b = a[0].value.substring(0, 3) //根据选中的value值判断条件,可以换成别的值,比如层级字段,
                    let c = []
                    a.map((i) => {
                        if (i.value.substring(0, 3) == b) {
                            c.push({
                                organGrade: i.data.organGrade,
                                organCode: i.data.organCode,
                            })
                        }
                        return c
                    })
                    this.formInline.cascade = c
                }
            })
        },
  • 9
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值