import { isObject } from '@vue/shared' /** * @description 获取元素节点信息(在组件中的元素必须要传ctx) * @param { String } selector 选择器 '.app' | '#app' * @param { Boolean } all 是否多选 * @param { ctx } context 当前组件实例 */ export const getRect = (selector: string, all = false, context?: any) => { return new Promise((resolve, reject) => { let query = uni.createSelectorQuery() if (context) { query = uni.createSelectorQuery().in(context) } query[all ? 'selectAll' : 'select'](selector) .boundingClientRect(function (rect) { if (all && Array.isArray(rect) && rect.length) { return resolve(rect) } if (!all && rect) { return resolve(rect) } reject('找不到元素') }) .exec() }) } /** * @description 获取当前页面实例 */ export function currentPage() { const pages = getCurrentPages() const currentPage = pages[pages.length - 1] return currentPage || {} } /** * @description 后台选择链接专用跳转 */ interface Link { path: string name?: string type: string isTab: boolean query?: Record } export enum LinkTypeEnum { 'SHOP_PAGES' = 'shop', 'CUSTOM_LINK' = 'custom' } export function navigateTo(link: Link, navigateType: 'navigateTo' | 'reLaunch' = 'navigateTo') { const url = link.query ? `${link.path}?${objectToQuery(link.query)}` : link.path navigateType == 'navigateTo' && uni.navigateTo({ url }) navigateType == 'reLaunch' && uni.reLaunch({ url }) } /** * @description 是否为空 * @param {unknown} value * @return {Boolean} */ export const isEmpty = (value: unknown) => { return value == null && typeof value == 'undefined' } /** * @description 对象格式化为Query语法 * @param { Object } params * @return {string} Query语法 */ export function objectToQuery(params: Record): string { let query = '' for (const props of Object.keys(params)) { const value = params[props] const part = encodeURIComponent(props) + '=' if (!isEmpty(value)) { console.log(encodeURIComponent(props), isObject(value)) if (isObject(value)) { for (const key of Object.keys(value)) { if (!isEmpty(value[key])) { const params = props + '[' + key + ']' const subPart = encodeURIComponent(params) + '=' query += subPart + encodeURIComponent(value[key]) + '&' } } } else { query += part + encodeURIComponent(value) + '&' } } } return query.slice(0, -1) } /** * @description 格式化输出价格 * @param { string } price 价格 * @param { string } take 小数点操作 * @param { string } prec 小数位补 */ export function formatPrice({ price, take = 'all', prec = undefined }: any) { let [integer, decimals = ''] = (price + '').split('.') // 小数位补 if (prec !== undefined) { const LEN = decimals.length for (let i = prec - LEN; i > 0; --i) decimals += '0' decimals = decimals.substr(0, prec) } switch (take) { case 'int': return integer case 'dec': return decimals case 'all': return integer + '.' + decimals } } /** * @description 组合异步任务 * @param { string } task 异步任务 */ export function series(...task: Array<(_arg: any) => any>) { return function (): Promise { return new Promise((resolve, reject) => { const iteratorTask = task.values() const next = (res?: any) => { const nextTask = iteratorTask.next() if (nextTask.done) { resolve(res) } else { Promise.resolve(nextTask.value(res)).then(next).catch(reject) } } next() }) } } /** * @description 添加单位 * @param {String | Number} value 值 100 * @param {String} unit 单位 px em rem */ export const addUnit = (value: string | number, unit = 'rpx') => { return !Object.is(Number(value), NaN) ? `${value}${unit}` : value }