小程序初始提交
This commit is contained in:
24
cool-unix/uni_modules/cool-ui/hooks/component.ts
Normal file
24
cool-unix/uni_modules/cool-ui/hooks/component.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { parse } from "@/cool";
|
||||
import type { ClCascaderOption, ClListViewItem, ClTreeItem } from "../types";
|
||||
|
||||
export function useListView(data: UTSJSONObject[]) {
|
||||
return data.map((e) => {
|
||||
return parse<ClListViewItem>({
|
||||
...e,
|
||||
value: e
|
||||
})!;
|
||||
});
|
||||
}
|
||||
|
||||
export function useCascader(data: UTSJSONObject[]) {
|
||||
return data.map((e) => parse<ClCascaderOption>(e)!);
|
||||
}
|
||||
|
||||
export function useTree(data: UTSJSONObject[]) {
|
||||
return data.map((e) => {
|
||||
return parse<ClTreeItem>({
|
||||
...e,
|
||||
value: e
|
||||
})!;
|
||||
});
|
||||
}
|
||||
142
cool-unix/uni_modules/cool-ui/hooks/form.ts
Normal file
142
cool-unix/uni_modules/cool-ui/hooks/form.ts
Normal file
@@ -0,0 +1,142 @@
|
||||
import { computed, ref, type ComputedRef } from "vue";
|
||||
import type { ClFormRule, ClFormValidateError } from "../types";
|
||||
import { useParent } from "@/cool";
|
||||
|
||||
export class Form {
|
||||
public formRef = ref<ClFormComponentPublicInstance | null>(null);
|
||||
public disabled: ComputedRef<boolean>;
|
||||
|
||||
constructor() {
|
||||
// 获取 cl-form 实例
|
||||
if (this.formRef.value == null) {
|
||||
const ClForm = useParent<ClFormComponentPublicInstance>("cl-form");
|
||||
|
||||
if (ClForm != null) {
|
||||
this.formRef.value = ClForm;
|
||||
}
|
||||
}
|
||||
|
||||
// 监听表单是否禁用
|
||||
this.disabled = computed<boolean>(() => {
|
||||
if (this.formRef.value == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.formRef.value.disabled;
|
||||
});
|
||||
}
|
||||
|
||||
// 注册表单字段
|
||||
addField = (prop: string, rules: ClFormRule[]): void => {
|
||||
this.formRef.value!.addField(prop, rules);
|
||||
};
|
||||
|
||||
// 注销表单字段
|
||||
removeField = (prop: string): void => {
|
||||
this.formRef.value!.removeField(prop);
|
||||
};
|
||||
|
||||
// 获取字段值
|
||||
getValue = (prop: string): any | null => {
|
||||
return this.formRef.value!.getValue(prop);
|
||||
};
|
||||
|
||||
// 设置字段错误信息
|
||||
setError = (prop: string, error: string): void => {
|
||||
this.formRef.value!.setError(prop, error);
|
||||
};
|
||||
|
||||
// 获取字段错误信息
|
||||
getError = (prop: string): string => {
|
||||
return this.formRef.value!.getError(prop);
|
||||
};
|
||||
|
||||
// 获取所有错误信息
|
||||
getErrors = async (): Promise<ClFormValidateError[]> => {
|
||||
return this.formRef.value!.getErrors();
|
||||
};
|
||||
|
||||
// 移除字段错误信息
|
||||
removeError = (prop: string): void => {
|
||||
this.formRef.value!.removeError(prop);
|
||||
};
|
||||
|
||||
// 清除所有错误信息
|
||||
clearErrors = (): void => {
|
||||
this.formRef.value!.clearErrors();
|
||||
};
|
||||
|
||||
// 获取字段规则
|
||||
getRule = (prop: string): ClFormRule[] => {
|
||||
return this.formRef.value!.getRule(prop);
|
||||
};
|
||||
|
||||
// 设置字段规则
|
||||
setRule = (prop: string, rules: ClFormRule[]): void => {
|
||||
this.formRef.value!.setRule(prop, rules);
|
||||
};
|
||||
|
||||
// 移除字段规则
|
||||
removeRule = (prop: string): void => {
|
||||
this.formRef.value!.removeRule(prop);
|
||||
};
|
||||
|
||||
// 验证单个规则
|
||||
validateRule = (value: any | null, rule: ClFormRule): string | null => {
|
||||
return this.formRef.value!.validateRule(value, rule);
|
||||
};
|
||||
|
||||
// 清除所有验证
|
||||
clearValidate = (): void => {
|
||||
this.formRef.value!.clearValidate();
|
||||
};
|
||||
|
||||
// 验证单个字段
|
||||
validateField = (prop: string): string | null => {
|
||||
return this.formRef.value!.validateField(prop);
|
||||
};
|
||||
|
||||
// 验证整个表单
|
||||
validate = (callback: (valid: boolean, errors: ClFormValidateError[]) => void): void => {
|
||||
this.formRef.value!.validate(callback);
|
||||
};
|
||||
|
||||
// 检查字段是否存在错误
|
||||
isError = (prop: string): boolean => {
|
||||
return this.formRef.value!.getError(prop) != "";
|
||||
};
|
||||
}
|
||||
|
||||
class FormItem {
|
||||
public formItemRef = ref<ClFormItemComponentPublicInstance | null>(null);
|
||||
public isError: ComputedRef<boolean>;
|
||||
|
||||
constructor() {
|
||||
const { isError } = new Form();
|
||||
|
||||
if (this.formItemRef.value == null) {
|
||||
const ClFormItem = useParent<ClFormItemComponentPublicInstance>("cl-form-item");
|
||||
|
||||
if (ClFormItem != null) {
|
||||
this.formItemRef.value = ClFormItem;
|
||||
}
|
||||
}
|
||||
|
||||
// 监听表单字段是否验证错误
|
||||
this.isError = computed<boolean>(() => {
|
||||
if (this.formItemRef.value == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isError(this.formItemRef.value.prop);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export const useForm = (): Form => {
|
||||
return new Form();
|
||||
};
|
||||
|
||||
export const useFormItem = (): FormItem => {
|
||||
return new FormItem();
|
||||
};
|
||||
5
cool-unix/uni_modules/cool-ui/hooks/index.ts
Normal file
5
cool-unix/uni_modules/cool-ui/hooks/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export * from "./component";
|
||||
export * from "./form";
|
||||
export * from "./page";
|
||||
export * from "./size";
|
||||
export * from "./ui";
|
||||
60
cool-unix/uni_modules/cool-ui/hooks/page.ts
Normal file
60
cool-unix/uni_modules/cool-ui/hooks/page.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { router, scroller, useParent } from "@/cool";
|
||||
|
||||
class Page {
|
||||
pageRef: ClPageComponentPublicInstance | null = null;
|
||||
|
||||
constructor() {
|
||||
this.pageRef = useParent<ClPageComponentPublicInstance>("cl-page");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取页面路径
|
||||
* @returns 页面路径
|
||||
*/
|
||||
path = () => {
|
||||
return router.path();
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取滚动位置
|
||||
* @returns 滚动位置
|
||||
*/
|
||||
getScrollTop = (): number => {
|
||||
return this.pageRef!.scrollTop as number;
|
||||
};
|
||||
|
||||
/**
|
||||
* 滚动到指定位置
|
||||
* @param top 滚动位置
|
||||
*/
|
||||
scrollTo = (top: number) => {
|
||||
this.pageRef!.scrollTo(top);
|
||||
};
|
||||
|
||||
/**
|
||||
* 回到顶部
|
||||
*/
|
||||
scrollToTop = () => {
|
||||
this.pageRef!.scrollToTop();
|
||||
};
|
||||
|
||||
/**
|
||||
* 监听页面滚动
|
||||
* @param callback 回调函数
|
||||
*/
|
||||
onScroll = (callback: (top: number) => void) => {
|
||||
scroller.on(callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* 取消监听页面滚动
|
||||
* @param callback 回调函数
|
||||
*/
|
||||
offScroll = (callback: (top: number) => void) => {
|
||||
scroller.off(callback);
|
||||
};
|
||||
}
|
||||
|
||||
export function usePage(): Page {
|
||||
return new Page();
|
||||
}
|
||||
159
cool-unix/uni_modules/cool-ui/hooks/size.ts
Normal file
159
cool-unix/uni_modules/cool-ui/hooks/size.ts
Normal file
@@ -0,0 +1,159 @@
|
||||
import { computed, type ComputedRef } from "vue";
|
||||
import { config } from "../config";
|
||||
import { rpx2px } from "@/cool";
|
||||
|
||||
/**
|
||||
* 字号管理类
|
||||
* 用于处理文本大小的缩放和样式
|
||||
*/
|
||||
class Size {
|
||||
// 预设的字号类名
|
||||
public names = [
|
||||
"text-xs",
|
||||
"text-sm",
|
||||
"text-md",
|
||||
"text-lg",
|
||||
"text-xl",
|
||||
"text-2xl",
|
||||
"text-3xl",
|
||||
"text-4xl",
|
||||
"text-5xl",
|
||||
"text-6xl",
|
||||
"text-7xl",
|
||||
"text-8xl",
|
||||
"text-9xl"
|
||||
];
|
||||
|
||||
// 对应的字号大小
|
||||
public sizes = [20, 24, 28, 32, 36, 44, 52, 60, 72, 84, 96, 120, 152];
|
||||
|
||||
// 对应的行高
|
||||
public lineHeights = [28, 36, 44, 52, 52, 1, 1, 1, 1, 1, 1, 1, 1];
|
||||
|
||||
// 原始类名
|
||||
public className: ComputedRef<string> = computed(() => "");
|
||||
|
||||
// 计算后的类名
|
||||
public ptClassName: ComputedRef<string>;
|
||||
|
||||
constructor(cb: (() => string) | null) {
|
||||
this.className = computed(cb ?? (() => ""));
|
||||
|
||||
// 根据全局字号配置动态计算类名
|
||||
this.ptClassName = computed(() => {
|
||||
if (config.fontSize == null) {
|
||||
return this.className.value;
|
||||
}
|
||||
|
||||
const name = this.names[this.getIndex()];
|
||||
return this.className.value.replace(`-important-${name}`, "").replace(name, "");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全局字号缩放比例
|
||||
*/
|
||||
getScale = () => {
|
||||
return config.fontSize ?? 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据缩放比例计算rpx值
|
||||
* @param val - 需要转换的值
|
||||
*/
|
||||
getRpx = (val: number | string) => {
|
||||
const scale = this.getScale();
|
||||
|
||||
if (typeof val == "number") {
|
||||
return val * scale + "rpx";
|
||||
} else {
|
||||
const num = parseFloat(val);
|
||||
const unit = val.replace(`${num}`, "");
|
||||
|
||||
return num * scale + unit;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取px值
|
||||
* @param val - 需要转换的值 10、10rpx、10px
|
||||
* @returns 转换后的px值
|
||||
*/
|
||||
getPxValue = (val: number | string) => {
|
||||
const scale = this.getScale();
|
||||
|
||||
if (typeof val == "string") {
|
||||
const num = parseFloat(val);
|
||||
const unit = val.replace(`${num}`, "");
|
||||
|
||||
if (unit == "px") {
|
||||
return num * scale;
|
||||
} else {
|
||||
return rpx2px(num * scale);
|
||||
}
|
||||
} else {
|
||||
return rpx2px(val * scale);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取px值
|
||||
*/
|
||||
getPx = (val: number | string) => {
|
||||
return this.getPxValue(val) + "px";
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取当前字号在预设中的索引
|
||||
*/
|
||||
getIndex = () => {
|
||||
let index = this.names.findIndex((name) => {
|
||||
if (this.className.value.includes(name)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
// 默认使用 text-md (14px)
|
||||
if (index < 0) {
|
||||
index = 2;
|
||||
}
|
||||
|
||||
return index;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取最终的字号大小
|
||||
* @param size - 指定字号大小,为空则使用预设值
|
||||
*/
|
||||
getSize = (size: number | string | null): null | string => {
|
||||
// 如果未设置全局字号,且未指定size,直接返回null;否则返回对应rpx值
|
||||
if (config.fontSize == null && size == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.getRpx(size ?? this.sizes[this.getIndex()]);
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取当前行高
|
||||
*/
|
||||
getLineHeight = (): null | string => {
|
||||
// 未设置全局字号时返回null
|
||||
if (config.fontSize == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const lineHeight = this.lineHeights[this.getIndex()];
|
||||
return lineHeight == 1 ? `1` : this.getRpx(lineHeight);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 字号管理Hook
|
||||
* @param className - 类名
|
||||
*/
|
||||
export function useSize(cb: (() => string) | null = null): Size {
|
||||
return new Size(cb);
|
||||
}
|
||||
120
cool-unix/uni_modules/cool-ui/hooks/ui.ts
Normal file
120
cool-unix/uni_modules/cool-ui/hooks/ui.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
import { router } from "@/cool";
|
||||
import type { ClConfirmAction, ClConfirmOptions, ClToastOptions } from "../types";
|
||||
import { t } from "@/locale";
|
||||
|
||||
/**
|
||||
* UiInstance 类型定义
|
||||
* - showConfirm: 显示确认弹窗的方法
|
||||
* - showTips: 显示提示弹窗的方法
|
||||
*/
|
||||
export type UiInstance = {
|
||||
/**
|
||||
* 显示确认弹窗
|
||||
* @param options ClConfirmOptions 弹窗配置项
|
||||
*/
|
||||
showConfirm: (options: ClConfirmOptions) => void;
|
||||
|
||||
/**
|
||||
* 显示提示弹窗
|
||||
* @param message 提示消息
|
||||
* @param callback 回调函数,参数为用户操作类型
|
||||
*/
|
||||
showTips: (message: string, callback: (action: ClConfirmAction) => void) => void;
|
||||
|
||||
/**
|
||||
* 显示提示弹窗
|
||||
* @param options ClToastOptions 弹窗配置项
|
||||
*/
|
||||
showToast: (options: ClToastOptions) => void;
|
||||
};
|
||||
|
||||
/**
|
||||
* 存储每个页面对应的 UiInstance 实例
|
||||
* key: 当前页面路由
|
||||
* value: UiInstance 实例
|
||||
*/
|
||||
const list = new Map<string, UiInstance>();
|
||||
|
||||
/**
|
||||
* Ui 类,提供全局弹窗调用能力
|
||||
*/
|
||||
class Ui {
|
||||
/**
|
||||
* 获取当前页面的 UiInstance 实例
|
||||
* @returns UiInstance | undefined
|
||||
*/
|
||||
getInstance() {
|
||||
return list.get(router.path());
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示确认弹窗
|
||||
* @param options ClConfirmOptions 弹窗配置项
|
||||
*/
|
||||
showConfirm(options: ClConfirmOptions): void {
|
||||
const instance = this.getInstance();
|
||||
if (instance != null) {
|
||||
instance.showConfirm(options);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示提示弹窗
|
||||
* @param message 提示消息
|
||||
* @param callback 回调函数
|
||||
*/
|
||||
showTips(message: string, callback: (action: ClConfirmAction) => void): void {
|
||||
const instance = this.getInstance();
|
||||
if (instance != null) {
|
||||
instance.showTips(message, callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示提示弹窗
|
||||
* @param options ClToastOptions 弹窗配置项
|
||||
*/
|
||||
showToast(options: ClToastOptions): void {
|
||||
const instance = this.getInstance();
|
||||
if (instance != null) {
|
||||
instance.showToast(options);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示加载中弹窗
|
||||
* @param title 提示内容
|
||||
* @param mask 是否显示蒙层
|
||||
*/
|
||||
showLoading(title: string | null = null, mask: boolean | null = null): void {
|
||||
uni.showLoading({
|
||||
title: title ?? t("加载中"),
|
||||
mask: mask ?? true
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏加载中弹窗
|
||||
*/
|
||||
hideLoading(): void {
|
||||
uni.hideLoading();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Ui 实例(始终返回同一个 Ui 实例)
|
||||
* @returns Ui
|
||||
*/
|
||||
const ui = new Ui();
|
||||
|
||||
export function useUi() {
|
||||
return ui;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册当前页面的 UiInstance 实例
|
||||
* @param instance UiInstance
|
||||
*/
|
||||
export function createUi(instance: UiInstance): void {
|
||||
list.set(router.path(), instance);
|
||||
}
|
||||
Reference in New Issue
Block a user