js常用函数封装和vue开发小技巧(持续添加)

拖拽上传

  • 监听事件drop 即监听文件拖拽释放时,获取文件内容
 upLoadFile(e) {
      e.preventDefault()
      e.stopPropagation()
      let df = e.dataTransfer
      let dragFiles = {} // 存储拖拽的文件对象
      if (df.items !== undefined) {
        // 谷歌
        // 拖拽多个文件
        // for (let i = 0; i < df.items.length; i++) {
        //   let item = df.items[i]
        //   // 用webkitGetAsEntry禁止上传目录
        //   if (item.kind === 'file' && item.webkitGetAsEntry().isFile) {
        //     let file = item.getAsFile()
        //     dragFiles.push(file)
        //   }
        // }
        // 脱脂啊单个文件
        let item = df.items[0]
        // 用webkitGetAsEntry禁止上传目录
        if (item.kind === 'file' && item.webkitGetAsEntry().isFile) {
          let file = item.getAsFile()
          dragFiles = file
        }
      } else {
        //safari 以及其他浏览器
        // 拖拽多个文件
        // for (var i = 0; i < df.files.length; i++) {
        //   dropFiles.push(df.files[i])
        // }
        // 拖拽单个文件
        dragFiles = df.files[0]
      }
      try {
        let fileReader = new FileReader()
        fileReader.readAsDataURL(dragFiles.slice(0, 3))
        fileReader.addEventListener('load', e => {
          console.log('load', e, dragFiles)
          // 上传
          let formData = new FormData()
          formData.append('file', dragFiles)
          respons.post(this.uploadUrl, formData).then(res => {
            if (res.status === 200) {
              // 上传成功
              this.dragFile = res.data
            } else {
              // 上传失败
              this.$message('上传失败,请重试!')
            }
          })
        })
        fileReader.addEventListener(
          'error',
          r => {
            this.$message.warning('不能上传文件夹')
          },
          false
        )
      } catch {
        this.$message.warning('不能上传文件夹')
        return
      }
    },

前端下载文件

  • 常规来说,对于文件类型的传输,后端接口一般返回字节流,数据类型一般Blob,ArrayBuffer这两种
  • 有个坑:如果你怎么调都无法下载…很可能你在用get请求方式,如果你用get请求,后端返给你的字节流对象不再是一个对象,而会把对象转成字节流对象字符串,于是乎下面的数据转换就失败了,然后用post则不会这样,返回的就是一个字节流对象于是乎轻松转换成文件
          // 这里的res,response中的data,
          const blob = new Blob([res], {
             type: 'application/zip' // 注意这里是以下载zip为例,其余文件格式此处不尽相同
           })
           const objectUrl = URL.createObjectURL(blob) // 创建URL
           link.href = objectUrl
           link.download = '测试' // 自定义文件名
           link.click() // 下载文件
           URL.revokeObjectURL(objectUrl) // 释放内存

H5简单粗暴的适配方案

(function (doc, win) {
  var docEl = doc.documentElement,
    resizeEvt = "orientationchange" in window ? "orientationchange" : "resize",
    //750 为设计稿宽度  适配rem
    recalc = function () {
      var clientWidth = docEl.clientWidth;
      if (!clientWidth) return;
      clientWidth = clientWidth <= 1080 ? clientWidth : 1080;
      $("html").css("fontSize", (clientWidth / 750) * 100 + "px");
    };
  if (!doc.addEventListener) return;
  win.addEventListener(resizeEvt, recalc, false);
  $(function () {
    recalc();
  });
})(document, window);

鼠标经过元素浮动动画

       
        //添加基本样式
        
        .li{
        -webkit-transform: translateZ(0);
        transform: translateZ(0);
        -webkit-transition-duration: 0.3s;
        transition-duration: 0.3s;
        -webkit-transition-property: transform;
        transition-property: transform;
        -webkit-transition-timing-function: ease-out;
        transition-timing-function: ease-out;
         
        //经过动画
         &:hover {
          -webkit-transform: translateY(-20px);
          transform: translateY(-20px);
          }
        }

获取url参数

function getQueryString(name) { 
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); 
var r = window.location.search.substr(1).match(reg); 
if (r != null) return unescape(r[2]); return null; 
// 如果有中文并且乱码,用下面这句
if (r != null) return decodeURI(r[2]); return null;
} 

移动端适配方案

  1. viewport
  2. 插件选择 postcss-px-to-viewport

配置

 //安装插件
 npm i postcss-px-to-viewport -D
 //根目录新建
 .postcssrc.js
 // 文件内容
 const path = require('path')
module.exports = ({ file }) => {
    // 记住这里:设计搞多大就给多大,然后剩下的就按照设计稿实际宽高,写就好了
    let designWidth = 750 
    return {
        plugins: {
            'postcss-px-to-viewport': {
                unitToConvert: 'px', // 要转化的单位
                viewportWidth: designWidth, // UI设计稿的宽度
                unitPrecision: 6, // 转换后的精度,即小数点位数
                propList: ['*'], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换
                viewportUnit: 'vw', // 指定需要转换成的视窗单位,默认vw
                fontViewportUnit: 'vw', // 指定字体需要转换成的视窗单位,默认vw
                selectorBlackList: ['usepx'], // 指定不转换为视窗单位的类名,
                minPixelValue: 1, // 默认值1,小于或等于1px则不进行转换
                mediaQuery: true, // 是否在媒体查询的css代码中也进行转换,默认false
                replace: true, // 是否转换后直接更换属性值
                landscape: false // 是否处理横屏情况
            }
        }
    }
}

标题vue-cil3 全局引入 公共样式变量

解决什么问题? 在每个文件都引入一个公共文件不烦吗?这就是一劳永逸饿方式

  1. 安装依赖 npm i style-resources-loader vue-cli-plugin-style-resources-loader -D

  2. 在vue.config.js 中添加以下配置

pluginOptions: {
 'style-resources-loader': { preProcessor: 'less', 
   patterns: [
   // 这个里面就是公共css的地址
   path.resolve(__dirname, "src/common/less/variable.less")]  
  }
 }

校验只能输入文字,英文,数字并限制长度

function checkStr(str) {
    var reg = new RegExp("^[A-Za-z0-9\u4e00-\u9fa5]+$");
    if (!reg.test(str)) {
        alert('文案中不能含有特殊字符');
        return false;
    }
    else {
        var cnLen = Math.ceil(str.replace(/[^\u4e00-\u9fa5]/gi, "").length * 2);
        var enLen = str.replace(/[^a-zA-Z]/gi, "").length;
        var numLen = str.replace(/[^0-9]/gi, "").length;
        if ((cnLen + enLen + numLen) > 30) {
            alert('已超出文案长度限制');
            return false;
        } else {
            return str;
        }
    }
}

数字切割千分位写法

    function convertTodecimal(s) {
      parseInt(s);
      s = s.replace(/^(\d*)$/, "$1.");
      s = (s + "00").replace(/(\d*\.\d\d)\d*/, "$1");
      s = s.replace(".", ",");
      var re = /(\d)(\d{3},)/;
      while (re.test(s))
        s = s.replace(re, "$1,$2");
      s = s.replace(/,(\d\d)$/, ".$1");
      return s.replace(/^\./, "0.")
    }

获取触摸移动距离

   (function () {
        var el = document.querySelector('.test');
        var startPosition, endPosition, deltaX, deltaY, moveLength;

        el.addEventListener('touchstart', function (e) {
            var touch = e.touches[0];
            startPosition = {
                x: touch.pageX,
                y: touch.pageY
            }
        });

        el.addEventListener('touchmove', function (e) {
            var touch = e.touches[0];
            endPosition = {
                x: touch.pageX,
                y: touch.pageY
            }

            deltaX = endPosition.x - startPosition.x;
            deltaY = endPosition.y - startPosition.y;
            moveLength = Math.sqrt(Math.pow(Math.abs(deltaX), 2) + Math.pow(Math.abs(deltaY), 2));
            console.log(moveLength);
        });
    })();

毫秒级时间格式转换

//毫秒时间格式转换

function MillisecondToDate(msd) {
    var time = parseFloat(msd) / 1000;
    if (null != time && "" != time) {
        if (time > 60 && time < 60 * 60) {
            time = (parseInt(time / 60.0) < 10 ? '0' + parseInt(time / 60.0) : parseInt(time / 60.0)) + "m" + ((parseInt((parseFloat(time / 60.0) -
                parseInt(time / 60.0)) * 60)) < 10 ? '0' + (parseInt((parseFloat(time / 60.0) -
                parseInt(time / 60.0)) * 60)) : (parseInt((parseFloat(time / 60.0) -
                parseInt(time / 60.0)) * 60))) + "s";
        } else if (time >= 60 * 60 && time < 60 * 60 * 24) {
            time = (parseInt(time / 3600.0) < 10 ? '0' + parseInt(time / 3600.0) : parseInt(time / 3600.0)) + "h" + ((parseInt((parseFloat(time / 3600.0) -
                parseInt(time / 3600.0)) * 60)) < 10 ? '0' + (parseInt((parseFloat(time / 3600.0) -
                parseInt(time / 3600.0)) * 60)) : (parseInt((parseFloat(time / 3600.0) -
                parseInt(time / 3600.0)) * 60))) + "m" +
                ((parseInt((parseFloat((parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60) -
                    parseInt((parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60)) * 60)) < 10 ? '0' + (parseInt((parseFloat((parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60) -
                    parseInt((parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60)) * 60)) : (parseInt((parseFloat((parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60) -
                    parseInt((parseFloat(time / 3600.0) - parseInt(time / 3600.0)) * 60)) * 60)) ) + "s";
        } else {
            time = (parseInt(time) < 10 ? '0' + parseInt(time) : parseInt(time)) + "s";
        }
    } else {
        time = "00h:00m:00s";
    }
    return time;

}

IE下时间戳转换

//判断IE  时间戳转化
//判断当前浏览器
function isIE() {
    if (!!window.ActiveXObject || "ActiveXObject" in window)
        return true;
    else
        return false;
}
if(isIE()){
    var date=$scope.maintenances[i].date;
    lastTime=Date.parse(date.replace(/-/g,"/"))
}else{
     lastTime = new Date($scope.maintenances[i].date).getTime();
}

FILE转换BASE64

input=file选择文件转化成base64
function readFile(img) {
    var file = img.files[0];
    if (!/image\/\w+/.test(file.type)) {
        alert("请确保文件为图像类型");
        return false;
    }
    var reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = function () {
        console.log(reader.result)
    }
}

blob和base64相互转化

// Base64转blob
function dataURLtoBlob(dataurl) {
    var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], {type: mime});
}
// blob转Base64
function blobToDataURL(blob, callback) {
    var a = new FileReader();
    a.onload = function (e) {
        callback(e.target.result);
    }
    a.readAsDataURL(blob);
}

项目引入字体

vue-cli3.0 引入外部字体并使用

  1. 去下载想要引入的字体的字体包,找ui要或者网上自己去搜
  2. 将要的字体放在资源目录下,看自己项目需求要放哪里,创建一个css文件
  3. 在fonts.css文件中引入想要的字体
@font-face {
  font-family: 'Medium';
  src: url('./SourceHanSansSC-Medium.otf');
}
 
@font-face {
  font-family: 'Regular';
  src: url('./SourceHanSansSC-Regular.otf');
}
  1. 在项目的main.js文件中引入刚写好的css文件
import './assets/fonts/fonts.css'
  1. 直接在vue文件中的样式添加字体样式
.text {
  font-family: 'Regular'; // 这里的Regular是引入时的自定义名字
}

loadash按需加载(vue-cli4)

npm i lodash lodash-webpack-plugin babel-plugin-lodash --dev

vue.config.js

  //引入
  const LodashModuleReplacementPlugin = require('lodash-webpack-plugin') //按需加载lodash
  chainWebpack: (config) => {
    //按需加载lodash
    if (process.env.NODE_ENV === 'production') {
      config.plugin('loadshReplace').use(new LodashModuleReplacementPlugin())
    }
  },

babel.condig.js

plugins: ['lodash']

echart按需加载(实时变更请同步官网)

// 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。
import * as echarts from 'echarts/core';
// 引入柱状图图表,图表后缀都为 Chart
import {
    BarChart
} from 'echarts/charts';
// 引入提示框,标题,直角坐标系组件,组件后缀都为 Component
import {
    TitleComponent,
    TooltipComponent,
    GridComponent
} from 'echarts/components';
// 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
import {
    CanvasRenderer
} from 'echarts/renderers';

// 注册必须的组件
echarts.use(
    [TitleComponent, TooltipComponent, GridComponent, BarChart, CanvasRenderer]
);

// 接下来的使用就跟之前一样,初始化图表,设置配置项
var myChart = echarts.init(document.getElementById('main'));
myChart.setOption({
    ...
});

echarts 封装

<template>
  <div ref="chart" :style="styles"></div>
</template>
<script>
import { addListener, removeListener } from 'resize-detector'
import { debounce } from 'lodash'
// eslint-disable-next-line no-undef
const echarts = equire(['bar'])
export default {
  name: 'BaseChart',
  props: {
    styles: {
      // 设置样式
      type: String,
      default: 'width:400px;height:400px'
    },
    option: {
      type: Object,
      default: () => {}
    }
  },
  data() {
    return {}
  },
  watch: {
    option(val) {
      this.chart.setOption(val)
    }
  },
  created() {
    this.resize = debounce(this.resize, 300)
  },
  mounted() {
    this.renderChart()
    addListener(this.$refs.chart, this.resize)
  },
  beforeDestroy() {
    removeListener(this.$refs.chart, this)
    this.chart.dispose()
    this.chart = null
  },
  methods: {
    renderChart() {
      this.chart = echarts.init(this.$refs.chart, this.resize)
      this.chart.setOption(this.option)
    },
    resize() {
      this
    }
  }
}
</script>
<style lang="sass" scoped></style>

thread-loader使用(vue-cli4)

npm i thread-loader -D

    // thread-loader
    config.module
      .rule('js')
      .test(/\.js$/)
      .use('thread-loader')
      .loader('thread-loader')
      .options({
        workers: 4,
        workerParallelJobs: 50, 
        poolTimeout: 2000,
        poolParallelJobs: 50,
      })
      .end()

hard-source-webpack-plugin 打包速度优化

npm i hard-source-webpack-plugin -D

const HardSourceWebpackPlugin = require('hard-source-webpack-plugin') // 开启构建缓存机制
 plugins.push(new HardSourceWebpackPlugin())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值