前端项目常用函数封装(一)
2023-12-20 16:56:03
文章目录
- 前端项目常用函数封装(二)
- vite vue3 遍历图片不显示问题
- @keyup.enter.native不生效问题解决
- js将一维数组转为二维数组
- electron中指定默认下载路径和名称
- TypeScript 中?: 、??、?. 、!. 、&&= 、??= 、||= 含义解析
- input框中输入的值,需要导出pdf或者打印出来为空的问题
- js写货币格式(每三位一个逗号分隔)
- 大数值转换为 K,M,G,T或者KB,MB,GB,TB
- 数组包对象,同时对多个属性进行筛选(搜索查询)
- 数组包对象,按照对象的某一属性去重
- 数组包对象,以对象的某一个属性排序
- getCookie、setCookie、removeCookie
- 防抖:n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时
- 节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
- 将文件类型转换成字符串数组
- 将对象转化为URL的查询字符串(对象转化为地址栏问号传参)
- vue3中解构地址栏参数 (比下面getUrlParams好用)
- 截取地址栏参数
- dom节点删除 删除子节点 removeChild
- 如何隐藏滚动条 滚动条的样式修改
- 获取系统时间日期, 返回:日期,星期
- 将rangepick 时间选择的数据进行过滤
- 字符串超出长度显示省略号 css方法
- 字符串超出长度显示省略号 js截取方法
- input 取消默认提示框
- 利用@media与@media screen进行响应式布局
- 表格时间格式化
- 日期格式化
- 获取设备信息方法
- 封装公共路径跳转的方法
- 扫码的方法 h5 不兼容
前端项目常用函数封装(二)
vite vue3 遍历图片不显示问题
官网:vite官网参考
<div
class="header-menu-list flex ac"
v-for="(item, i) in header"
:key="item.title"
>
<div class="header-img">
<img :src="getimg(i)" alt="" />
</div>
</div>
<script>
methods: {
// 图片
getimg(e) {
let path1 = [
"/src/assets/img/guangfu1.png",
"/src/assets/img/day.png",
"/src/assets/img/sum.png",
"/src/assets/img/yongshuiliang.png",
"/src/assets/img/leijiyongshui.png",
];
//属性是href,正好是函数的返回值
//(我测试的,打包后就不能用了,绝对路径可以:(E:/img/sum.png))
// 是在不行也可以用 import url1 from '/@/assets/img/shamen.jpg'; 最后吧rul1放到数组里面再去遍历
return new URL(path1[e],import.meta.url).href //import.meta 对象包含关于当前模块的信息。
},
}
<script/>
@keyup.enter.native不生效问题解决
el-form表单中的el-input回车刷新页面,@keyup.enter.native不生效问题解决
表单中只有一个input,键盘回车会刷新页面,@keyup.enter就会失效
解决方案:
1:在表单里加一个不显示的input(不推荐此写法)
2:在el-form上添加@submit.native.prevent(推荐)
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px" @submit.native.prevent>
<el-form-item label="客户id" prop="customerId">
<el-input v-model="queryParams.customerId" placeholder="请输入客户id" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
js将一维数组转为二维数组
如果多维数组转以为数组用 flat() arr.flat()
//推荐使用 convertTo2DArray
const convertTo2DArray = (arr: Array<any>, chunkSize: number) => {
var result = [];
for (var i = 0; i < arr.length; i += chunkSize) {
result.push(arr.slice(i, i + chunkSize));
}
return result;
}
const arrToMatrix = (arr: Array<any>, num: number) => {
var matrix = [], i, k;
for (i = 0, k = -1; i < arr.length; i++) {
if (i % num === 0) {
k++;
matrix[k] = [];
}
matrix[k].push(arr[i]);
}
return matrix;
}
electron中指定默认下载路径和名称
const { BrowserWindow} = require('electron');
// 触发下载
let win = BrowserWindow.getFocusedWindow();
win.webContents.downloadURL(args.download)
//监听下载动作
win.webContents.session.on('will-download', (event, item, webContents) => {
/*
args.localPath:下载的资源连接 url
args.saveName:下载名字
*/
var zipFile = path.join(args.localPath, args.saveName)
// console.log(zipFile)
item.setSavePath(zipFile)
//监听下载过程
item.on('updated', (event, state) => {
//下载意外中断,可以恢复
if (state === 'interrupted') {
console.log('Download is interrupted but can be resumed')
} else if (state === 'progressing') {
//下载正在进行中
if (item.isPaused()) {
//下载暂停中
console.log('Download is paused')
} else {
//下载进行中 下载进度
console.log(`complete:${(item.getReceivedBytes() / item.getTotalBytes() * 100).toFixed(2)}%`)
//任务栏进度条 -1不展示
win.setProgressBar(item.getReceivedBytes() / item.getTotalBytes())
}
}
})
//监听完成
item.once('done', (event, state) => {
console.log('下载完成下载完成')
//读取一个Buffer
var buffer = fs.readFileSync(zipFile);
var fsHash = crypto.createHash('sha1');
fsHash.update(buffer);
var sha1 = fsHash.digest('hex');
console.log("文件的MD5是:%s", args.hash + ',' + sha1);
if (sha1 == args.hash) {
shell.openPath(zipFile)
}
// console.log(getFileSha1(zipFile))
// win.webContents.send('onFileSHA1', zipFile)
// shell.openPath(zipFile)
})
})
TypeScript 中?: 、??、?. 、!. 、&&= 、??= 、||= 含义解析
- ?: 是指可选参数,可以理解为参数自动加上undefined
- ?? ?? 和 || 的意思有点相似,但是又有点区别,??相较||比较严谨, 当值等于0的时候||就把他给排除了,但是?? 不会.
- ?. ?.的意思基本和 && 是一样的
- !. !.的意思是断言,告诉ts你这个对象里一定有某个值
- &&= 如果第一个表达式的值为 true,则执行第二个表达式,并将结果赋值给第一个表达式;如果第一个表达式的值为 false,则不执行第二个表达式,第一个表达式的值不变。
- ||= 如果左侧的操作数(表达式)为真(即非零、非空或非undefined),则返回左侧的操作数(表达式);否则,返回右侧的操作数(表达式)。
- ??= 如果左侧的操作数(表达式)是 null 或 undefined,那么返回右侧的操作数(表达式);否则,将右侧的操作数(表达式)赋值给左侧的操作数(表达式)。
看下面的例子
a = a && b
a = a || b
a = a ?? b
//等效于下面的方法
a &&= b;
a ||= b;
a ??= b;
input框中输入的值,需要导出pdf或者打印出来为空的问题
原理:利用 setAttribute()方法添加value属性,并为其赋值
let allInput = document.querySelectorAll('input') //先获取所有的input 的dom对象
allInput.forEach((item, index) => {
if (index != 0) {
//利用 setAttribute()方法天骄value属性,并为其赋值 allInput[index].value:对应input中输入的值
allInput[index].setAttribute('value', allInput[index].value)
}
})
js写货币格式(每三位一个逗号分隔)
注意:每个组件库中都有:Statistic 统计数值,可以参考一下,直接应用
const convertNum = (val: number) => {
return val.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,');
};
大数值转换为 K,M,G,T或者KB,MB,GB,TB
export default function convertNumber(number: any) {
if (number < 10 ** 3) {
return number;
}
if (10 ** 3 <= number && number < 10 ** 6) {
return `${(number / 10 ** 3).toFixed(1)} K`;
}
if (10 ** 6 <= number && number < 10 ** 9) {
return `${(number / 10 ** 6).toFixed(1)} M`;
}
if (10 ** 9 <= number && number < 10 ** 12) {
return `${(number / 10 ** 9).toFixed(1)} G`;
}
return `${(number / 10 ** 12).toFixed(1)} T`;
}
export function convertBase(number: any) {
if (number < 10 ** 3) {
return number;
}
if (10 ** 3 <= number && number < 10 ** 6) {
return `${(number / 10 ** 3).toFixed(1)} Kb`;
}
if (10 ** 6 <= number && number < 10 ** 9) {
return `${(number / 10 ** 6).toFixed(1)} Mb`;
}
if (10 ** 9 <= number && number < 10 ** 12) {
return `${(number / 10 ** 9).toFixed(1)} Gb`;
}
return `${(number / 10 ** 12).toFixed(1)} Tb`;
}
数组包对象,同时对多个属性进行筛选(搜索查询)
html页面的input
<div class="search">
<!-- orderName geneName similar length evalue score-->
<a-space>
<a-input v-model:value="tableConfig.orderName" placeholder="请输入序列名称" @keyup.enter.native="search" allowClear />
<a-input v-model:value="tableConfig.geneName" placeholder="请输入参考基因组名称" @keyup.enter.native="search" allowClear />
<a-input v-model:value="tableConfig.similar" placeholder="请输入相似性" @keyup.enter.native="search" allowClear />
<a-button type="primary" @click="search">查询</a-button>
<a-button type="default" @click="reset">重置</a-button>
</a-space>
</div>
这里是需要筛选的数据 方法在下面写
let tableConfig.SearchtotalData = [
{
"序列名称": "contig_1",
"参考基因组名称": "AJ938182",
"相似性(%)": "98.489",
"id": "1",
},
{
"序列名称": "contig_1",
"参考基因组名称": "AJ938182",
"相似性(%)": "98.857",
"id": "2",
},
{
"序列名称": "contig_1",
"参考基因组名称": "AJ938182",
"id": "3",
},
{
"序列名称": "contig_1",
"参考基因组名称": "AJ938182",
"相似性(%)": "98.386",
"id": "4",
},
{
"序列名称": "contig_1",
"参考基因组名称": "AJ938182",
"相似性(%)": "97.522",
"id": "5",
},
{
"序列名称": "contig_1",
"参考基因组名称": "AJ938182",
"相似性(%)": "98.889",
"id": "6",
},
{
"序列名称": "contig_1",
"参考基因组名称": "AJ938182",
"相似性(%)": "99.048",
"id": "7",
},
{
"序列名称": "contig_1",
"参考基因组名称": "AJ938182",
"相似性(%)": "98.706",
"id": "8",
},
{
"序列名称": "contig_1",
"参考基因组名称": "AJ938182",
"相似性(%)": "98.085",
"id": "9",
}
]
筛选的方法
const search = () => {
if (!tableConfig.orderName && !tableConfig.geneName && !tableConfig.similar && !tableConfig.length && !tableConfig.evalue && !tableConfig.score) {
message.info('请输入筛选条件!')
} else {
let tempArray = [];
tableConfig.SearchtotalData.forEach(item => {
let flag = false;
let flag2 = false;
let flag3 = false;
if (tableConfig.orderName) {
if (item.序列名称.includes(tableConfig.orderName)) {
flag = true;
} else {
flag = false;
}
} else {
flag = true;
}
if (tableConfig.geneName) {
if (flag && item.参考基因组名称.includes(tableConfig.geneName)) {
flag2 = true;
} else {
flag2 = false;
}
} else {
flag2 = true;
}
let isSimilar = parseFloat(item['相似性(%)']) > parseFloat(tableConfig.similar)
if (tableConfig.similar) {
if (flag && flag2 && isSimilar) {
flag3 = true;
} else {
flag3 = false;
}
} else {
flag3 = true;
}
if (flag && flag2 && flag3 ) {
tempArray.push(item);
}
tableConfig.totalData = tempArray;
tableConfig.totalNumber = tableConfig.totalData.length
})
}
}
数组包对象,按照对象的某一属性去重
//arr: 要去重的数组, attribute:按照对象的属性去重
let deWeightThree = (arr: Array<any>, attribute: string) => {
let map = new Map();
for (let item of arr) {
if (!map.has(item[attribute])) {
map.set(item[attribute], item);
}
}
return [...map.values()];
}
//得到的新数组
tempArray2 = deWeightThree(tempArray, 'sample');
数组包对象,以对象的某一个属性排序
首相要了解数组的sort方法
对象的属性是 number类型
let arr = [{name: "zlw", age: 24}, {name: "wlz", age: 25}];
//降序
let ObjDescend= function (prop) {
return function (obj1, obj2) {
var val1 = obj1[prop];
var val2 = obj2[prop];
if (val1 < val2) {
return -1;
} else if (val1 > val2) {
return 1;
} else {
return 0;
}
}
}
如果想以 age,进行排序:arr.sort(ObjDescend('age'))
如果 age 的值为字符串 (age:“24”),还用上面的方法则会按照ASCII排序(按照字符串排序)
对象的属性是字符串的类型
let arr = [{name: "zlw", age: 24}, {name: "wlz", age: 25}];
//升序
let ObjAscend= function (prop) {
return function (obj1, obj2) {
var val1 = obj1[prop];
var val2 = obj2[prop];
if (!isNaN(Number(val1)) && !isNaN(Number(val2))) {
val1 = Number(val1);
val2 = Number(val2);
}
if (val1 > val2) {
return -1;
} else if (val1 < val2) {
return 1;
} else {
return 0;
}
}
}
如果想以 age,进行排序:arr.sort(ObjAscend('age'))
getCookie、setCookie、removeCookie
function getCookie(key){
var arr1 = document.cookie.split('; ');//这里是分号+空格分隔
for( var i = 0 , len = arr1.length ; i < len ; i++ ){
var arr2 = arr1[i].split('=');
if( arr2[0] == key ){
return decodeURI(arr2[1]);
}
}
}
getCookie('age');//21
function setCookie(key,value,time){
var oDate = new Date();
oDate.setDate( oDate.getDate() + time );
document.cookie = key +'=' + value + ';expires=' + oDate.toGMTString();
}
setCookie('sex','男',10);//sex='男'存cookie十天
//封装一个删除cookie的方法,就是将cookie的有效时间更改为昨天而已。
function removeCookie(key){
setCookie(key,'',-1);//调用上面的setCookie方法
}
removeCookie('sex');
防抖:n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时
// 防抖:n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时
function _debounce(func,delay) {
let timeout;
var delay = delay || 200;
return function () {
let context = this;
let args = arguments;
if (timeout) clearTimeout(timeout);
let callNow = !timeout;
timeout = setTimeout(() => {
timeout = null;
}, delay)
if (callNow) func.apply(context, args)
}
}
//防抖
let timer_debounce: any;
export const debounce = (func: Function, wait?: number) => {
wait = wait || 500;
clearTimeout(timer_debounce);
timer_debounce = setTimeout(() => {
func.apply(this);
}, wait);
};
节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
// 节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
function _throttle(fn, interval) {
var last;
var timer;
var interval = interval || 200;
return function () {
var th = this;
var args = arguments;
var now = +new Date();
if (last && now - last < interval) {
clearTimeout(timer);
timer = setTimeout(function () {
last = now;
fn.apply(th, args);
}, interval);
} else {
last = now;
fn.apply(th, args);
}
}
}
let timer_throttle: any;
export const throttle = (func: Function, wait?: number) => {
wait = wait || 500;
if (!timer_throttle) {
timer_throttle = setTimeout(() => {
func.apply(this);
timer_throttle = null;
}, wait);
}
};
不想自己写,也可以用 lodash 库去实现
_.throttle(func, [wait=0], [options=])//节流
//说明:
//func (Function): 要节流的函数。
//[wait=0] (number): 需要节流的毫秒。
//[options=] (Object): 选项对象。
//[options.leading=true] (boolean): 指定调用在节流开始前。
//[options.trailing=true] (boolean): 指定调用在节流结束后。
_.debounce(func, [wait=0], [options=])//防抖
//说明:
//func (Function): 要防抖动的函数。
//[wait=0] (number): 需要延迟的毫秒数。
//[options=] (Object): 选项对象。
//[options.leading=false] (boolean): 指定在延迟开始前调用。
//[options.maxWait] (number): 设置 func 允许被延迟的最大值。
//[options.trailing=true] (boolean): 指定在延迟结束后调用。
//记得安装
//引入
import _ from "lodash";
//使用
_.debounce(() => {
console.log("防抖");
}, 500);
_.throttle(() => {
console.log("节流");
}, 500);
将文件类型转换成字符串数组
// 将文件类型转换成字符串数组
export const filesToStringArrary = function (list: any) {
if (typeof list === 'string') return list;
if (list === null) return [];
const _list: { fileName: any; fileType: any; fileId: any }[] = [];
const _ids_list: any[] = [];
list.length > 0 &&
list.map(function (
item: { response: { data: any[] }; name: any; type: any; contentType: any; uid: any },
) {
if (item.response) {
_list.push({
fileName: item.name,
fileType: item.type,
fileId: item.response.data[0],
});
_ids_list.push(item.response.data[0]);
} else {
_list.push({
fileName: item.name,
fileType: item.contentType,
fileId: item.uid,
});
_ids_list.push(item.uid);
}
});
return { _list, _ids_list };
};
将对象转化为URL的查询字符串(对象转化为地址栏问号传参)
常用语get请求传参,将对象格式转换为?+&的情况
/**
* 将对象转化为URL的查询字符串
* @param q 查询对象
* @returns URL的查询字符串
*/
export const formatQuery = (q: any) => {
let query = '';
Object.keys(q).forEach((key) => {
if (q[key] !== '' && q[key] !== undefined) {
query += `${key}=${q[key]}&`;
}
});
return query.substring(0, query.length - 1);
};
vue3中解构地址栏参数 (比下面getUrlParams好用)
import { useRouter } from 'vue-router';
const router = useRouter();
const query = JSON.parse(JSON.stringify(router.currentRoute.value.query));
const { taskId, barcodeId, sampleId, generation, barcodeName } = query; //{}里面直接结构参数
截取地址栏参数
// 获取数组的params字段默认用来获取rbacToken;
export const getUrlParams = function (name: string) {
const url2 = window.location.href;
const temp2 = url2.split('?')[1];
const pram2 = new URLSearchParams(`?${temp2}`);
let data = pram2.get(name);
if (!data) return '';
if (data.indexOf('#/') >= 0) {
data = data.split('#/')[0];
}
return data;
};
如果需要传值过多,推荐使用下列方法,类似于vue3中的vue-router
//将地址栏参数返回一个对象直接结构出来就好了,类似于上面的vue3获取地址栏参数
export const getUrlParamsObj = function () {
var s = location.href.indexOf("?");
var t = location.href.substring(s + 1);
let arr = t.split('\&')
let paramsObj: any = {}
arr.forEach((item: string, index: number) => paramsObj[item.split('=')[0]] = item.split('=')[1])
return paramsObj;
};
//使用方法
//let { taskId ,barcodeId } = getUrlParamsObj()
//console.log(taskId ,barcodeId);
dom节点删除 删除子节点 removeChild
在同一个div中话echart是,需要清除画布,重回绘制,否则会重叠,这里我用了删除dom在添加一个div进去
/**
* 要删除的父div id
* 要删除的div id
*/
resetDom('mapParent', 'map')
const resetDom = (parentId: string, childId: string) => {
let parentsDom = document.getElementById(parentId);
// clear
let childDom = document.getElementById(childId);
if (childDom) {
parentsDom.removeChild(childDom)
}
// create
var littleBox = document.createElement('div')
littleBox.style.width = "100%";
littleBox.style.height = "100%";
littleBox.setAttribute("id", childId)
parentsDom.appendChild(littleBox)
}
如何隐藏滚动条 滚动条的样式修改
overflow: auto;
overflow-x: hidden;
overflow-y: scroll;
scrollbar-width: none; /* firefox */
-ms-overflow-style: none; /* IE 10+ */
/* 设置滚动条的样式 */
&::-webkit-scrollbar {
display: none;
//width: 12px;
//height:12px;
}
/* 滚动槽 */
&::-webkit-scrollbar-track {
background-color: #fdffeb;
border-radius: 10px;
}
/* 滚动条滑块 */
&::-webkit-scrollbar-thumb {
border-radius: 10px;
background: rgba(173, 247, 89, 0.6);
}
&::-webkit-scrollbar-thumb:window-inactive {
background: rgba(255, 0, 0, 0.4);
}
获取系统时间日期, 返回:日期,星期
/** 获取系统时间日期, 返回:
* @returns dateNum: 日期, dayStr: 星期
*/
const getNowDateStr = () => {
const nowDate = new Date();
const dayStrs = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六",];
const dateNum = nowDate.getDate();
const dayStr = dayStrs[nowDate.getDay()];
return {
dateNum,
dayStr
}
}
将rangepick 时间选择的数据进行过滤
//将rangepick 时间选择的数据进行过滤
export const filterKeys = function (data) {
const filterData = {};
for (let key in data) {
if (key.indexOf('-') >= 0) {
key.split('-').map(function (item, idx) {
if (!data[key]) {
filterData[item] = undefined;
} else {
if (typeof data[key][idx] === 'object') {
//目前只针对时间做了优化 未出现有其他是对象的值
filterData[item] = data[key][idx].format('YYYY-MM-DD 00:00:00');
} else {
filterData[item] = data[key][idx];
}
}
});
} else {
filterData[key] = data[key];
}
}
return filterData;
};
字符串超出长度显示省略号 css方法
word-break: break-all; 只对英文起作用,以字母作为换行依据。
word-wrap: break-word; 只对英文起作用,以单词作为换行依据。
white-space: pre-wrap; 只对中文起作用,强制换行。
一行显示
// 这样只能显示一行,多出的省略号显示
white-space: nowrap;/* 强制在一行显示 */
text-overflow: ellipsis; /* 超过最小宽度后,超过部分用省略号显示 */
overflow: hidden; /* 超过最小宽度后,自动隐藏 */
多行显示
text-overflow: ellipsis;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2; //这里控制行数
-webkit-box-orient: vertical;
字符串超出长度显示省略号 js截取方法
// 字符串超出长度显示省略号
const lineOmit = function (str, breakLength) {
if (!breakLength) breakLength = 3;
if (str.length <= breakLength) return str;
return str.slice(0, breakLength) + '...';
};
input 取消默认提示框
autocomplete="off" // 添加这个属性
<input autocomplete="off" /> //这样获取焦点的时候就没有提示框了
利用@media与@media screen进行响应式布局
<style>
//一种是直接在link中判断设备的尺寸,然后引用不同的css文件:
<link rel="stylesheet" type="text/css" href="styleA.css" media="screen and (min-width: 400px)">
//另一种方式,即是直接写在 style 标签里:
@media screen and (max-width: 1919px) {
@import './styles/small.less';
}
@media screen and (min-width: 1920px) {
@import './styles/big.less';
}
// 参考下面的例子:
//我们用min-width时,小的放上面大的在下面,同理如果是用max-width那么就是大的在上面,小的在下面
@media (min-width: 1200){ //>=1200的设备 }
@media (min-width: 992px){ //>=992的设备 }
@media (min-width: 768px){ //>=768的设备 }
//注意下顺序,如果你把@media (min-width: 768px)写在了上面那么就是错误的!!!
@media (max-width: 1199){ //<=1199的设备 }
@media (max-width: 991px){ //<=991的设备 }
@media (max-width: 767px){ //<=768的设备 }
//混合使用
@media screen and (min-width:1200px){}
@media screen and (min-width: 960px) and (max-width: 1199px) { }
@media screen and (min-width: 768px) and (max-width: 959px) { }
@media only screen and (min-width: 480px) and (max-width: 767px){ }
@media only screen and (max-width: 479px) { }
</style>
表格时间格式化
/**
* 表格时间格式化
*/
export function formatDate(cellValue) {
if (cellValue == null || cellValue == "") return "";
var date = new Date(cellValue)
var year = date.getFullYear()
var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
}
/**
* @param {number} time
* @param {string} option
* @returns {string}
*/
export function formatTime(time, option) {
if (('' + time).length === 10) {
time = parseInt(time) * 1000
} else {
time = +time
}
const d = new Date(time)
const now = Date.now()
const diff = (now - d) / 1000
if (diff < 30) {
return '刚刚'
} else if (diff < 3600) {
// less 1 hour
return Math.ceil(diff / 60) + '分钟前'
} else if (diff < 3600 * 24) {
return Math.ceil(diff / 3600) + '小时前'
} else if (diff < 3600 * 24 * 2) {
return '1天前'
}
if (option) {
return parseTime(time, option)
} else {
return (
d.getMonth() +
1 +
'月' +
d.getDate() +
'日' +
d.getHours() +
'时' +
d.getMinutes() +
'分'
)
}
}
日期格式化
// 日期格式化
export function parseTime(time, pattern) {
if (arguments.length === 0 || !time) {
return null
}
const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
time = parseInt(time)
} else if (typeof time === 'string') {
time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '');
}
if ((typeof time === 'number') && (time.toString().length === 10)) {
time = time * 1000
}
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
let value = formatObj[key]
// Note: getDay() returns 0 on Sunday
if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
if (result.length > 0 && value < 10) {
value = '0' + value
}
return value || 0
})
return time_str
}
获取设备信息方法
//获取设备信息方法
const getClientInfo = () => {
var cid, getClientInfo;
return new Promise(function (resolve) {
try {
if (window && window.plus) {
} else {
if (plus) {
//#ifdef APP-PLUS
getClientInfo = plus.push.getClientInfo();
cid = getClientInfo.clientid;
console.log(cid);
console.log(getClientInfo);
resolve({
cid,
getClientInfo
})
//#endif
} else {
plus.globalEvent.addEventListener('plusready', function () {
if (cid && cid != 'undefind' && cid != '' && cid != 'null') {
return;
}
//#ifdef APP-PLUS
getClientInfo = plus.push.getClientInfo();
//#endif
cid = getClientInfo.clientid;
console.log(cid);
console.log(getClientInfo);
resolve({
cid,
getClientInfo
})
});
}
}
} catch (e) {
//#ifdef H5
resolve({})
//#endif
//TODO handle the exception
}
})
}
封装公共路径跳转的方法
//封装公共路径跳转的方法
const navTo = function (url, params) {
if (!isNaN(parseInt(url))) {
uni.navigateBack({
delta: Number(url)
})
return;
}
let _params = "";
params ?
Object.keys(params).map(function (key, idx) {
_params = _params + `${idx == 0 ? '?' : '&'}${key}=${params[key]}`;
}) : null;
uni.navigateTo({
url: url + _params,
})
}
//提示文字+路径跳转方法
//如果没有传navTo对象 则不进行跳转 只进行提示
const showToastOrNavTo = function (conf) {
const { title, duration, icon, image, navTo: _navTo } = conf;
uni.showToast({
//icon 类型 success error loading none
//none 不显示图标,此时 title 文本在小程序最多可显示两行,App仅支持单行显示。
icon: icon ? icon : 'success',
//自定义图标路径
image: image ? image : null,
mask: true,
title: title || "操作成功",
duration: Number(duration) || 1500,
complete: function () {
_navTo ?
setTimeout(function () {
navTo(_navTo.url, _navTo.params)
}, duration || 1500) : null
}
});
}
扫码的方法 h5 不兼容
//扫码的方法 h5 不兼容
const scanCode = (conf) => {
const { onlyFromCamera, scanType } = conf || {};
return new Promise(function (resolve) {
uni.scanCode({
//是否只能从相机扫码,不允许从相册选择图片
onlyFromCamera: onlyFromCamera || true,
//扫码类型,参数类型是数组,二维码是'qrCode',一维码是'barCode',DataMatrix是‘datamatrix’,pdf417是‘pdf417’。
scanType: scanType || ['qrCode'],
success: function (...data) {
resolve(...data)
},
fail: function (err) {
if (err.errMsg.includes("cancel")) {
return;
} else {
showToastOrNavTo({
icon: "error",
title: "扫码失败",
})
}
},
complete: function () {
}
})
})
}
文章来源:https://blog.csdn.net/qq_43940789/article/details/135109894
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!