@cataract6545/tmui
Version:
tm-vuetify是一个新势力由主题驱动的UI组件库,相比其它优势大,组件全,设计趋势紧跟未来。具有主题生成,主题实时切换,暗黑实时切换,lottie动画,图表等新颖功能,tmui TMUI
901 lines (844 loc) • 24.3 kB
text/typescript
import { ComponentInternalInstance } from 'vue'
interface Data {
[key: string]: any;
}
/**
* 预览图片。
@param {Object} url 必填 当前预览的图片链接。
@param {Object} list 可以是url数组,也可以是对象,数据比如:["http:url"] or [{url:"https:url",...}]
@param {Object} rangKey 如果list是对象数组,需要提供url字段。
*/
import { preview } from "./preview.js"
export default preview;
/**
* 检测是否是数字
* @param arg 待检测的字符
* @param defaultNum 0,如果不符合值时设置默认值
* @returns number类型数值
*/
export function isNumber(arg: string | number | undefined | null, defaultNum = 0): number {
const p = Number(arg);
return p || defaultNum;
}
/**
* 检测是否是字符串
* @param arg 待检测的字符
* @param defaultNum 默认"",如果不符合值是设置默认值
* @returns 字符串
*/
export function isString(arg: string | number | undefined | null, defaultStr = ""): string {
let p = "";
if (typeof arg === "string" && arg != null) {
p = String(arg);
} else p = defaultStr;
return p;
}
/**
* 把一个数字进行分页返回数字数组
* @param total 总数
* @param pageSize 分页大小
* @returns 数字数组
*/
export function paginate(total: number, pageSize: number): number[] {
const pages = Math.ceil(total / pageSize);
const pageArr: number[] = [];
for (let i = 0; i < pages; i++) {
pageArr.push(i + 1);
}
return pageArr;
}
/**
* 取对象数据值(可深层次取值)
* @example getValue(data,"a.b.c")
* @param data 对象数据
* @param keys 键值
* @returns 返回值
* @description 注意不会去改变原来的数据
*/
export function getValue(data: Data, keys: string): any {
const keyArr = keys.split(".");
let result = { ...data };
for (const key of keyArr) {
result = result[key];
if (result === undefined || result === null) {
return result;
}
}
return result;
}
/**
* 设置对象键值(可深层次设置值)
* @example setValue(data,"a.b.c","haha")
* @param data 对象数据
* @param keys 键值
* @returns 修改后的对象数据。
* @description 改变原来的数据
*/
export function setValue(data: Data, keys: string, value: any): void {
const keyArr = keys.split(".");
let obj = data;
for (let i = 0; i < keyArr.length - 1; i++) {
const key = keyArr[i];
if (!(key in obj)) {
obj[key] = {};
}
obj = obj[key];
}
obj[keyArr[keyArr.length - 1]] = value;
}
/**
* 计算并返回一个对象中最大的层级数
* @param data 待检测对象数据
* @returns 最大层级数
*/
export function getMaxDepth(data: Data): number {
let maxDepth = 0;
function traverse(obj: any, depth: number): void {
if (typeof obj !== "object" || obj === null) {
maxDepth = Math.max(maxDepth, depth);
return;
}
for (const key in obj) {
// deno-lint-ignore no-prototype-builtins
if (obj.hasOwnProperty(key)) {
traverse(obj[key], depth + 1);
}
}
}
traverse(data, 0);
return maxDepth;
}
/**
* 深度合并对象
* @param FirstOBJ 需要合并的对象
* @param SecondOBJ 被合并的对象
* @returns 返回合并后的对象
*/
export function deepObjectMerge(FirstOBJ : Data, SecondOBJ : Data) : Data { // 深度合并对象
for (var key in SecondOBJ) {
FirstOBJ[key] = FirstOBJ[key] && FirstOBJ[key]?.toString() === "[object Object]" ?
deepObjectMerge(FirstOBJ[key], SecondOBJ[key]) : FirstOBJ[key] = SecondOBJ[key];
}
return FirstOBJ;
}
/**
* 数据分组
* @param {Array} oArr - 原数组列表
* @param {Number} length - 单个数组长度
* @return {Array} arr - 分组后的新数组
*/
export function splitData<T>(arr: Array<T> = [], size = 1): Array<T[]> {
const result = [];
for (let i = 0; i < arr.length; i += size) {
result.push(arr.slice(i, i + size));
}
return result as T[][];
}
/**
* 深度克隆
* @param {T} data 待大克隆复制的数据
* @return {T} any
*/
export function deepClone<T>(data: T): T {
// 对常见的“非”值,直接返回原来值
if (data === null || typeof data !== "object") {
return data;
}
if (Array.isArray(data)) {
const clone: any[] = [];
for (const item of data) {
clone.push(deepClone(item));
}
return clone as any;
}
if (data instanceof Date) {
return new Date(data.getTime()) as unknown as T;
}
if (data instanceof RegExp) {
const flags = data.flags;
return new RegExp(data.source, flags) as unknown as T;
}
if (typeof data === "function") {
return data as unknown as T;
}
const clone = {} as T;
for (const key in data) {
if (Object.prototype.hasOwnProperty.call(data, key)) {
clone[key] = deepClone(data[key]);
}
}
return clone;
}
/**
* 剩余时间格式化
* @param {Number} t - 剩余多少秒
* @return {Object} format - 格式后的天时分秒对象
*/
export function timeMuch(t: number) {
let format: any = {
d: '00',
h: '00',
m: '00',
s: '00'
};
if (t > 0) {
let d = Math.floor(t / 86400);
let h = Math.floor((t / 3600) % 24);
let m = Math.floor((t / 60) % 60);
let s = Math.floor(t % 60);
format.d = d < 10 ? '0' + d : d;
format.h = h < 10 ? '0' + h : h;
format.m = m < 10 ? '0' + m : m;
format.s = s < 10 ? '0' + s : s;
}
return format;
}
//获取时间距离当前时间
export function getDateToNewData(timestamp: number | string | Date = new Date().getTime()) {
if (typeof timestamp == 'string') {
timestamp = new Date(timestamp).getTime();
}
// 补全为13位
var arrTimestamp: Array<string> = (timestamp + '').split('');
for (var start = 0; start < 13; start++) {
if (!arrTimestamp[start]) {
arrTimestamp[start] = '0';
}
}
timestamp = Number(arrTimestamp.join('')) * 1;
var minute = 1000 * 60;
var hour = minute * 60;
var day = hour * 24;
var halfamonth = day * 15;
var month = day * 30;
var now = new Date().getTime();
var diffValue = now - timestamp;
// 如果本地时间反而小于变量时间
if (diffValue < 0) {
return '不久前';
}
// 计算差异时间的量级
var monthC = diffValue / month;
var weekC = diffValue / (7 * day);
var dayC = diffValue / day;
var hourC = diffValue / hour;
var minC = diffValue / minute;
// 数值补0方法
var zero = function (value: number) {
if (value < 10) {
return '0' + value;
}
return value;
};
// 使用
if (monthC > 12) {
// 超过1年,直接显示年月日
return (function () {
var date = new Date(timestamp);
return date.getFullYear() + '年' + zero(date.getMonth() + 1) + '月' + zero(date.getDate()) + '日';
})();
} else if (monthC >= 1) {
return parseInt(monthC + '') + "月前";
} else if (weekC >= 1) {
return parseInt(weekC + '') + "周前";
} else if (dayC >= 1) {
return parseInt(dayC + '') + "天前";
} else if (hourC >= 1) {
return parseInt(hourC + '') + "小时前";
} else if (minC >= 1) {
return parseInt(minC + '') + "分钟前";
}
return '刚刚';
}
/**
* 打电话
* @param {String<Number>} phoneNumber - 数字字符串
* @return {Promise}
*/
export function callPhone(phoneNumber = '') {
let num = phoneNumber.toString()
return new Promise((rs, rj) => {
uni.makePhoneCall({
phoneNumber: num,
success: () => rs(true),
fail: (err) => rj(err)
});
})
}
/**
* 调起客户端相机扫码。
* @param {Boolean} onlyFromCamera true 是否只允许相机扫码识别
* @param {Array<string>} scanType ['barCode', 'qrCode', 'datamatrix','datamatrix']
* @returns Promise 成功返回相关数据结构
*/
export function scanCode(onlyFromCamera = true, scanType = ['barCode', 'qrCode', 'datamatrix', 'datamatrix']): Promise<string | UniApp.ScanCodeSuccessRes> {
return new Promise((rs, rj) => {
// #ifdef H5
rj('不支持H5');
// #endif
// #ifndef H5
uni.scanCode({
onlyFromCamera: onlyFromCamera,
scanType: scanType,
success: (res) => rs(res),
fail: (error) => rj(error)
});
// #endif
})
}
/**
* 设置剪切板内容。
* @param {String} data
* @returns Promise true/false
*/
export function setClipboardData(data: string): Promise<string | boolean> {
return new Promise((rs, rj) => {
// #ifndef H5
uni.setClipboardData({
data: data,
success: () => rs(true),
fail: (error) => rj(error)
});
// #endif
// #ifdef H5
if (navigator.clipboard && window.isSecureContext) {
navigator.clipboard.writeText(data).then(() => rs(true)).catch((error => rs(error)))
} else {
const textArea = document.createElement('textarea')
textArea.style.opacity = "0"
textArea.style.position = "fixed"
textArea.style.top = "0px"
textArea.value = data
document.body.appendChild(textArea)
textArea.focus()
textArea.select()
document.execCommand('copy') ? rs(true) : rj("错误")
textArea.remove()
}
// #endif
})
}
/**
* 获取剪切板内容
* @returns Promise 剪切板内容
*/
export function getClipboardData(): Promise<boolean | string> {
return new Promise((rs, rj) => {
// #ifndef H5
uni.getClipboardData({
success: (res) => rs(res.data),
fail: (error) => rj(error)
});
// #endif
// #ifdef H5
console.error('H5无法获取剪切板内容')
rj('H5无法获取剪切板内容')
// #endif
})
}
/**
* 设置cookie数据
* @param {String} key 键值
* @param {String} data 值
* @returns Boolean
*/
export function setCookie(key: string, data: any) {
try {
uni.setStorageSync(key, data);
return true;
} catch (e) {
return false;
}
}
/**
* 删除一个本地cookie
* @param {String} key 键值
* @returns Boolean
*/
export function delCookie(key: string) {
try {
uni.removeStorageSync(key);
return true;
} catch (e) {
return false;
}
}
/**
* 获取一个cookie数据
* 如果存入的是对象,返回的也是对象。如果是string返回的也是字符串。
* @param {String} key 键
* @returns json/string
*/
export function getCookie(key: string) {
try {
const value = uni.getStorageSync(key);
try {
let val = JSON.parse(value)
return val;
} catch (e) {
return value;
}
} catch (e) {
return undefined;
}
}
/**
* 向地址连接追加参数。
* @param {string} uri 网址
* @param {string} key 字段
* @param {string} value 字段值
* @returns
*/
export function httpUrlAddKey(uri: string, key: string, value: string) {
if (!value) {
return uri;
}
var re = new RegExp("([?&])" + key + "=.*?(&|$)", "i");
var separator = uri.indexOf("?") !== -1 ? "&" : "?";
if (uri.match(re)) {
return uri.replace(re, "$1" + key + "=" + value + "$2");
} else {
return uri + separator + key + "=" + value;
}
}
/**
* 取url参数
* @param {string} uri 网址
* @param {string} key 字段
* @returns string
*/
export function getQueryString(url: string, key: string): string {
var query_string = url.substring(url.indexOf("?"));
if (!query_string) return "";
var re = /[?&]?([^=]+)=([^&]*)/g;
var tokens: any;
while (tokens = re.exec(query_string)) {
if (decodeURIComponent(tokens[1]) === key) {
return decodeURIComponent(tokens[2]);
break;
}
}
return "";
}
/**
*
* @param rdix 随机因子
* @param length 取的长度
* @param isAddStr 是否限制随机结果中的长度,不允许输出长度
* @returns String
*/
export function getUid(rdix = 1, length = 12, isAddStr = false) {
return Math.floor(Math.random() * rdix * Math.floor(Math.random() * Date.now())).toString(isAddStr ? 16 : 10).substring(0, length);
}
/*
防抖
防抖原理:在一定时间内,只有最后一次操作,再过wait毫秒后才执行函数
@param {Function} func 要执行的回调函数
@param {Number} wait 延迟的时间
@param{Boolean} immediate 是否要立即执行
*/
var timeout: any = getUid(1)
export function debounce(func: Function, wait = 500, immediate = false) {
// 清除定时器
if (timeout !== null) clearTimeout(timeout);
// 立即执行,此类情况一般用不到
if (immediate) {
timeout = setTimeout(() => {
timeout = null;
}, wait);
typeof func === "function" && func();
} else {
// 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法
timeout = getUid(1);
timeout = setTimeout(() => {
typeof func === "function" && func();
}, wait);
}
}
/**
* 节流
节流原理:在一定时间内,只能触发一次
* @param {Function} func 要执行的回调函数
* @param {Number} wait 延时的时间
* @param {Boolean} immediate 是否立即执行
* @return null
*/
var timesr: any = NaN, throttleFlag: boolean;
export function throttle(func: Function, wait = 500, immediate = true) {
if (immediate) {
if (!throttleFlag) {
throttleFlag = true;
// 如果是立即执行,则在wait毫秒内开始时执行
typeof func === 'function' && func();
timesr = setTimeout(() => {
throttleFlag = false;
}, wait);
}
} else {
if (!throttleFlag) {
throttleFlag = true
// 如果是非立即执行,则在wait毫秒内的结束处执行
timesr = setTimeout(() => {
throttleFlag = false
typeof func === 'function' && func();
}, wait);
}
}
};
/**等同:queryDom */
export function quereyDom(t: ComponentInternalInstance, node: string): Promise<UniApp.NodeInfo | UniApp.NodeInfo[]> {
return new Promise((res, rej) => {
// #ifdef APP-NVUE
const dom: any = uni.requireNativePlugin('dom')
setTimeout(function () {
node = node.replace(/^[#\.]/g, '')
dom.getComponentRect(t.refs[node], function (el: any) {
res(el?.size);
})
}, 60)
// #endif
// #ifndef APP-NVUE
const query = uni.createSelectorQuery().in(t);
query.select(node).boundingClientRect(el => {
res(el);
}).exec();
// #endif
})
}
/**
* 查询文档节点信息
* @param t Vue上下文对象
* @param node 提供带#的id比如:'#id',在nvue中应该是元素上写明ref='id'
* @returns vue页面返回查询的节点信息,nvue返回weex的节点信息。
*/
export const queryDom = quereyDom
/**
* 是否是手机号码
* @param phone 号码
* @returns Boolean
*/
export function isPhone(phone: string | number) {
let val = String(phone);
let reg = /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/
return !!val.match(reg);
}
/**
* 是否含有中文
* @param s 字符串
* @returns Boolean
*/
export function isChina(s: string) {
var patrn = /[\u4E00-\u9FA5]|[\uFE30-\uFFA0]/gi;
return !!patrn.exec(s);
}
/**
* 是否为空
* @description 判断是否是null,对象是否为空,数组是否为空。是否为 undefaind,是否为 “”空字符串。
* @param s 任意
*/
export function isEmpty(s: any) {
if (typeof s === 'string') {
s = s.trim();
}
if (s == "") return true
if (s == null) return true;
if (typeof s === 'undefined') return true;
if (Array.isArray(s)) {
if (s.length == 0) return true;
}
if (typeof s === 'object') {
if (Object.keys(s).length == 0) return true;
}
return false;
}
/**
* 是否邮箱
* @param s 字符串
* @returns Boolean
*/
export function isEmail(s: string) {
let reg = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;
return !!s.match(reg);
}
/**
* 是否身份证号
* @param val 字符号或者数字
* @returns Boolean
* @author https://cloud.tencent.com/developer/article/1114323
*/
export function isIdCard(val: string | number) {
val = String(val)
var p = /^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/;
var factor = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
var parity = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2];
var code = val.substring(17);
if (p.test(val)) {
var sum: number = 0;
for (var i = 0; i < 17; i++) {
let id: number | string | any = val[i]
sum += id * factor[i];
}
if (parity[sum % 11] == code.toUpperCase()) {
return true;
}
}
return false;
}
/**
* 是否车牌
* @description 蓝牌5位,绿牌6位。
* @param s 字符串
* @returns Boolean
*/
export function isIdCar(s: string) {
let reg = /^[京|沪|津|渝|鲁|冀|晋|蒙|辽|吉|黑|苏|浙|皖|闽|赣|豫|湘|鄂|粤|桂|琼|川|贵|云|藏|陕|甘|青|宁|新|港|澳|台|新|使]{1}[A-Z]{1}[A-Z_0-9]{5,6}$/
return !!s.match(reg);
}
/**
* 纯数字密码验证
* @param s 字符串或者数字
* @param len 最小长度,默认6
* @param maxLen 最大长度,默认20
* @returns Boolean
*/
export function isPasswordOfNumber(s: number | string, len = 6, maxLen = 20) {
s = String(s);
let reg = new RegExp(`^[0-9]{${len},${maxLen}}$`)
return !!s.match(reg)
}
/**
* 密码验证
* @param s 字符串或者数字
* @param len 最小长度,默认6
* @param maxLen 最大长度,默认20
* @param model 0数字和英文,1数字,英文必须包含,不允许有特殊字符,2数字和字母必须包含,可以有特殊字符。
* @returns Boolean
*/
export function isPasswordOfOther(s: string | number, len = 6, maxLen = 20, model = 0) {
s = String(s);
//密码至少包含 数字和英文,长度6-20
let reg = /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$/
//密码包含 数字,英文,字符中的两种以上,长度6-20
if (model === 1) {
reg = /^(?![0-9]+$)(?![a-z]+$)(?![A-Z]+$)(?!([^(0-9a-zA-Z)])+$).{6,20}$/
}
//至少包含数字跟字母,可以有字符
if (model === 2) {
reg = /(?=.*([a-zA-Z].*))(?=.*[0-9].*)[a-zA-Z0-9-*/+.~!@#$%^&*()]{6,20}$/
}
return !!s.match(reg)
}
/**
* 是否是一个有效的日期
* @param s 字符串,数字,日期对象
* @returns Boolean
*/
export function isDate(s: string | number | Date) {
if (s == null || typeof s === 'undefined' || !s) return false;
if (typeof s === 'string') {
//兼容ios,mac
s = s.replace('-', '/');
}
let d = new Date(s);
if (d.toString() == 'Invalid Date') return false;
return true;
}
/**
* 显示信息
* @param word 标题
* @param mask 不允许穿透
* @param icon 图标
*/
export function toast(word: string, mask: boolean = true, icon: any = 'none') {
// #ifndef MP-ALIPAY
uni.showToast({
mask: mask,
title: word,
icon: icon
})
// #endif
// #ifdef MP-ALIPAY
uni.showToast({
title: word,
icon: icon
})
// #endif
}
/**
* 获取屏幕窗口安全高度和宽度
* 注意是针对种屏幕的统一计算,统一高度,不再让uni获取有效高度而烦恼。
* 请一定要在onMounted或者onLoad中调用,否则不准确在h5端。
* @return {height,width,top,isCustomHeader,statusBarHeight,sysinfo}
*/
export function getWindow(): { width: number, height: number, top: number, bottom: number, statusBarHeight: number, isCustomHeader: Boolean, sysinfo: UniApp.GetSystemInfoResult } {
// let getsysinfoSync = getCookie("tmui_sysinfo")
// if(getsysinfoSync){
// return getsysinfoSync
// }
const sysinfo = uni.getSystemInfoSync();
let top = 0;
let height = sysinfo.windowHeight;
let nowPage = getCurrentPages().pop()
let isCustomHeader = false;
let pages = uni.$tm?.pages ?? []
let bottom = sysinfo.safeAreaInsets?.bottom ?? 0;
if (uni.$tm?.globalNavStyle == 'custom') {
isCustomHeader = true;
} else {
for (let i = 0; i < uni.$tm.pages.length; i++) {
if (nowPage?.route == uni.$tm.pages[i].path && uni.$tm.pages[i].custom == 'custom') {
isCustomHeader = true;
break;
}
}
}
// #ifdef H5
// 兼容说明:h5端第一次获取的高度和第二次获取的高度是有差异 的。
if (isCustomHeader) {
height = sysinfo.windowHeight + sysinfo.windowTop
} else {
top = 44
if (sysinfo.windowTop > 0) {
height = sysinfo.windowHeight;
} else {
height = sysinfo.windowHeight + sysinfo.windowTop
}
}
// #endif
let results = { bottom: bottom, height: height, width: sysinfo.windowWidth, top: top, isCustomHeader: isCustomHeader, statusBarHeight: sysinfo.statusBarHeight || 0, sysinfo: sysinfo };
return results;
}
type openUrlType = "navigate" | "redirect" | "reLaunch" | "switchTab" | "navigateBack"
/**
*
* @param url string 打开的页面路径
* @param type openUrlType "navigate"|"redirect"|"reLaunch"|"switchTab"|"navigateBack"
*/
export function routerTo(url: string, type: openUrlType = 'navigate') {
type openUrlTypeFun = "navigateTo" | "redirectTo" | "reLaunch" | "switchTab" | "navigateBack"
let funType = {
navigate: "navigateTo",
redirect: "redirectTo",
switchTab: "switchTab",
reLaunch: "reLaunch",
navigateBack: "navigateBack",
}
let fun = funType[type];
if (fun == 'navigateBack') {
uni.navigateBack({
fail(error) {
console.error(error)
}
})
} else if (fun == 'reLaunch') {
uni.reLaunch({
url: url,
fail(error) {
console.error(error)
}
})
} else if (fun == 'switchTab') {
uni.switchTab({
url: url,
fail(error) {
console.error(error)
}
})
} else if (fun == 'redirectTo') {
uni.redirectTo({
url: url,
fail(error) {
console.error(error)
}
})
} else if (fun == 'navigateTo') {
uni.navigateTo({
url: url,
fail(error) {
console.error(error)
}
})
}
}
/**
* 将rpx转换为px
* @param v 待转换的数字
* @param screenWidth 屏幕的宽度,如果不提供默认自动获取
* @return number
*/
export function torpx(v: number, screenWidth: number = 0) {
if (typeof screenWidth === 'undefined' || !screenWidth) {
screenWidth = uni.getSystemInfoSync().screenWidth;
}
let pixelRatio = 750 / screenWidth;
return Math.ceil(v * pixelRatio)
}
/**
* 将rpx转换为px
* @param v 待转换的数字
* @return number
*/
export function topx(v: number) {
return Math.ceil(uni.upx2px(Number(v)))
}
var lastTime = 0;
/**
* 在下一次前执行回调函数
* @param callback 回调函数
* @returns 一个id值,取消时cancelAnimationFrame(id)来取消
*/
export function requestAnimationFrame(callback: Function): number {
const currentTime = new Date().getTime();
const timeToCall = Math.max(0, 16 - (currentTime - lastTime));
const id = <any>setTimeout(() => {
callback(currentTime + timeToCall);
}, timeToCall);
lastTime = currentTime + timeToCall;
return id;
}
/**
* 取消回调执行
* @param id requestAnimationFrame产生的id
*/
export function cancelAnimationFrame(id: number): void {
clearTimeout(id)
}
/**
* 给定一个值,来填充边距所需要的数组值
* @param val any
* @returns [左,上,右,下]
*/
export function valToMarginAr(val:any):number[]{
let ar:number[] = [];
if(typeof val==='string'&&val){
ar = [Number(val)]
}else if(typeof val=== 'number'&&isNaN(Number(val))){
ar = [val]
}else if(typeof val ==='undefined'||typeof val === null || val==="" || val === undefined){
val = [0]
}else if(Array.isArray(val)){
ar = val.map(el=>Number(el))
};
if(ar.length==1){
ar = new Array(4).fill(ar[0])
}else if(ar.length==2){
ar = [...ar,...ar]
}else if(ar.length==3){
ar = [...ar,0]
}
return ar;
}
/**
* 给定一个值,来填充边距所需要的数组值
* @param val any
* @returns [左,上,右,下]
*/
export function valToRoundStrClass(val:number|number[]){
let dstr = ""
if(typeof val == 'number') return 'round-'+val
if (val.length == 1) return 'round-'+val
if (val.length == 2) return `round-tl-${val[0]} round-tr-${val[1]}`
if (val.length == 3) return `round-tl-${val[0]} round-tr-${val[1]} round-br-${val[2]} `
if (val.length == 4) return `round-tl-${val[0]} round-tr-${val[1]} round-br-${val[2]} round-bl-${val[2]}`
return dstr
}