拖拽上传
- 监听事件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;
}
移动端适配方案
- viewport
- 插件选择 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 全局引入 公共样式变量
解决什么问题? 在每个文件都引入一个公共文件不烦吗?这就是一劳永逸饿方式
-
安装依赖 npm i style-resources-loader vue-cli-plugin-style-resources-loader -D
-
在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 引入外部字体并使用
- 去下载想要引入的字体的字体包,找ui要或者网上自己去搜
- 将要的字体放在资源目录下,看自己项目需求要放哪里,创建一个css文件
- 在fonts.css文件中引入想要的字体
@font-face {
font-family: 'Medium';
src: url('./SourceHanSansSC-Medium.otf');
}
@font-face {
font-family: 'Regular';
src: url('./SourceHanSansSC-Regular.otf');
}
- 在项目的main.js文件中引入刚写好的css文件
import './assets/fonts/fonts.css'
- 直接在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())