前端tip

开始

git常用指令

git add .
git commit -m ""
git push origin 自己分支  提交自己的代码提交到自己的分支
git checkout dev   切换分支
git pull origin dev  (拉取dev最新代码)
git merge origin 自己分支  合并自己的代码到dev
git push origin dev (此时dev分支是最新的)
git checkotut 自己分支 切换到自己的分支
git merge dev  合并dev代码  完毕
git  创建分支步骤
git 创建自己的分支
git branck -b dhli
git push origin dhli
git fetch origin 仓库分支名称   关联远程仓库
git checkout -b 本地分支名称 origin 仓库分支名称  在本地新建分支关联远程仓库分支
git pull origin 本地分支名称 拉去这个分支的代码
:wq退出保存

1.使用 background-image实现渐变色边框,边框圆角

.box{
border: 4px solid transparent;
border-radius: 16px;
background-clip: padding-box, border-box;
background-origin: padding-box, border-box;
background-image: linear-gradient(to right, #222, #222), linear-gradient(90deg, #8F41E9, #578AEF);
}

2.动态边框

.box{
border-radius: 16px;
border: 10px solid;
border-image: linear-gradient(#8f41e9, #578aef,#ff5277)30 30;
animation: light 3s linear infinite;
}
@keyframes light {
0% {filter: hue-rotate(0deg);/*色调旋转*/}
20% {filter: hue-rotate(100deg);/*色调旋转*/}
40% {filter: hue-rotate(200deg);/*色调旋转*/}
100% {filter: hue-rotate(360deg);/*色调旋转*/}
}

3.监听事(当data数据中的对象发生变化时,进行相应的操作)

 watch: {
    //监听的对象
    searchForm: {
      deep: true,
      immediate: true,
      handler(nv) {
       //进行事件操作
        this.onSubmit();
      },
    },
  },

4.vue实现禁止浏览器网页缩放

// APP.vue文件中添加以下代码
 created() {
    window.addEventListener(
      "mousewheel",
      function (event) {
        if (event.ctrlKey === true || event.metaKey) {
          event.preventDefault();
        }
      },
      { passive: false }
    );
    //firefox
    window.addEventListener(
      "DOMMouseScroll",
      function (event) {
        if (event.ctrlKey === true || event.metaKey) {
          event.preventDefault();
        }
      },
      { passive: false }
    );
  },

5.封装video视频播放组件

可自定义设置以下属性:

  • 视频文件url(videoSrc),必传,支持网络地址https和相对地址require(‘…’)
  • 视频封面url(videoPoster),默认为null,支持网络地址https和相对地址require(‘…’)(在未设置封面且preload不等于none时,自动获取视频第0.3s对应帧作为封面图)
  • 视频播放器宽度(width),默认为800px
  • 视频播放器高度(height),默认为450px
  • 视频就绪后是否马上播放(autoplay),默认为false
  • 是否向用户显示控件,比如是否向用户显示控件,比如进度条,全屏等(controls),默认为true
  • 视频播放完成后,是否循环播放(loop),默认为false
  • 是否静音(muted),默认为false
  • 是否在页面加载后载入视频(preload)如果设置了autoplay属性,则preload将被忽略,默认为auto // auto:一旦页面加载,则开始加载视频; metadata:当页面加载后仅加载视频的元数据none:页面加载后不应加载视频
  • 播放暂停时是否显示播放器中间的暂停图标(showPlay),默认为false
  • 中间播放暂停按钮的边长(playWidth),默认为96px
  • video的poster默认图片和视频内容的缩放规则(zoom),默认为’none’ // none:(默认)保存原有内容,不进行缩放; fill:不保持原有比例,内容拉伸填充整个内容容器;
  • contain:保存原有比例,内容以包含方式缩放; cover:保存原有比例,内容以覆盖方式缩放

video组件

<template>
    <div class="m-video" :class="{'u-video-hover': !vplay}" :style="`width: ${width}px; height: ${height}px;`">
      <video
        ref="veo"
        :style="`object-fit: ${zoom};`"
        :src="videoSrc"
        :poster="poster"
        :width="width"
        :height="height"
        :autoplay="autoplay"
        :controls="!originPlay&&controls"
        :loop="loop"
        :muted="autoplay || muted"
        :preload="preload"
        crossorigin="anonymous"
        v-bind="$attrs"
        @loadeddata="poster ? e => e.preventDefault():getPoster()"
        @click.prevent.once="onPlay">
        您的浏览器不支持video标签。
      </video>
      <svg v-show="originPlay || showPlay" class="u-play" :class="{'hidden': vplay}" :style="`width: ${playWidth}px; height: ${playWidth}px;`" viewBox="0 0 24 24">
        <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M4.75 6.75C4.75 5.64543 5.64543 4.75 6.75 4.75H17.25C18.3546 4.75 19.25 5.64543 19.25 6.75V17.25C19.25 18.3546 18.3546 19.25 17.25 19.25H6.75C5.64543 19.25 4.75 18.3546 4.75 17.25V6.75Z"></path>
        <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M15.25 12L9.75 8.75V15.25L15.25 12Z"></path>
      </svg>
    </div>
  </template>
  <script>
  export default {
    name: 'Video',
    props: {
      videoSrc: { // 视频文件url,必传,支持网络地址 https 和相对地址 require('@/assets/files/Bao.mp4')
        type: String,
        required: true,
        default: null
      },
      videoPoster: { // 视频封面url,支持网络地址 https 和相对地址 require('@/assets/images/Bao.jpg')(在未设置封面且preload不等于none时,自动获取视频第0.3s对应帧作为封面图)
        type: String,
        default: null
      },
      width: { // 视频播放器宽度
        type: Number,
        default: 800
      },
      height: { // 视频播放器高度
        type: Number,
        default: 450
      },
      autoplay: { // 视频就绪后是否马上播放
        type: Boolean,
        default: false
      },
      controls: { // 是否向用户显示控件,比如进度条,全屏
        type: Boolean,
        default: true
      },
      loop: { // 视频播放完成后,是否循环播放
        type: Boolean,
        default: false
      },
      muted: { // 是否静音
        type: Boolean,
        default: false
      },
      preload: { // 是否在页面加载后载入视频,如果设置了autoplay属性,则preload将被忽略;
        type: String,
        default: 'auto' // auto:一旦页面加载,则开始加载视频; metadata:当页面加载后仅加载视频的元数据 none:页面加载后不应加载视频
      },
      showPlay: { // 播放暂停时是否显示播放器中间的暂停图标
        type: Boolean,
        default: false
      },
      playWidth: { // 中间播放暂停按钮的边长
        type: Number,
        default: 96
      },
      zoom: { // video的poster默认图片和视频内容缩放规则
        type: String,
        default: 'none' // none:(默认)保存原有内容,不进行缩放; fill:不保持原有比例,内容拉伸填充整个内容容器; contain:保存原有比例,内容以包含方式缩放; cover:保存原有比例,内容以覆盖方式缩放
      }
    },
    data () {
      return {
        poster: this.videoPoster,
        originPlay: true,
        vplay: false
      }
    },
    mounted () {
      if (this.showPlay) {
        this.$refs.veo.addEventListener('pause', this.onPause)
        this.$refs.veo.addEventListener('playing', this.onPlaying)
      }
      if (this.autoplay) {
        this.vplay = true
        this.originPlay = false
      }
      /*
        自定义设置播放速度,经测试:
        在vue2中需设置:this.$refs.veo.playbackRate = 2
        在vue3中需设置:veo.value.defaultPlaybackRate = 2
      */
      // this.$refs.veo.playbackRate = 2
    },
    methods: {
      /*
        loadeddata 事件在媒体当前播放位置的视频帧(通常是第一帧)加载完成后触发
        preload为none时不会触发
      */
      getPoster () { // 在未设置封面时,自动获取视频0.3s对应帧作为视频封面
        // 由于不少视频第一帧为黑屏,故设置视频开始播放时间为0.3s,即取该时刻帧作为封面图
        this.$refs.veo.currentTime = 0.3
        // 创建canvas元素
        const canvas = document.createElement('canvas')
        const ctx = canvas.getContext('2d')
        // canvas画图
        canvas.width = this.$refs.veo.videoWidth
        canvas.height = this.$refs.veo.videoHeight
        ctx.drawImage(this.$refs.veo, 0, 0, canvas.width, canvas.height)
        // 把canvas转成base64编码格式
        this.poster = canvas.toDataURL('image/png')
      },
      onPlay () {
        // eslint-disable-next-line no-console
        console.log('click')
        if (!this.autoplay) {
          this.vplay = true
          this.originPlay = false
          this.$refs.veo.play()
        } else {
          this.$refs.veo.pause()
        }
      },
      onPause () {
        this.vplay = false
       
        this.$once('hook:beforeDestroy', function () {
          removeEventListener('pause', this.onPause)
        })
      },
      onPlaying () {
        this.vplay = true
        
        // 自动清理自己,避免内存泄漏
        this.$once('hook:beforeDestroy', function () {
          removeEventListener('playing', this.onPlaying)
        })
      }
    }
  }
  </script>
  <style lang="less" scoped>
  .m-video {
    display: inline-block;
    position: relative;
    background: #000;
    cursor: pointer;
    .u-play {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      margin: auto;
      fill: none;
      color: #FFF;
      pointer-events: none;
      opacity: 0.7;
      transition: opacity .3s;
    }
    .hidden {
      opacity: 0;
    }
  }
  .u-video-hover {
    &:hover {
      .u-play {
        opacity: 0.9;
      }
    }
  }
  </style>

调用组件

 <Video :videoSrc="videoSrc" :videoPoster="videoPoster" :width="500" :height="300" :autoplay="false"
          :controls="true" :loop="false" :muted="false" preload="auto" :showPlay="true" :playWidth="96" zoom="contain" />
     videoSrc: '',//支持http链接 和本地视频地址.MP4
      videoPoster: '', //封面图片

6.Vue自定义拖拽指令

import Vue from 'vue'
Vue.directive('drag', (el) => {
  const oDiv = el // 当前元素
  const minTop = oDiv.getAttribute('drag-min-top')
  const ifMoveSizeArea = 20
  oDiv.onmousedown = e => {
    let target = oDiv
    while (window.getComputedStyle(target).position !== 'absolute' && target !== document.body) {
      target = target.parentElement
    }

    document.onselectstart = () => {
      return false
    }
    if (!target.getAttribute('init_x')) {
      target.setAttribute('init_x', target.offsetLeft)
      target.setAttribute('init_y', target.offsetTop)
    }

    const initX = parseInt(target.getAttribute('init_x'))
    const initY = parseInt(target.getAttribute('init_y'))

    // 鼠标按下,计算当前元素距离可视区的距离
    const disX = e.clientX - target.offsetLeft
    const disY = e.clientY - target.offsetTop
    document.onmousemove = e => {
      // 通过事件委托,计算移动的距离
      // 因为浏览器里并不能直接取到并且使用clientX、clientY,所以使用事件委托在内部做完赋值
      const l = e.clientX - disX
      const t = e.clientY - disY
      const { marginLeft : ml , marginTop : mt } =cwindow.getComputedStyle(target)
      // 计算移动当前元素的位置,并且给该元素样式中的left和top值赋值
      target.style.left = l - ml + 'px'
      target.style.top = (t < minTop ? minTop : t - mt) + 'px'
      if (Math.abs(l - initX) > ifMoveSizeArea || Math.abs(t - initY) > ifMoveSizeArea) {
        target.setAttribute('dragged', '')
      } else {
        target.removeAttribute('dragged')
      }
    }
    // eslint-disable-next-line no-unused-vars
    document.onmouseup = e => {
      document.onmousemove = null
      document.onmouseup = null
      document.onselectstart = null
    }
    // return false不加的话可能导致黏连,拖到一个地方时div粘在鼠标上不下来,相当于onmouseup失效
    return false
  }
})

7.Vue返回顶部(参考element ui 的返回顶部组件)

<template>
 <div>
  <div class="scroll" :class="{show:isActive}">
   <div id="toTop" @click="toTop(step)">&lt;</div>
   <div id="toBottom" @click="toBottom(step)">&gt;</div>
  </div>
 </div>
</template>
<script>
 export default{
  props:{
   step:{ //此数据是控制动画快慢的
    type:Number,
    default:50 
   }
  },
  data(){
   return {
    isActive:false,
   }
  },
  methods:{
   toTop(i){
    //参数i表示间隔的幅度大小,以此来控制速度
    document.documentElement.scrollTop-=i;
    if (document.documentElement.scrollTop>0) {
     var c=setTimeout(()=>this.toTop(i),16);
    }else {
     clearTimeout(c);
    }
   },
   toBottom(i){
    var clientHeight=document.documentElement.clientHeight||document.body.clientHeight;
    var scrollHeight=document.documentElement.scrollHeight;
    var height=scrollHeight-clientHeight; //超出窗口上界的值就是底部的scrolTop的值
    document.documentElement.scrollTop+=i;
    if (document.documentElement.scrollTop<height) {
     var c=setTimeout(()=>this.toBottom(i),16);
    }else {
     clearTimeout(c);
    }
   }
  },
  created(){
   var vm=this;
   window.οnscrοll=function(){
    if (document.documentElement.scrollTop>60) {
     vm.isActive=true;
    }else {
     vm.isActive=false;
    }
   }
  }
 }
</script>
<style scoped>
 .scroll{
   position: fixed;
   right: 10px;
   bottom: 60px;
   width: 45px;
   height: 90px;
   cursor: pointer;
   display: none;
  }
  .scroll>div{
   width: 45px;
   height: 45px;
   transform: rotate(90deg);
   line-height: 45px;
   text-align: center;
   font-size: 35px;
   font-family: "黑体";
   background-color: rgba(0,0,0,.2);
   color: #fff;
  }
  .scroll>div:hover{
   background-color: rgba(0,0,0,.5);
  }
  .show{
   display: block;
  }
</style>

8.echarts Demo集(https://www.isqqw.com/#/homepage)

9.按设计稿开发好固定尺寸的页面尺寸,然后根据各种分辨率进行放大缩小。

bodyScale() {
      var devicewidth = document.documentElement.clientWidth
      var scale = devicewidth / 1902
      document.body.style.zoom = scale
    }
    window.onresize = function(){
    this.bodyScale() 
    }

10.粒子特效全屏效果

html:
   <div class="animation-wrapper">
          <div class="particle particle-1"></div>
          <div class="particle particle-2"></div>
          <div class="particle particle-3"></div>
          <div class="particle particle-4"></div>
        </div>
css:

//以下为粒子背景---------
 /* Config */
 $color-bg: #111;
 $color-particle: #fff;
 $spacing: 3840px;
 $time-1: 60s;
 $time-2: 120s;
 $time-3: 180s;
 $time-4: 600s;

 /* Pauls awesome mixin */
 @function particles($max) {
     $val: 0px 0px $color-particle;

     @for $i from 1 through $max {
         $val: #{$val},
         random($spacing)+px random($spacing)+px $color-particle;
     }

     @return $val;
 }

 @mixin particles($max) {
     box-shadow: particles($max);
 }

 /* Styles */

 .animation-wrapper {
     position: absolute;
     top: 0;
     left: 0;
     width: 100%;
     height: 100%;
    //  z-index: 1;
 }

 .particle,
 .particle:after {
     background: transparent;
 }

 .particle:after {
     position: absolute;
     content: "";
     top: $spacing;
 }

 .particle-1 {
     animation: animParticle $time-1 linear infinite;
     @include particles(600);
     height: 1px;
     width: 1px;
 }

 .particle-1:after {
     @include particles(600);
     height: 1px;
     width: 1px;
 }

 .particle-2 {
     animation: animParticle $time-2 linear infinite;
     @include particles(300);
     height: 2px;
     width: 2px;
 }

 .particle-2:after {
     @include particles(300);
     height: 2px;
     width: 2px;
 }

 .particle-3 {
     animation: animParticle $time-3 linear infinite;
     @include particles(200);
     height: 3px;
     width: 3px;
 }

 .particle-3:after {
     @include particles(200);
     height: 3px;
     width: 3px;
 }

 .particle-4 {
     animation: animParticle $time-4 linear infinite;
     @include particles(400);
     height: 1px;
     width: 1px;
 }

 .particle-4:after {
     @include particles(400);
     height: 1px;
     width: 1px;
 }

 @keyframes animParticle {
     from {
         transform: translateY(0px);
     }

     to {
         transform: translateY($spacing * -1);
     }
 }

 //以上为粒子背景---------

11.文件导出通用方法(后端返回文件流)

// 文件导出 通用方法 
// blob  文件流
// tagFileName  文件名称
// fileType  文件格式 xsl xlsx
export function downloadExportFile(blob, tagFileName, fileType) {
  var downloadElement = document.createElement('a')
  var href = blob.data
  if (typeof blob.data == 'string') {
      downloadElement.target = '_blank'
  } else {
      href = window.URL.createObjectURL(blob.data) //创建下载的链接
  }
  downloadElement.href = href
  if (fileType) {
      downloadElement.download = tagFileName + '.' + fileType //下载后文件名
  } else {
      downloadElement.download = tagFileName //下载后文件名
  }

  document.body.appendChild(downloadElement)
  downloadElement.click()
  //点击下载
  document.body.removeChild(downloadElement) //下载完成移除元素
  if (typeof blob != 'string') {
      window.URL.revokeObjectURL(href) //释放掉blob对象
  }
}

12.各种正则验证方法

在这里插入代码片

/* 邮箱是否为空 */
export function isNullEmail(str) {
    const reg = /^[A-Za-z\d]+([-_.][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}$/i;
    return reg.test(str);
}

/* 数字 */
export function validateNumber(str) {
    var reg = /^[0-9]*$/
    return reg.test(str)
}

/* 验证:输入的数字长度验证
   格式:"6,10"
*/
export function validateNumberLength(str, range) {
    var ranges = range.split(",")
    var low = ranges[0] == "," ? 0 : parseInt(ranges[0])
    var high = ranges[1] == '' ? '' : parseInt(ranges[1])
    var reg = eval("/^\\d{" + low + "," + high + "}$/;");
    return reg.test(str);
}

/* 手机号*/
export function validatePhone(str) {
    const reg = /^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1}))+\d{8})$/;
    return reg.test(str);
}

/* 是否是邮箱*/
export function isWscnEmail(str) {
    const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
    return reg.test(str.trim());
}

/* 合法uri*/
export function validateURL(textval) {
    const urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/;
    return urlregex.test(textval);
}

/* 小写字母*/
export function validateLowerCase(str) {
    const reg = /^[a-z]+$/;
    return reg.test(str);
}

/* 大写字母*/
export function validateUpperCase(str) {
    const reg = /^[A-Z]+$/;
    return reg.test(str);
}

/* 大小写字母*/
export function validatAlphabets(str) {
    const reg = /^[A-Za-z]+$/;
    return reg.test(str);
}

/* 特殊字符正则*/
export function validatSpecialChar(str) {
    const reg = /[`~!@#$%^&*()_\-+=<>?:"{}|,.\/;'\\[\]·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、\u4E00-\u9FA5]/g;
    return reg.test(str);
}

/* 特殊字符正则可包含中英文括号和汉字*/
export function validatSpecialCharNoBracket(str) {
    const reg = /[`~!@#$%^&*_\-+=<>?:"{}|,.\/;'\\[\]·~!@#¥%……&*——\-+={}|《》?:“”【】、;‘’,。、]/g;
    return reg.test(str);
}

/* 特殊字符正则可包含英文逗号*/
export function validatSpecialCharNoComma(str) {
    const reg = /[`~!@#$%^&*()_\-+=<>?:"{}|.\/;'\\[\]·~!@#¥%……&*()——\-+={}|《》?:“”【】、;‘’,。、\u4E00-\u9FA5]/g;
    return reg.test(str);
}

/*身份证号码校验*/
export function validatIdNumfunction(value) {
  // 1.传入15位或者18位身份证号码,18位号码末位可以为数字或X
  var idCard = value;
  // 2.身份证中的X,必须是大写的
  if (value.indexOf("x") !== -1) {
    return false;
  }
  // 3.判断输入的身份证长度
  if (!(/(^\d{15}$)|(^\d{17}([0-9]|X)$)/.test(idCard))) {
    return false;
  }
  // 4.验证前两位城市编码是否正确
  var aCity = {
    11: "北京", 12: "天津", 13: "河北", 14: "山西", 15: "内蒙古", 21: "辽宁", 22: "吉林", 23: "黑龙江",
    31: "上海", 32: "江苏", 33: "浙江", 34: "安徽", 35: "福建", 36: "江西", 37: "山东", 41: "河南", 42: "湖北",
    43: "湖南", 44: "广东", 45: "广西", 46: "海南", 50: "重庆", 51: "四川", 52: "贵州", 53: "云南", 54: "西藏",
    61: "陕西", 62: "甘肃", 63: "青海", 64: "宁夏", 65: "新疆", 71: "台湾", 81: "香港", 82: "澳门", 91: "国外"
  };
  if (aCity[parseInt(idCard.substr(0, 2))] == null) {
    return false;
  }
  // 5.验证出生日期和校验位
  if (validId15(idCard) || validId18(idCard)) {
    return true;
  } else {
    return false;
  }

  // 身份证18位号码验证
  function validId18(str) {
    if (str.length != 18) {
      return false;
    }
    //1. 出生日期验证
    var re = new RegExp(/^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$/);
    var arrSplit = str.match(re); //检查生日日期是否正确
    if (arrSplit != null) {
      if (!YearMonthDayValidate(arrSplit[2], arrSplit[3], arrSplit[4])) {
        return false;
      }
    } else {
      return false;
    }
    //2. 校验位验证
    var iW = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1);//加权因子
    var iSum = 0;
    for (var i = 0; i < 17; i++) {
      var iC = str.charAt(i);
      var iVal = parseInt(iC);
      iSum += iVal * iW[i];
    }
    var iJYM = iSum % 11;//取模
    var sJYM = '';
    //获取的模查找对应的校验码字符值
    if (iJYM == 0) sJYM = "1";
    else if (iJYM == 1) sJYM = "0";
    else if (iJYM == 2) sJYM = "x";
    else if (iJYM == 3) sJYM = "9";
    else if (iJYM == 4) sJYM = "8";
    else if (iJYM == 5) sJYM = "7";
    else if (iJYM == 6) sJYM = "6";
    else if (iJYM == 7) sJYM = "5";
    else if (iJYM == 8) sJYM = "4";
    else if (iJYM == 9) sJYM = "3";
    else if (iJYM == 10) sJYM = "2";
    var cCheck = str.charAt(17).toLowerCase();
    if (cCheck != sJYM) {
      return false;
    }
    return true;
  }

  // 身份证15位(1984-2004)身份验证
  function validId15(str) {
    if (str.length != 15) {
      return false;
    }
    //1. 出生日期验证
    var re = new RegExp(/^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})$/);
    var arrSplit = str.match(re); //检查生日日期是否正确
    if (arrSplit != null) {
      if (parseInt(arrSplit[2].substr(1)) > 0) {
        arrSplit[2] = "19" + arrSplit[2];
      } else {
        arrSplit[2] = "20" + arrSplit[2]
      }
      if (!YearMonthDayValidate(arrSplit[2], arrSplit[3], arrSplit[4])) {
        return false;
      }
    } else {
      return false;
    }
    return true;
  }

  //出生日期的年月日验证
  function YearMonthDayValidate(year, month, day) {
    year = parseInt(year); //年
    month = parseInt(month);//月
    day = parseInt(day);//日
    //判断年,月,日是否为空
    if (isNaN(year) || isNaN(month) || isNaN(day)) {
      return false;
    }
    //判断月是否是在1-12月之间
    if (month < 1 || month > 12) {
      return false;
    }
    //返回当月的最后一天
    var date = new Date(year, month, 0);
    //判断是否超过天数范围
    if (day < 1 || day > date.getDate()) {
      return false;
    }
    return true;
  }

}


/* 校验 当前年份  - 输入年份(year) < ( n)
* 通过返回 true 不通过 返回 false
* */
export function validateBegainYear(year,n) {
  let currentYear = new Date().getFullYear();
  if ((currentYear - parseInt(year)) >=0 && (currentYear - parseInt(year)) <= n ){
    return true
  }else {
    return false
  }
}
/**
 * Object是否为空
 * @param {*对象} object
 */
export function objIsEmpty(object) {
    return object === undefined ||
        object === null ||
        JSON.stringify(object) === '{}'
}
/**
 * $ref去重
 */
export function refRemove(key, json) {
    let keyArr = key.split('.')
    keyArr.splice(0, 1)
    let obj = {...json }
    if (keyArr.length > 0) {
        keyArr.forEach((item) => {
            if (item.indexOf('[') !== -1) {
                let itemStr = item.replace(']', '')
                let itemArr = itemStr.split('[')
                obj = obj[itemArr[0]][itemArr[1]]
            } else {
                obj = obj[item]
            }
        })
    }
    return obj
}

13. 3D词云动画效果

这是svg3dtag.js

/*
 * Copyright (c) 2017 Niklas Knaack
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
var textLabel = ''
!(function() {
  function t(t, e) {
    function o() {
      (F = document.createElementNS(N, "svg")),
        F.addEventListener("mousemove", v),
        t.appendChild(F),
        x.bgDraw &&
          ((D = document.createElementNS(N, "rect")),
          D.setAttribute("x", 0),
          D.setAttribute("y", 0),
          D.setAttribute("fill", x.bgColor),
          F.appendChild(D)),
        a(),
        i(),
        h(),
        window.addEventListener("resize", b);
    }
    function i() {
      var e =
          window.innerWidth ||
          document.documentElement.clientWidth ||
          document.body.clientWidth,
        o =
          window.innerHeight ||
          document.documentElement.clientHeight ||
          document.body.clientHeight,
        i = e,
        r = o;
      x.width.toString().indexOf("%") > 0 ||
      x.height.toString().indexOf("%") > 0
        ? ((i = Math.round((t.offsetWidth / 100) * parseInt(x.width))),
          (r = Math.round((i / 100) * parseInt(x.height))))
        : ((i = parseInt(x.width)), (r = parseInt(x.height))),
        i >= e && (i = e),
        r >= o && (r = o),
        (P = {
          x: i / 2,
          y: r / 2,
        }),
        (E.x = x.speed / P.x),
        (E.y = x.speed / P.y),
        (S =
          i >= r
            ? (r / 100) * parseInt(x.radius)
            : (i / 100) * parseInt(x.radius)),
        1 > S && (S = 1),
        (C = S / 2),
        C < x.radiusMin && ((C = x.radiusMin), (S = 2 * C)),
        F.setAttribute("width", i),
        F.setAttribute("height", r),
        x.bgDraw && (D.setAttribute("width", i), D.setAttribute("height", r)),
        n(C);
    }
    function n(t) {
      for (var e = 0, o = z.length; o > e; e++) r(z[e], t);
    }
    function r(t, e) {
      var o = t.vectorPosition.x - O.x,
        i = t.vectorPosition.y - O.y,
        n = t.vectorPosition.z - O.z,
        r = Math.sqrt(o * o + i * i + n * n);
      (t.vectorPosition.x /= r),
        (t.vectorPosition.y /= r),
        (t.vectorPosition.z /= r),
        (t.vectorPosition.x *= e),
        (t.vectorPosition.y *= e),
        (t.vectorPosition.z *= e);
    }
    function s(t, e, o, i, n) {
      var r = {};
      return (
        "undefined" != typeof e.label
          ? ((r.element = document.createElementNS(N, "text")),
            r.element.setAttribute("x", 0),
            r.element.setAttribute("y", 0),
            r.element.setAttribute(
              "fill",
              e.fontColor == null ? x.fontColor : e.fontColor
            ),
            r.element.setAttribute(
              "font-family",
              e.fontFamily == null ? x.fontFamily : e.fontFamily
            ),
            r.element.setAttribute(
              "font-size",
              e.fontSize == null ? x.fontSize : e.fontSize
            ),
            r.element.setAttribute(
              "font-weight",
              e.fontWeight == null ? x.fontWeight : e.fontWeight
            ),
            r.element.setAttribute(
              "font-style",
              e.fontStyle == null ? x.fontStyle : e.fontStyle
            ),
            r.element.setAttribute(
              "font-stretch",
              e.fontStretch == null ? x.fontStretch : e.fontStretch
            ),
            r.element.setAttribute("text-anchor", "middle"),
            (r.element.textContent = x.fontToUpperCase
              ? e.label.toUpperCase()
              : e.label))
          : "undefined" != typeof e.image &&
            ((r.element = document.createElementNS(N, "image")),
            r.element.setAttribute("x", 0),
            r.element.setAttribute("y", 0),
            r.element.setAttribute("width", e.width),
            r.element.setAttribute("height", e.height),
            r.element.setAttribute("id", "image_" + t),
            r.element.setAttributeNS(
              "http://www.w3.org/1999/xlink",
              "href",
              e.image
            ),
            (r.diffX = e.width / 2),
            (r.diffY = e.height / 2)),
        (r.link = document.createElementNS(N, "a")),
        r.link.setAttributeNS(
          "http://www.w3.org/1999/xlink",
          "xlink:href",
          e.url
        ),
        r.link.setAttribute("target", e.target),
        r.link.setAttribute("class", e.class),
        r.link.addEventListener("mouseover", m, !0),
        r.link.addEventListener("mouseout", y, !0),
        r.link.appendChild(r.element),
        "undefined" != typeof e.tooltip
          ? ((r.tooltip = !0),
            (r.tooltipLabel = x.tooltipFontToUpperCase
              ? e.tooltip.toUpperCase()
              : e.tooltip))
          : (r.tooltip = !1),
        (r.index = t),
        (r.mouseOver = !1),
        (r.vectorPosition = {
          x: o,
          y: i,
          z: n,
        }),
        (r.vector2D = {
          x: 0,
          y: 0,
        }),
        F.appendChild(r.link),
        r
      );
    }
    function a() {
      for (var t = !1, e = 1, o = x.entries.length + 1; o > e; e++) {
        var i = Math.acos(-1 + (2 * e) / o),
          n = Math.sqrt(o * Math.PI) * i,
          r = Math.cos(n) * Math.sin(i),
          a = Math.sin(n) * Math.sin(i),
          u = Math.cos(i),
          c = s(e - 1, x.entries[e - 1], r, a, u);
        z.push(c), "undefined" != typeof x.entries[e - 1].tooltip && (t = !0);
      }
      t && l();
    }
    function l() {
      (w = document.createElementNS(N, "text")),
        w.setAttribute("x", 0),
        w.setAttribute("y", 0),
        w.setAttribute("fill", x.tooltipFontColor),
        w.setAttribute("font-family", x.tooltipFontFamily),
        w.setAttribute("font-size", x.tooltipFontSize),
        w.setAttribute("font-weight", x.tooltipFontWeight),
        w.setAttribute("font-style", x.tooltipFontStyle),
        w.setAttribute("font-stretch", x.tooltipFontStretch),
        w.setAttribute("text-anchor", x.tooltipTextAnchor),
        (w.textContent = ""),
        F.appendChild(w);
    }
    function u(t) {
      for (var e = 0, o = z.length; o > e; e++) {
        var i = z[e];
        if (
          i.element.getAttribute("x") === t.getAttribute("x") &&
          i.element.getAttribute("y") === t.getAttribute("y")
        )
          return i;
      }
    }
    function c(t) {
      for (var e = 0, o = z.length; o > e; e++) {
        var i = z[e];
        i.index === t.index ? (i.mouseOver = !0) : (i.mouseOver = !1);
      }
    }
    function f(t) {
      t.tooltip &&
        (w.setAttribute("x", t.vector2D.x - x.tooltipDiffX),
        w.setAttribute("y", t.vector2D.y - x.tooltipDiffY),
        (w.textContent = x.tooltipFontToUpperCase
          ? t.tooltipLabel.toUpperCase()
          : t.tooltipLabel),
        w.setAttribute("opacity", 1));
    }
    function d(t) {
      w.setAttribute("opacity", 0);
    }
    function p() {
      var t = E.x * T.x - x.speed,
        e = x.speed - E.y * T.y,
        o = t * I,
        i = e * I;
      (k.sx = Math.sin(o)),
        (k.cx = Math.cos(o)),
        (k.sy = Math.sin(i)),
        (k.cy = Math.cos(i));
      for (var n = 0, r = z.length; r > n; n++) {
        var s = z[n];
        if (M) {
          var a = s.vectorPosition.x,
            l = s.vectorPosition.y * k.sy + s.vectorPosition.z * k.cy;
          (s.vectorPosition.x = a * k.cx + l * k.sx),
            (s.vectorPosition.y =
              s.vectorPosition.y * k.cy + s.vectorPosition.z * -k.sy),
            (s.vectorPosition.z = a * -k.sx + l * k.cx);
        }
        var u = x.fov / (x.fov + s.vectorPosition.z);
        (s.vector2D.x = s.vectorPosition.x * u + P.x),
          (s.vector2D.y = s.vectorPosition.y * u + P.y),
          s.diffX &&
            s.diffY &&
            ((s.vector2D.x -= s.diffX), (s.vector2D.y -= s.diffY)),
          s.element.setAttribute("x", s.vector2D.x),
          s.element.setAttribute("y", s.vector2D.y);
        var c;
        M
          ? ((c = (C - s.vectorPosition.z) / S),
            c < x.opacityOut && (c = x.opacityOut))
          : ((c = parseFloat(s.element.getAttribute("opacity"))),
            (c += s.mouseOver
              ? (x.opacityOver - c) / x.opacitySpeed
              : (x.opacityOut - c) / x.opacitySpeed)),
          s.element.setAttribute("opacity", c);
      }
      z = z.sort(function(t, e) {
        return e.vectorPosition.z - t.vectorPosition.z;
      });
    }
    function h() {
      requestAnimFrame(h), p();
    }
    function m(t) {
      M = !1;
      var e = u(t.target);
      c(e), e.tooltip && f(e);
    }
    function y(t) {
      M = !0;
      var e = u(t.target);
      e.tooltip && d(e);
    }
    function v(t) {
      T = g(F, t);
    }
    function g(t, e) {
      var o = t.getBoundingClientRect();
      return {
        x: e.clientX - o.left,
        y: e.clientY - o.top,
      };
    }
    function b(t) {
      i();
    }
    var x = {
      entries: [],
      width: 360,
      height: 250,
      radius: "70%",
      radiusMin: 75,
      bgDraw: !0,
      bgColor: "#000",
      opacityOver: 1,
      opacityOut: 0.05,
      opacitySpeed: 6,
      fov: 800,
      speed: 2,
      fontFamily: "Arial, sans-serif",
      fontSize: "15",
      fontColor: "#fff",
      fontWeight: "normal",
      fontStyle: "normal",
      fontStretch: "normal",
      fontToUpperCase: !1,
      tooltipFontFamily: "Arial, sans-serif",
      tooltipFontSize: "15",
      tooltipFontColor: "#fff",
      tooltipFontWeight: "normal",
      tooltipFontStyle: "normal",
      tooltipFontStretch: "normal",
      tooltipFontToUpperCase: !1,
      tooltipTextAnchor: "left",
      tooltipDiffX: 0,
      tooltipDiffY: 10,
    };
    if (void 0 !== e)
      for (var A in e)
        e.hasOwnProperty(A) && x.hasOwnProperty(A) && (x[A] = e[A]);
    if (!x.entries.length) return !1;
    var w,
      C,
      S,
      P,
      F,
      D,
      z = [],
      M = !0,
      T = {
        x: 0,
        y: 0,
      },
      O = {
        x: 0,
        y: 0,
        z: 0,
      },
      E = {
        x: 0,
        y: 0,
      },
      k = {
        sx: 0,
        cx: 0,
        sy: 0,
        cy: 0,
      },
      I = Math.PI / 180,
      N = "http://www.w3.org/2000/svg";
    (window.requestAnimFrame = (function() {
      return (
        window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        function(t) {
          window.setTimeout(t, 1e3 / 60);
        }
      );
    })()),
      o();
  }
  window.SVG3DTagCloud = t;
})(),
  "undefined" != typeof jQuery &&
    !(function(t) {
      t.fn.svg3DTagCloud = function(e) {
        var o = arguments;
        return this.each(function() {
          if (t.data(this, "plugin_SVG3DTagCloud")) {
            var i = t.data(this, "plugin_SVG3DTagCloud");
            i[e]
              ? i[e].apply(this, Array.prototype.slice.call(o, 1))
              : t.error(
                  "Method " + e + " does not exist on jQuery.svg3DTagCloud"
                );
          } else t.data(this, "plugin_SVG3DTagCloud", new SVG3DTagCloud(this, e));
        });
      };
    })(jQuery);

页面中运用

<template>
  <div id="impexpCategoriesCharts" ref="impexpCategoriesCharts"
    style="width:100%;height:100%;position: relative;z-index: 999;"></div>
</template>

<script>
import './svg3dtagcloud.min.js'
export default {
  name: "impexpCategoriesCharts",
  components: {},
  props: {
    chartData: {
      type: Object,
      default() {
        return {
          seriesData: [
            { value: "50", name: "电子产品" }, // 50
            { value: "30", name: "服装及配饰" },
            { value: "29", name: "机械设备" },
            { value: "28", name: "化工产品" },
            { value: "27", name: "音箱设备及影视制品" },
            { value: "26", name: "车辆及零配件" },
            { value: "25", name: "塑料制品" },
            { value: "24", name: "包装材料" },
            { value: "23", name: "纸制品" },
          ],
        };
      },
    },
  },
  watch: {
    chartData: {
      deep: true,
      handler(val) {
        document.getElementById('impexpCategoriesCharts').innerHTML = ''
        this.initChart(val.seriesData);
      },
    },
  },
  data() {
    return {
      chart: null,
      textLabel: ''
    };
  },
  mounted() {
    this.$nextTick(() => {
      document.getElementById('impexpCategoriesCharts').innerHTML = ''
      this.initChart(this.chartData.seriesData);
    });
  },
  methods: {
    initChart(chartData) {
      this.chart = document.getElementById('impexpCategoriesCharts')
      var entries = [
        //这里的fontColor设置字体颜色,fontSize设置字体大小,还有fontFamily,fontWeight,fontStyle,fontStretch这几个属性,做什么就自己研究吧
        { label: '郁闷', fontColor: '#00E2FF', fontSize: 40, url: '#', target: '_top', class: 'id1' },
        { label: '慌张', fontColor: '#C0C4CC',fontSize: 36, url: '#', target: '_top', class: 'id1' },
        { label: '惊讶', fontColor: '#287CE8',fontSize: 30, url: '#', target: '_top', class: 'id1' },
        { label: '棒棒哒', fontColor: '#3F6ADF',fontSize: 28, url: '#', target: '_top', class: 'id1' },
        { label: '很有趣', fontColor: '#41E4DE',fontSize: 26, url: '#', target: '_top', class: 'id1' },
        { label: '还行', fontColor: '#41E4DE', url: '#',fontSize: 25, target: '_top', class: 'id1' },
        { label: '污染严重', fontColor: '#3F6ADF', url: '#',fontSize: 24, target: '_top', class: 'id1' },
        { label: '有帮助', fontColor: '#287CE8', url: '#', fontSize: 23,target: '_top', class: 'id1' },
        { label: '能走', fontColor: '#C0C4CC', url: '#',fontSize: 22, target: '_top', class: 'id1' },
        { label: '能走', fontColor: '#00E2FF', url: '#',fontSize: 21, target: '_top', class: 'id1' },
      ]
      let entries1 = []
      let sizeArr = [40,36,30,28,26,25,24,23,22,21,20]
      let colorArr=['#00E2FF','#C0C4CC','#287CE8','#3F6ADF','#41E4DE','#41E4DE','#3F6ADF','#287CE8','#C0C4CC','#00E2FF',]
      chartData.forEach((ele,index) => {
        entries1.push({label: ele.name, fontColor: colorArr[index], fontSize: sizeArr[index], url: '#', target: '_top', class: 'id1' })
      });
      entries = entries1
      var settings = {
        class: 'mySvg',
        entries: entries,//数据
        width: 400,//宽度
        height: 250,//高度
        radius: '80%',
        radiusMin: 75,
        bgDraw: false,//是否显示背景
        bgColor: '#AFEEEE',//背景颜色
        opacityOver: 1.00,
        opacityOut: 0.2,
        opacitySpeed: 6,
        fov: 800,
        speed: 0.4,//旋转的速度
        fontFamily: 'Oswald, Arial, sans-serif',
        fontSize: '18',//默认字体大小
        fontColor: '#00E2FF',//默认字体颜色
        fontWeight: 'normal',//bold
        fontStyle: 'normal',//italic 
        fontStretch: 'normal',//wider, narrower, ultra-condensed, extra-condensed, condensed, semi-condensed, semi-expanded, expanded, extra-expanded, ultra-expanded
        fontToUpperCase: true,
        tooltipFontFamily: 'Oswald, Arial, sans-serif',
        tooltipFontSize: '32',
        tooltipFontColor: 'red',
        tooltipFontWeight: 'normal',//bold
        tooltipFontStyle: 'normal',//italic 
        tooltipFontStretch: 'normal',//wider, narrower, ultra-condensed, extra-condensed, condensed, semi-condensed, semi-expanded, expanded, extra-expanded, ultra-expanded
        tooltipFontToUpperCase: false,
        tooltipTextAnchor: 'left',
        tooltipDiffX: 0,
        tooltipDiffY: 10
      };
      new SVG3DTagCloud(this.chart, settings)
      var arr = []
      arr = Array.from(document.getElementsByClassName('id1'))
      arr.map(item => {
        item.addEventListener("click", (e) => {
          this.textLabel = e.target.innerHTML
          this.$emit('changeTextLabel', e.target.innerHTML)
        })
      })
    },
  },
};
</script>

<style lang="scss" scoped></style>

14. 仿element的弹窗点击空白区域弹窗消失

 //假如这是一个弹窗元素
 <div class="wordModel" ref="wordModel" v-if="wordModelShow">
 </div>
//给弹窗设置一个ref名称比如ref="maskModel"
 mounted() {
    document.addEventListener("mouseup",this.bodyCloseMenus);
  },
  beforeDestroy() {
    document.removeEventListener("click", this.bodyCloseMenus);
  },
//监听事件传入事件event
bodyCloseMenus (event){
	if(!this.$refs.wordModel && !this.$refs.maskModel.contains(event.target)){
		this.wordModelShow= false	
	}
}

15.base64转成file对象

// 先将base64字符串转换为二进制数据
base64ToBlob(base64String, mimeType = 'image/png') {
  const byteCharacters = atob(base64String.split(',')[1]);
  const byteArrays = [];
  for (let offset = 0; offset < byteCharacters.length; offset += 1024) {
    const slice = byteCharacters.slice(offset, offset + 1024);
    const byteNumbers = new Array(slice.length);
    for (let i = 0; i < slice.length; i++) {
      byteNumbers[i] = slice.charCodeAt(i);
    }
    const byteArray = new Uint8Array(byteNumbers);
    byteArrays.push(byteArray);
  }
  return new Blob(byteArrays, {type: mimeType});
}// 将Blob转换为File对象
base64ToFile(base64String, fileName, mimeType = 'image/png') {
  // 先转换为Blob
  const blob = base64ToBlob(base64String, mimeType);
  // 然后将Blob转换为File对象
  return new File([blob], fileName, {type: mimeType});
}

16.解决html2canvas截图截不到svg的问题

	// 下载依赖 ---- 版本
	"canvg": "^1.5.3",
	 "html2canvas": "^1.4.1",
   // 引入两个依赖
   import html2canvas from "html2canvas";
   import canvg from "canvg";
	//传入一个要截图的容器id
	 getContainerImg(containerId) {
      const el = document.getElementById("containerId");
      //Svgdom数组
      var fileUrl = "";
      let svgNodesToRemove = [];
      // 获取到所有的SVG 得到一个数组
      let svgElements = document.body.querySelectorAll("#containerId svg");
      // 遍历这个数组
      svgElements.forEach(function (item) {
        let children = item.childNodes;
        // 处理 SVG子节点  children 透明度
        children.forEach(function (child) {
          //解决svg透明度问题
          child.style.opacity = 1;
        });
        //去除空白字符
        let svg = item.outerHTML.trim();
        // 创建一个 canvas DOM元素
        let canvas = document.createElement("canvas");
        //设置 canvas 元素的宽高
        canvas.width = item.getBoundingClientRect().width;
        canvas.height = item.getBoundingClientRect().height;
        // 将 SVG转化 成 canvas
        canvg(canvas, svg);
        //设置生成 canvas 元素的坐标  保证与原SVG坐标保持一致
        if (item.style.position) {
          canvas.style.position += item.style.position;
          canvas.style.left += item.style.left;
          canvas.style.top += item.style.top;
        }
        //添加到 你需要截图的DOM节点中
        item.parentNode.appendChild(canvas);
        // 删除这个元素
        svgNodesToRemove.push(canvas);
      });
      const width = el.offsetWidth;
      const height = el.offsetHeight;
      let canvas = html2canvas(el, {
        allowTaint: true,
        useCORS: true,
        scale: 2,
        logging: false,
        width: width,
        height: height ,
        windowWidth: width,
        windowHeight: height ,
      });
      const screenShot = canvas.then((canvas) => {
        return canvas.toDataURL("image/jpg");
      });
      // 这一步一定要放在生成截图之后 ----- 删除增加的canvas元素
      document.querySelectorAll("#flowContent canvas").forEach((item) => {
        item.remove();
      });
      return screenShot;
    },

	// 这个方法返回的是一个promise对象,所以接收时可以这样写:
	 this.getContainerImg().then((res) => {
	 console.log(res)
	 // 这个res就是截的图,文件格式是base64
	 })

17.Vue实现排序功能组件:升序、降序

<template>
  <div class="sort-box" @click="changeSort">
    <div :style="{ cursor: isCursor }">{{ name }}</div>
    <div class="sort-con">
      <div class="s-item" :class="{ active: currentDesc == item.name }" v-for="(item, index) in sortIconList" :key="index">
        <i :class="`iconfont ${item.icon}`"></i>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'BaseSort',
  props: {
    currentDesc: {
      type: String,
      required: true,
      default: '',
    },
    name: {
      type: String,
      default: '',
    },
    isCursor: {
      type: String,
      default: 'pointer',
    },
  },
  data() {
    return {
      isActive: 0,
      sortIconList: [
        {
          name: 'asc',
          icon: 'icon-shengxu',
        },
        {
          name: 'desc',
          icon: 'icon-jiangxu',
        },
      ],
    }
  },
  methods: {
    changeSort(index) {
      this.$emit('changeSort', this.currentDesc)
    },
  },
  created() {},
  watch: {},
}
</script>

<style lang="scss" scoped>
.sort-box {
  display: flex;
  align-items: center;
}
.sort-con {
  .s-item {
    cursor: pointer;
    position: relative;

    i {
      font-size: 13px;
    }
    &.active {
      i {
        color: #67e5ff;
      }
    }
  }
  .s-item:first-child {
    height: 14px;
  }
}
</style>

在页面上调用:

<template>
	<base-sort :name="'次数'" :currentDesc="currentDesc" @changeSort="changeSort"></base-sort>
</template>
<script>
export default {
	data() {
	  return{
	  	currentDesc: 'desc',
	  }
	},
	methods:{
	  changeSort(val) {
	      this.currentDesc = val === 'asc' ? 'desc' : 'asc'
	  },
	}
}
</script>

18.Vue实现获取本周、本月、本季度、本年

	getDate(){
	  let today = new Date();
      let year = today.getFullYear();
      let month = today.getMonth();
      let day = today.getDate();
 	  let quarter = Math.floor(month / 3);
 	  //当天
      let startDay = new Date(today.getFullYear(), today.getMonth(), today.getDate());
      let endDay = new Date(new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1) - 1);
      //本月
      let startMonth = new Date(year, month, 1);
      let endMonth = new Date(year, month + 1, 0);
      //本季度
      let startQuarter = new Date(year, quarter * 3, 1);
      let endQuarter = new Date(year, quarter * 3 + 3, 1);
      //本年
      let startYear = new Date(year, 0, 1);
      let endYear = new Date(year, 11, 31);
      //本周
      let startWeek = new Date(today.getFullYear(), today.getMonth(), today.getDate() - today.getDay() + 1);
      let endWeek = new Date(today.getFullYear(), today.getMonth(), today.getDate() - today.getDay() + 7);
      return [startWeek,endWeek  ]
      }
     // 格式化时间
    formatChinaStandardTime(date) {
      const year = date.getFullYear();
      const month = ("0" + (date.getMonth() + 1)).slice(-2); // getMonth返回的月份是从0开始的,所以需要+1
      const day = ("0" + date.getDate()).slice(-2);
      const hours = ("0" + date.getHours()).slice(-2);
      const minutes = ("0" + date.getMinutes()).slice(-2);
      const seconds = ("0" + date.getSeconds()).slice(-2);
      return `${year}-${month}-${day}`;
    },
    //调用
    this.formatChinaStandardTime(this.getDate())

19.Vue批量上传

 <input ref="fileInput" type="file" multiple :accept="inputFileType" @input="handleFileChange" 
 style="display: none">
 // 文件上传接收的格式
 inputFileType: '.csv,.xlsx,application/vnd.ms-excel',
uploadFile() {
        this.$refs.fileInput.click();
},
handleFileChange(evt) {
        let files = this.$refs.fileInput.files
        if (files.length + this.fileList.length > 5) {
          this.$pop({
            type: 'warning',
            message: '最多上传5个文件'
          })
          return
        }
        let that = this
        for (var i = 0; i < files.length; i++) {
          var file = files[i]
          //文件格式校验
          let fileType = file.name.split('.')[1];
            if (fileType != 'xls' && fileType != 'xlsx' && fileType != 'csv') {
              that.$pop({
                message: "请检查文件格式",
                type: "warning"
              });
              return;
            }
          if (file.size > sizeM) {
            that.$pop({
              message: "文件大于 20M,不能上传!",
              type: "warning"
            });
          }
          that.fileList.push({
            name: file.name,
            binFile: file
          })
        }
  },

    if (this.fileList[0].type == 'application/pdf') {
                this.pdfImg = false
                const blob = new Blob([this.fileList[0]], { type: "application/pdf" })
                this.PdfUrl = window.URL.createObjectURL(blob)
            } else {
                this.pdfImg = true
                const blob = new Blob([this.fileList[0]], { type: "application/pdf,image/png,image/jpeg,image/jpg" })
                this.PdfUrl = window.URL.createObjectURL(blob)
            }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值