mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
chore: make util function shorter, reduce file count for vite (#9595)
* chore: make util function shorter, reduce file count for vite * fix: test case
This commit is contained in:
parent
8d9ccfd8c7
commit
7c45604f8f
@ -1,7 +1,6 @@
|
||||
import Locale from '../../src/locale';
|
||||
import enUS from '../../src/locale/lang/en-US';
|
||||
import { camelize } from '../../src/utils/format/string';
|
||||
import { createTranslate } from '../../src/utils/create/translate';
|
||||
import { camelize, createTranslate } from '../../src/utils';
|
||||
import type { App } from 'vue';
|
||||
import type { Router } from 'vue-router';
|
||||
|
||||
|
@ -50,9 +50,7 @@ const DEFAULT_DATA: AddressEditInfo = {
|
||||
addressDetail: '',
|
||||
};
|
||||
|
||||
function isPostal(value: string) {
|
||||
return /^\d{6}$/.test(value);
|
||||
}
|
||||
const isPostal = (value: string) => /^\d{6}$/.test(value);
|
||||
|
||||
const props = {
|
||||
areaList: Object as PropType<AreaList>,
|
||||
|
@ -46,9 +46,7 @@ const INHERIT_PROPS = [
|
||||
'confirmButtonText',
|
||||
] as const;
|
||||
|
||||
function isOverseaCode(code: string) {
|
||||
return code[0] === '9';
|
||||
}
|
||||
const isOverseaCode = (code: string) => code[0] === '9';
|
||||
|
||||
const props = extend({}, pickerProps, {
|
||||
value: String,
|
||||
|
@ -4,9 +4,8 @@ const [name, bem, t] = createNamespace('calendar');
|
||||
|
||||
export { name, bem, t };
|
||||
|
||||
export function formatMonthTitle(date: Date) {
|
||||
return t('monthTitle', date.getFullYear(), date.getMonth() + 1);
|
||||
}
|
||||
export const formatMonthTitle = (date: Date) =>
|
||||
t('monthTitle', date.getFullYear(), date.getMonth() + 1);
|
||||
|
||||
export function compareMonth(date1: Date, date2: Date) {
|
||||
const year1 = date1.getFullYear();
|
||||
|
@ -6,9 +6,7 @@ const [name, bem] = createNamespace('circle');
|
||||
|
||||
let uid = 0;
|
||||
|
||||
function format(rate: string | number) {
|
||||
return Math.min(Math.max(+rate, 0), 100);
|
||||
}
|
||||
const format = (rate: string | number) => Math.min(Math.max(+rate, 0), 100);
|
||||
|
||||
function getPath(clockwise: boolean, viewBoxSize: number) {
|
||||
const sweepFlag = clockwise ? 1 : 0;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Ref } from 'vue';
|
||||
import { useHeight } from './use-height';
|
||||
import type { BEM } from '../utils/create/bem';
|
||||
import type { BEM } from '../utils/create';
|
||||
|
||||
export function usePlaceholder(contentRef: Ref<Element | undefined>, bem: BEM) {
|
||||
const height = useHeight(contentRef);
|
||||
|
@ -27,15 +27,11 @@ function getDate(timeStamp: number) {
|
||||
)}`;
|
||||
}
|
||||
|
||||
function formatDiscount(discount: number) {
|
||||
return (discount / 10).toFixed(discount % 10 === 0 ? 0 : 1);
|
||||
}
|
||||
const formatDiscount = (discount: number) =>
|
||||
(discount / 10).toFixed(discount % 10 === 0 ? 0 : 1);
|
||||
|
||||
function formatAmount(amount: number) {
|
||||
return (amount / 100).toFixed(
|
||||
amount % 100 === 0 ? 0 : amount % 10 === 0 ? 1 : 2
|
||||
);
|
||||
}
|
||||
const formatAmount = (amount: number) =>
|
||||
(amount / 100).toFixed(amount % 100 === 0 ? 0 : amount % 10 === 0 ? 1 : 2);
|
||||
|
||||
export default defineComponent({
|
||||
name,
|
||||
|
@ -43,6 +43,5 @@ export function getTrueValue(value: string | undefined): number {
|
||||
return parseInt(value, 10);
|
||||
}
|
||||
|
||||
export function getMonthEndDay(year: number, month: number): number {
|
||||
return 32 - new Date(year, month - 1, 32).getDate();
|
||||
}
|
||||
export const getMonthEndDay = (year: number, month: number): number =>
|
||||
32 - new Date(year, month - 1, 32).getDate();
|
||||
|
@ -5,9 +5,7 @@ import { CONFIG_PROVIDER_KEY } from '../config-provider/ConfigProvider';
|
||||
|
||||
const [name, bem] = createNamespace('icon');
|
||||
|
||||
function isImage(name?: string) {
|
||||
return name?.includes('/');
|
||||
}
|
||||
const isImage = (name?: string) => name?.includes('/');
|
||||
|
||||
export default defineComponent({
|
||||
name,
|
||||
|
@ -11,12 +11,11 @@ import { Image } from '../image';
|
||||
import { Loading } from '../loading';
|
||||
import { SwipeItem } from '../swipe-item';
|
||||
|
||||
function getDistance(touches: TouchList) {
|
||||
return Math.sqrt(
|
||||
const getDistance = (touches: TouchList) =>
|
||||
Math.sqrt(
|
||||
(touches[0].clientX - touches[1].clientX) ** 2 +
|
||||
(touches[0].clientY - touches[1].clientY) ** 2
|
||||
);
|
||||
}
|
||||
|
||||
const bem = createNamespace('image-preview')[1];
|
||||
|
||||
|
@ -8,7 +8,7 @@ import {
|
||||
createNamespace,
|
||||
} from '../utils';
|
||||
import { INDEX_BAR_KEY } from '../index-bar/IndexBar';
|
||||
import { getScrollTop, getRootScrollTop } from '../utils/dom/scroll';
|
||||
import { getScrollTop, getRootScrollTop } from '../utils/dom';
|
||||
|
||||
// Composables
|
||||
import { useRect, useParent } from '@vant/use';
|
||||
|
@ -13,9 +13,8 @@ import type { NotifyMessage, NotifyOptions } from './types';
|
||||
let timer: number;
|
||||
let instance: ComponentInstance;
|
||||
|
||||
function parseOptions(message: NotifyMessage | NotifyOptions) {
|
||||
return isObject(message) ? message : { message };
|
||||
}
|
||||
const parseOptions = (message: NotifyMessage | NotifyOptions) =>
|
||||
isObject(message) ? message : { message };
|
||||
|
||||
function initInstance() {
|
||||
({ instance } = mountComponent({
|
||||
@ -47,20 +46,18 @@ function Notify(options: NotifyMessage | NotifyOptions) {
|
||||
return instance;
|
||||
}
|
||||
|
||||
function defaultOptions() {
|
||||
return {
|
||||
type: 'danger',
|
||||
color: undefined,
|
||||
message: '',
|
||||
onClose: undefined,
|
||||
onClick: undefined,
|
||||
onOpened: undefined,
|
||||
duration: 3000,
|
||||
className: '',
|
||||
lockScroll: false,
|
||||
background: undefined,
|
||||
} as NotifyOptions;
|
||||
}
|
||||
const getDefaultOptions = (): NotifyOptions => ({
|
||||
type: 'danger',
|
||||
color: undefined,
|
||||
message: '',
|
||||
onClose: undefined,
|
||||
onClick: undefined,
|
||||
onOpened: undefined,
|
||||
duration: 3000,
|
||||
className: '',
|
||||
lockScroll: false,
|
||||
background: undefined,
|
||||
});
|
||||
|
||||
Notify.clear = () => {
|
||||
if (instance) {
|
||||
@ -68,14 +65,14 @@ Notify.clear = () => {
|
||||
}
|
||||
};
|
||||
|
||||
Notify.currentOptions = defaultOptions();
|
||||
Notify.currentOptions = getDefaultOptions();
|
||||
|
||||
Notify.setDefaultOptions = (options: NotifyOptions) => {
|
||||
extend(Notify.currentOptions, options);
|
||||
};
|
||||
|
||||
Notify.resetDefaultOptions = () => {
|
||||
Notify.currentOptions = defaultOptions();
|
||||
Notify.currentOptions = getDefaultOptions();
|
||||
};
|
||||
|
||||
Notify.Component = withInstall(VanNotify);
|
||||
|
@ -9,13 +9,11 @@ type PageItem = {
|
||||
active?: boolean;
|
||||
};
|
||||
|
||||
function makePage(
|
||||
const makePage = (
|
||||
number: number,
|
||||
text: string | number,
|
||||
active?: boolean
|
||||
): PageItem {
|
||||
return { number, text, active };
|
||||
}
|
||||
): PageItem => ({ number, text, active });
|
||||
|
||||
export type PaginationMode = 'simple' | 'multi';
|
||||
|
||||
|
@ -36,9 +36,8 @@ function getElementTranslateY(element: Element) {
|
||||
|
||||
export const PICKER_KEY = Symbol(name);
|
||||
|
||||
function isOptionDisabled(option: PickerOption) {
|
||||
return isObject(option) && option.disabled;
|
||||
}
|
||||
const isOptionDisabled = (option: PickerOption) =>
|
||||
isObject(option) && option.disabled;
|
||||
|
||||
export default defineComponent({
|
||||
name,
|
||||
|
@ -23,9 +23,8 @@ const [name, bem] = createNamespace('stepper');
|
||||
const LONG_PRESS_INTERVAL = 200;
|
||||
const LONG_PRESS_START_TIME = 600;
|
||||
|
||||
function equal(value1?: string | number, value2?: string | number) {
|
||||
return String(value1) === String(value2);
|
||||
}
|
||||
const isEqual = (value1?: string | number, value2?: string | number) =>
|
||||
String(value1) === String(value2);
|
||||
|
||||
export type StepperTheme = 'default' | 'round';
|
||||
|
||||
@ -107,7 +106,7 @@ export default defineComponent({
|
||||
const defaultValue = props.modelValue ?? props.defaultValue;
|
||||
const value = format(defaultValue);
|
||||
|
||||
if (!equal(value, props.modelValue)) {
|
||||
if (!isEqual(value, props.modelValue)) {
|
||||
emit('update:modelValue', value);
|
||||
}
|
||||
|
||||
@ -135,7 +134,7 @@ export default defineComponent({
|
||||
|
||||
const check = () => {
|
||||
const value = format(current.value);
|
||||
if (!equal(value, current.value)) {
|
||||
if (!isEqual(value, current.value)) {
|
||||
current.value = value;
|
||||
}
|
||||
};
|
||||
@ -185,7 +184,7 @@ export default defineComponent({
|
||||
|
||||
if (props.beforeChange) {
|
||||
input.value = String(current.value);
|
||||
} else if (!equal(value, formatted)) {
|
||||
} else if (!isEqual(value, formatted)) {
|
||||
input.value = formatted;
|
||||
}
|
||||
|
||||
@ -281,7 +280,7 @@ export default defineComponent({
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(value) => {
|
||||
if (!equal(value, current.value)) {
|
||||
if (!isEqual(value, current.value)) {
|
||||
current.value = format(value!);
|
||||
}
|
||||
}
|
||||
|
@ -9,13 +9,8 @@ const [name, bem] = createNamespace('uploader');
|
||||
|
||||
export { name, bem };
|
||||
|
||||
export function toArray<T>(item: T | T[]): T[] {
|
||||
if (Array.isArray(item)) {
|
||||
return item;
|
||||
}
|
||||
|
||||
return [item];
|
||||
}
|
||||
export const toArray = <T>(item: T | T[]): T[] =>
|
||||
Array.isArray(item) ? item : [item];
|
||||
|
||||
export function readFileContent(file: File, resultType: UploaderResultType) {
|
||||
return new Promise<string | void>((resolve) => {
|
||||
@ -73,9 +68,7 @@ export function filterFiles(
|
||||
|
||||
const IMAGE_REGEXP = /\.(jpeg|jpg|gif|png|svg|webp|jfif|bmp|dpg)/i;
|
||||
|
||||
export function isImageUrl(url: string): boolean {
|
||||
return IMAGE_REGEXP.test(url);
|
||||
}
|
||||
export const isImageUrl = (url: string): boolean => IMAGE_REGEXP.test(url);
|
||||
|
||||
export function isImageFile(item: UploaderFileListItem): boolean {
|
||||
// some special urls cannot be recognized
|
||||
|
71
packages/vant/src/utils/create.ts
Normal file
71
packages/vant/src/utils/create.ts
Normal file
@ -0,0 +1,71 @@
|
||||
import { get } from './basic';
|
||||
import { camelize } from './format';
|
||||
import { isFunction } from './validate';
|
||||
import locale from '../locale';
|
||||
|
||||
export function createTranslate(name: string) {
|
||||
const prefix = camelize(name) + '.';
|
||||
|
||||
return (path: string, ...args: any[]): any => {
|
||||
const messages = locale.messages();
|
||||
const message = get(messages, prefix + path) || get(messages, path);
|
||||
|
||||
return isFunction(message) ? message(...args) : message;
|
||||
};
|
||||
}
|
||||
|
||||
export type Translate = ReturnType<typeof createTranslate>;
|
||||
|
||||
export type Mod = string | { [key: string]: any };
|
||||
export type Mods = Mod | Mod[];
|
||||
|
||||
function genBem(name: string, mods?: Mods): string {
|
||||
if (!mods) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (typeof mods === 'string') {
|
||||
return ` ${name}--${mods}`;
|
||||
}
|
||||
|
||||
if (Array.isArray(mods)) {
|
||||
return mods.reduce<string>((ret, item) => ret + genBem(name, item), '');
|
||||
}
|
||||
|
||||
return Object.keys(mods).reduce(
|
||||
(ret, key) => ret + (mods[key] ? genBem(name, key) : ''),
|
||||
''
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* bem helper
|
||||
* b() // 'button'
|
||||
* b('text') // 'button__text'
|
||||
* b({ disabled }) // 'button button--disabled'
|
||||
* b('text', { disabled }) // 'button__text button__text--disabled'
|
||||
* b(['disabled', 'primary']) // 'button button--disabled button--primary'
|
||||
*/
|
||||
export function createBEM(name: string) {
|
||||
return (el?: Mods, mods?: Mods): Mods => {
|
||||
if (el && typeof el !== 'string') {
|
||||
mods = el;
|
||||
el = '';
|
||||
}
|
||||
|
||||
el = el ? `${name}__${el}` : name;
|
||||
|
||||
return `${el}${genBem(el, mods)}`;
|
||||
};
|
||||
}
|
||||
|
||||
export type BEM = ReturnType<typeof createBEM>;
|
||||
|
||||
export function createNamespace(name: string) {
|
||||
const prefixedName = `van-${name}`;
|
||||
return [
|
||||
prefixedName,
|
||||
createBEM(prefixedName),
|
||||
createTranslate(prefixedName),
|
||||
] as const;
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/**
|
||||
* bem helper
|
||||
* b() // 'button'
|
||||
* b('text') // 'button__text'
|
||||
* b({ disabled }) // 'button button--disabled'
|
||||
* b('text', { disabled }) // 'button__text button__text--disabled'
|
||||
* b(['disabled', 'primary']) // 'button button--disabled button--primary'
|
||||
*/
|
||||
|
||||
export type Mod = string | { [key: string]: any };
|
||||
export type Mods = Mod | Mod[];
|
||||
|
||||
function gen(name: string, mods?: Mods): string {
|
||||
if (!mods) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (typeof mods === 'string') {
|
||||
return ` ${name}--${mods}`;
|
||||
}
|
||||
|
||||
if (Array.isArray(mods)) {
|
||||
return mods.reduce<string>((ret, item) => ret + gen(name, item), '');
|
||||
}
|
||||
|
||||
return Object.keys(mods).reduce(
|
||||
(ret, key) => ret + (mods[key] ? gen(name, key) : ''),
|
||||
''
|
||||
);
|
||||
}
|
||||
|
||||
export function createBEM(name: string) {
|
||||
return function (el?: Mods, mods?: Mods): Mods {
|
||||
if (el && typeof el !== 'string') {
|
||||
mods = el;
|
||||
el = '';
|
||||
}
|
||||
|
||||
el = el ? `${name}__${el}` : name;
|
||||
|
||||
return `${el}${gen(el, mods)}`;
|
||||
};
|
||||
}
|
||||
|
||||
export type BEM = ReturnType<typeof createBEM>;
|
@ -1,11 +0,0 @@
|
||||
import { createBEM } from './bem';
|
||||
import { createTranslate } from './translate';
|
||||
|
||||
export function createNamespace(name: string) {
|
||||
const prefixedName = `van-${name}`;
|
||||
return [
|
||||
prefixedName,
|
||||
createBEM(prefixedName),
|
||||
createTranslate(prefixedName),
|
||||
] as const;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
import { get } from '../base';
|
||||
import { camelize } from '../format/string';
|
||||
import { isFunction } from '../validate';
|
||||
import locale from '../../locale';
|
||||
|
||||
export function createTranslate(name: string) {
|
||||
const prefix = camelize(name) + '.';
|
||||
|
||||
return function (path: string, ...args: any[]): any {
|
||||
const messages = locale.messages();
|
||||
const message = get(messages, prefix + path) || get(messages, path);
|
||||
|
||||
return isFunction(message) ? message(...args) : message;
|
||||
};
|
||||
}
|
||||
|
||||
export type Translate = ReturnType<typeof createTranslate>;
|
@ -1,10 +1,9 @@
|
||||
import { isIOS as checkIsIOS } from '../validate';
|
||||
import { unref, Ref } from 'vue';
|
||||
import { isIOS as checkIsIOS } from './validate';
|
||||
|
||||
export type ScrollElement = Element | Window;
|
||||
|
||||
function isWindow(val: unknown): val is Window {
|
||||
return val === window;
|
||||
}
|
||||
const isWindow = (val: unknown): val is Window => val === window;
|
||||
|
||||
export function getScrollTop(el: ScrollElement): number {
|
||||
const top = 'scrollTop' in el ? el.scrollTop : el.pageYOffset;
|
||||
@ -68,3 +67,41 @@ export function resetScroll() {
|
||||
setRootScrollTop(getRootScrollTop());
|
||||
}
|
||||
}
|
||||
|
||||
export const stopPropagation = (event: Event) => event.stopPropagation();
|
||||
|
||||
export function preventDefault(event: Event, isStopPropagation?: boolean) {
|
||||
/* istanbul ignore else */
|
||||
if (typeof event.cancelable !== 'boolean' || event.cancelable) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
if (isStopPropagation) {
|
||||
stopPropagation(event);
|
||||
}
|
||||
}
|
||||
|
||||
export function trigger(target: Element, type: string) {
|
||||
const inputEvent = document.createEvent('HTMLEvents');
|
||||
inputEvent.initEvent(type, true, true);
|
||||
target.dispatchEvent(inputEvent);
|
||||
}
|
||||
|
||||
export function isHidden(
|
||||
elementRef: HTMLElement | Ref<HTMLElement | undefined>
|
||||
) {
|
||||
const el = unref(elementRef);
|
||||
if (!el) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const style = window.getComputedStyle(el);
|
||||
const hidden = style.display === 'none';
|
||||
|
||||
// offsetParent returns null in the following situations:
|
||||
// 1. The element or its parent element has the display property set to none.
|
||||
// 2. The element has the position property set to fixed
|
||||
const parentHidden = el.offsetParent === null && style.position !== 'fixed';
|
||||
|
||||
return hidden || parentHidden;
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
export function stopPropagation(event: Event) {
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
export function preventDefault(event: Event, isStopPropagation?: boolean) {
|
||||
/* istanbul ignore else */
|
||||
if (typeof event.cancelable !== 'boolean' || event.cancelable) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
if (isStopPropagation) {
|
||||
stopPropagation(event);
|
||||
}
|
||||
}
|
||||
|
||||
export function trigger(target: Element, type: string) {
|
||||
const inputEvent = document.createEvent('HTMLEvents');
|
||||
inputEvent.initEvent(type, true, true);
|
||||
target.dispatchEvent(inputEvent);
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
import { unref, Ref } from 'vue';
|
||||
|
||||
export function isHidden(
|
||||
elementRef: HTMLElement | Ref<HTMLElement | undefined>
|
||||
) {
|
||||
const el = unref(elementRef);
|
||||
if (!el) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const style = window.getComputedStyle(el);
|
||||
const hidden = style.display === 'none';
|
||||
|
||||
// offsetParent returns null in the following situations:
|
||||
// 1. The element or its parent element has the display property set to none.
|
||||
// 2. The element has the position property set to fixed
|
||||
const parentHidden = el.offsetParent === null && style.position !== 'fixed';
|
||||
|
||||
return hidden || parentHidden;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import { CSSProperties } from 'vue';
|
||||
import { inBrowser } from '../base';
|
||||
import { isDef, isNumeric } from '../validate';
|
||||
import { inBrowser } from './basic';
|
||||
import { isDef, isNumeric } from './validate';
|
||||
|
||||
export function addUnit(value?: string | number): string | undefined {
|
||||
if (!isDef(value)) {
|
||||
@ -79,3 +79,70 @@ export function unitToPx(value: string | number): number {
|
||||
|
||||
return parseFloat(value);
|
||||
}
|
||||
|
||||
const camelizeRE = /-(\w)/g;
|
||||
|
||||
export const camelize = (str: string): string =>
|
||||
str.replace(camelizeRE, (_, c) => c.toUpperCase());
|
||||
|
||||
export const kebabCase = (str: string) =>
|
||||
str
|
||||
.replace(/([A-Z])/g, '-$1')
|
||||
.toLowerCase()
|
||||
.replace(/^-/, '');
|
||||
|
||||
export function padZero(num: number | string, targetLength = 2): string {
|
||||
let str = num + '';
|
||||
|
||||
while (str.length < targetLength) {
|
||||
str = '0' + str;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/** clamps number within the inclusive lower and upper bounds */
|
||||
export const clamp = (num: number, min: number, max: number): number =>
|
||||
Math.min(Math.max(num, min), max);
|
||||
|
||||
function trimExtraChar(value: string, char: string, regExp: RegExp) {
|
||||
const index = value.indexOf(char);
|
||||
|
||||
if (index === -1) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (char === '-' && index !== 0) {
|
||||
return value.slice(0, index);
|
||||
}
|
||||
|
||||
return value.slice(0, index + 1) + value.slice(index).replace(regExp, '');
|
||||
}
|
||||
|
||||
export function formatNumber(
|
||||
value: string,
|
||||
allowDot = true,
|
||||
allowMinus = true
|
||||
) {
|
||||
if (allowDot) {
|
||||
value = trimExtraChar(value, '.', /\./g);
|
||||
} else {
|
||||
value = value.split('.')[0];
|
||||
}
|
||||
|
||||
if (allowMinus) {
|
||||
value = trimExtraChar(value, '-', /-/g);
|
||||
} else {
|
||||
value = value.replace(/-/, '');
|
||||
}
|
||||
|
||||
const regExp = allowDot ? /[^-0-9.]/g : /[^-0-9]/g;
|
||||
|
||||
return value.replace(regExp, '');
|
||||
}
|
||||
|
||||
// add num and avoid float number
|
||||
export function addNumber(num1: number, num2: number) {
|
||||
const cardinal = 10 ** 10;
|
||||
return Math.round((num1 + num2) * cardinal) / cardinal;
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
/** clamps number within the inclusive lower and upper bounds */
|
||||
export function clamp(num: number, min: number, max: number): number {
|
||||
return Math.min(Math.max(num, min), max);
|
||||
}
|
||||
|
||||
function trimExtraChar(value: string, char: string, regExp: RegExp) {
|
||||
const index = value.indexOf(char);
|
||||
|
||||
if (index === -1) {
|
||||
return value;
|
||||
}
|
||||
|
||||
if (char === '-' && index !== 0) {
|
||||
return value.slice(0, index);
|
||||
}
|
||||
|
||||
return value.slice(0, index + 1) + value.slice(index).replace(regExp, '');
|
||||
}
|
||||
|
||||
export function formatNumber(
|
||||
value: string,
|
||||
allowDot = true,
|
||||
allowMinus = true
|
||||
) {
|
||||
if (allowDot) {
|
||||
value = trimExtraChar(value, '.', /\./g);
|
||||
} else {
|
||||
value = value.split('.')[0];
|
||||
}
|
||||
|
||||
if (allowMinus) {
|
||||
value = trimExtraChar(value, '-', /-/g);
|
||||
} else {
|
||||
value = value.replace(/-/, '');
|
||||
}
|
||||
|
||||
const regExp = allowDot ? /[^-0-9.]/g : /[^-0-9]/g;
|
||||
|
||||
return value.replace(regExp, '');
|
||||
}
|
||||
|
||||
// add num and avoid float number
|
||||
export function addNumber(num1: number, num2: number) {
|
||||
const cardinal = 10 ** 10;
|
||||
return Math.round((num1 + num2) * cardinal) / cardinal;
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
const camelizeRE = /-(\w)/g;
|
||||
|
||||
export function camelize(str: string): string {
|
||||
return str.replace(camelizeRE, (_, c) => c.toUpperCase());
|
||||
}
|
||||
|
||||
export function kebabCase(str: string) {
|
||||
return str
|
||||
.replace(/([A-Z])/g, '-$1')
|
||||
.toLowerCase()
|
||||
.replace(/^-/, '');
|
||||
}
|
||||
|
||||
export function padZero(num: number | string, targetLength = 2): string {
|
||||
let str = num + '';
|
||||
|
||||
while (str.length < targetLength) {
|
||||
str = '0' + str;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
@ -1,12 +1,8 @@
|
||||
export * from './base';
|
||||
export * from './basic';
|
||||
export * from './dom';
|
||||
export * from './create';
|
||||
export * from './format';
|
||||
export * from './constant';
|
||||
export * from './validate';
|
||||
export * from './dom/style';
|
||||
export * from './dom/event';
|
||||
export * from './dom/scroll';
|
||||
export * from './interceptor';
|
||||
export * from './with-install';
|
||||
export * from './format/unit';
|
||||
export * from './format/number';
|
||||
export * from './format/string';
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { createBEM } from '../create/bem';
|
||||
import { createBEM } from '../create';
|
||||
|
||||
test('bem', () => {
|
||||
const bem = createBEM('button');
|
||||
|
@ -1,10 +1,8 @@
|
||||
import { get, noop } from '../basic';
|
||||
import { deepClone } from '../deep-clone';
|
||||
import { deepAssign } from '../deep-assign';
|
||||
import { get, noop } from '..';
|
||||
import { isDef, isMobile, isNumeric } from '../validate';
|
||||
import { camelize } from '../format/string';
|
||||
import { formatNumber } from '../format/number';
|
||||
import { addUnit, unitToPx } from '../format/unit';
|
||||
import { addUnit, unitToPx, camelize, formatNumber } from '../format';
|
||||
|
||||
test('deepClone', () => {
|
||||
const a = { foo: 0 };
|
||||
|
@ -1,28 +1,21 @@
|
||||
import { inBrowser } from './base';
|
||||
import { inBrowser } from './basic';
|
||||
|
||||
export function isDef<T>(val: T): val is NonNullable<T> {
|
||||
return val !== undefined && val !== null;
|
||||
}
|
||||
export const isDef = <T>(val: T): val is NonNullable<T> =>
|
||||
val !== undefined && val !== null;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||
export function isFunction(val: unknown): val is Function {
|
||||
return typeof val === 'function';
|
||||
}
|
||||
export const isFunction = (val: unknown): val is Function =>
|
||||
typeof val === 'function';
|
||||
|
||||
export function isObject(val: unknown): val is Record<any, any> {
|
||||
return val !== null && typeof val === 'object';
|
||||
}
|
||||
export const isObject = (val: unknown): val is Record<any, any> =>
|
||||
val !== null && typeof val === 'object';
|
||||
|
||||
export function isPromise<T = any>(val: unknown): val is Promise<T> {
|
||||
return isObject(val) && isFunction(val.then) && isFunction(val.catch);
|
||||
}
|
||||
export const isPromise = <T = any>(val: unknown): val is Promise<T> =>
|
||||
isObject(val) && isFunction(val.then) && isFunction(val.catch);
|
||||
|
||||
export function isDate(val: unknown): val is Date {
|
||||
return (
|
||||
Object.prototype.toString.call(val) === '[object Date]' &&
|
||||
!Number.isNaN((val as Date).getTime())
|
||||
);
|
||||
}
|
||||
export const isDate = (val: unknown): val is Date =>
|
||||
Object.prototype.toString.call(val) === '[object Date]' &&
|
||||
!Number.isNaN((val as Date).getTime());
|
||||
|
||||
export function isMobile(value: string): boolean {
|
||||
value = value.replace(/[^-|\d]/g, '');
|
||||
@ -31,12 +24,10 @@ export function isMobile(value: string): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
export function isNumeric(val: string | number): val is string {
|
||||
return typeof val === 'number' || /^\d+(\.\d+)?$/.test(val);
|
||||
}
|
||||
export const isNumeric = (val: string | number): val is string =>
|
||||
typeof val === 'number' || /^\d+(\.\d+)?$/.test(val);
|
||||
|
||||
export function isIOS(): boolean {
|
||||
return inBrowser
|
||||
export const isIOS = (): boolean =>
|
||||
inBrowser
|
||||
? /ios|iphone|ipad|ipod/.test(navigator.userAgent.toLowerCase())
|
||||
: false;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { App } from 'vue';
|
||||
import { camelize } from './format/string';
|
||||
import { camelize } from './format';
|
||||
|
||||
// https://github.com/youzan/vant/issues/8302
|
||||
type EventShim = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user