调整组件类型

This commit is contained in:
icssoa
2025-09-11 11:20:12 +08:00
parent 051469750c
commit 456b857249
10 changed files with 68 additions and 104 deletions

View File

@@ -1,4 +1,3 @@
import { ref, type Ref } from "vue";
import { forEach, forInObject, isArray, isObject, isString } from "./comm";
/**
@@ -112,11 +111,11 @@ export const parseClass = (data: any): string => {
*/
export function parseToObject<T>(data: T): UTSJSONObject {
// #ifdef APP-ANDROID
return JSON.parseObject(JSON.stringify(data)!)!;
return JSON.parseObject(JSON.stringify(data ?? {})!)!;
// #endif
// #ifndef APP-ANDROID
return JSON.parse(JSON.stringify(data)) as UTSJSONObject;
return JSON.parse(JSON.stringify(data || {})) as UTSJSONObject;
// #endif
}

View File

@@ -52,8 +52,7 @@
<demo-item :label="t('自定义')">
<cl-text
:pt="{
className:
'mb-3 text-sm p-3 bg-surface-100 dark:!bg-surface-700 rounded-lg'
className: 'mb-3 text-sm p-3 bg-surface-100 dark:!bg-surface-700 rounded-lg'
}"
v-if="form.selected4 != null && isShowValue"
>

View File

@@ -1,10 +1,7 @@
<template>
<cl-select-trigger
v-if="showTrigger"
:pt="{
className: pt.trigger?.className,
icon: pt.trigger?.icon
}"
:pt="ptTrigger"
:placeholder="placeholder"
:disabled="disabled"
:focus="popupRef?.isOpen"
@@ -13,18 +10,7 @@
@clear="clear"
></cl-select-trigger>
<cl-popup
ref="popupRef"
v-model="visible"
:title="title"
:pt="{
className: pt.popup?.className,
header: pt.popup?.header,
container: pt.popup?.container,
mask: pt.popup?.mask,
draw: pt.popup?.draw
}"
>
<cl-popup ref="popupRef" v-model="visible" :title="title" :pt="ptPopup">
<view class="cl-select-popup" @touchmove.stop>
<slot name="prepend"></slot>
@@ -70,7 +56,7 @@
<script setup lang="ts">
import { ref, computed, type PropType } from "vue";
import type { ClCalendarDateConfig, ClCalendarMode } from "../../types";
import { isEmpty, parsePt } from "@/cool";
import { isEmpty, parsePt, parseToObject } from "@/cool";
import type { ClSelectTriggerPassThrough } from "../cl-select-trigger/props";
import type { ClPopupPassThrough } from "../cl-popup/props";
import { t } from "@/locale";
@@ -178,6 +164,12 @@ type PassThrough = {
// 解析透传样式配置
const pt = computed(() => parsePt<PassThrough>(props.pt));
// 解析触发器透传样式配置
const ptTrigger = computed(() => parseToObject(pt.value.trigger));
// 解析弹窗透传样式配置
const ptPopup = computed(() => parseToObject(pt.value.popup));
// 当前选中的值
const value = ref<string | null>(null);

View File

@@ -1,10 +1,7 @@
<template>
<cl-select-trigger
v-if="showTrigger"
:pt="{
className: pt.trigger?.className,
icon: pt.trigger?.icon
}"
:pt="ptTrigger"
:placeholder="placeholder"
:disabled="disabled"
:focus="popupRef?.isOpen"
@@ -13,19 +10,7 @@
@clear="clear"
></cl-select-trigger>
<cl-popup
ref="popupRef"
v-model="visible"
:title="title"
:pt="{
className: pt.popup?.className,
header: pt.popup?.header,
container: pt.popup?.container,
mask: pt.popup?.mask,
draw: pt.popup?.draw
}"
@closed="onClosed"
>
<cl-popup ref="popupRef" v-model="visible" :title="title" :pt="ptPopup" @closed="onClosed">
<view class="cl-select-popup" @touchmove.stop>
<view class="cl-select-popup__labels">
<cl-tag
@@ -93,7 +78,16 @@
<script setup lang="ts">
import { ref, computed, type PropType, nextTick } from "vue";
import { isDark, isEmpty, isMp, isNull, parseClass, parsePt, parseRpx } from "@/cool";
import {
isDark,
isEmpty,
isMp,
isNull,
parseClass,
parsePt,
parseRpx,
parseToObject
} from "@/cool";
import type { ClSelectTriggerPassThrough } from "../cl-select-trigger/props";
import type { ClPopupPassThrough } from "../cl-popup/props";
import { t } from "@/locale";
@@ -227,6 +221,12 @@ type PassThrough = {
*/
const pt = computed(() => parsePt<PassThrough>(props.pt));
// 解析触发器透传样式配置
const ptTrigger = computed(() => parseToObject(pt.value.trigger));
// 解析弹窗透传样式配置
const ptPopup = computed(() => parseToObject(pt.value.popup));
/**
* 当前显示的级联层级索引
* 用于控制 swiper 组件显示哪一级的选项列表

View File

@@ -1,10 +1,7 @@
<template>
<cl-select-trigger
v-if="showTrigger"
:pt="{
className: pt.trigger?.className,
icon: pt.trigger?.icon
}"
:pt="ptTrigger"
:placeholder="placeholder"
:disabled="disabled"
:focus="popupRef?.isOpen"
@@ -14,19 +11,7 @@
@clear="clear"
></cl-select-trigger>
<cl-popup
ref="popupRef"
v-model="visible"
:title="title"
:pt="{
className: pt.popup?.className,
header: pt.popup?.header,
container: pt.popup?.container,
mask: pt.popup?.mask,
draw: pt.popup?.draw
}"
@closed="onClosed"
>
<cl-popup ref="popupRef" v-model="visible" :title="title" :pt="ptPopup" @closed="onClosed">
<view class="cl-select-popup" @touchmove.stop>
<view class="cl-select-popup__range" v-if="rangeable">
<view class="cl-select-popup__range-shortcuts" v-if="showShortcuts">
@@ -136,7 +121,7 @@
<script setup lang="ts">
import { ref, computed, type PropType, watch, nextTick } from "vue";
import type { ClSelectDateShortcut, ClSelectOption } from "../../types";
import { dayUts, isDark, isEmpty, isNull, parsePt } from "@/cool";
import { dayUts, isDark, isEmpty, isNull, parsePt, parseToObject } from "@/cool";
import type { ClSelectTriggerPassThrough } from "../cl-select-trigger/props";
import type { ClPopupPassThrough } from "../cl-popup/props";
import { t } from "@/locale";
@@ -283,6 +268,12 @@ type PassThrough = {
// 解析透传样式配置,返回合并后的样式对象
const pt = computed(() => parsePt<PassThrough>(props.pt));
// 解析触发器透传样式配置
const ptTrigger = computed(() => parseToObject(pt.value.trigger));
// 解析弹窗透传样式配置
const ptPopup = computed(() => parseToObject(pt.value.popup));
// 格式化类型
const formatType = computed(() => {
switch (props.type) {

View File

@@ -1,10 +1,7 @@
<template>
<cl-select-trigger
v-if="showTrigger"
:pt="{
className: pt.trigger?.className,
icon: pt.trigger?.icon
}"
:pt="ptTrigger"
:placeholder="placeholder"
:disabled="disabled"
:focus="popupRef?.isOpen"
@@ -14,18 +11,7 @@
@clear="clear"
></cl-select-trigger>
<cl-popup
ref="popupRef"
v-model="visible"
:title="title"
:pt="{
className: pt.popup?.className,
header: pt.popup?.header,
container: pt.popup?.container,
mask: pt.popup?.mask,
draw: pt.popup?.draw
}"
>
<cl-popup ref="popupRef" v-model="visible" :title="title" :pt="ptPopup">
<view class="cl-select-popup" @touchmove.stop>
<view class="cl-select-popup__picker">
<cl-picker-view
@@ -67,7 +53,7 @@
<script setup lang="ts">
import { ref, computed, type PropType, watch } from "vue";
import type { ClSelectOption } from "../../types";
import { isEmpty, isNull, parsePt } from "@/cool";
import { isEmpty, isNull, parsePt, parseToObject } from "@/cool";
import type { ClSelectTriggerPassThrough } from "../cl-select-trigger/props";
import type { ClPopupPassThrough } from "../cl-popup/props";
import { t } from "@/locale";
@@ -160,6 +146,12 @@ type PassThrough = {
// 解析透传样式配置
const pt = computed(() => parsePt<PassThrough>(props.pt));
// 解析触发器透传样式配置
const ptTrigger = computed(() => parseToObject(pt.value.trigger));
// 解析弹窗透传样式配置
const ptPopup = computed(() => parseToObject(pt.value.popup));
// 标签格式化
const labelFormat = computed(() => {
if (props.labelFormat != null) {

View File

@@ -1,10 +1,7 @@
<template>
<cl-select-trigger
v-if="showTrigger"
:pt="{
className: pt.trigger?.className,
icon: pt.trigger?.icon
}"
:pt="ptTrigger"
:placeholder="placeholder"
:disabled="disabled"
:focus="popupRef?.isOpen"
@@ -13,18 +10,7 @@
@clear="clear"
></cl-select-trigger>
<cl-popup
ref="popupRef"
v-model="visible"
:title="title"
:pt="{
className: pt.popup?.className,
header: pt.popup?.header,
container: pt.popup?.container,
mask: pt.popup?.mask,
draw: pt.popup?.draw
}"
>
<cl-popup ref="popupRef" v-model="visible" :title="title" :pt="ptPopup">
<view class="cl-select-popup" @touchmove.stop>
<slot name="prepend"></slot>
@@ -67,8 +53,8 @@
<script setup lang="ts">
import { ref, computed, type PropType, watch } from "vue";
import type { ClSelectOption } from "../../types";
import { isEmpty, isNull, parsePt } from "@/cool";
import type { ClSelectOption, ClSelectValue } from "../../types";
import { isEmpty, isNull, parsePt, parseToObject } from "@/cool";
import type { ClSelectTriggerPassThrough } from "../cl-select-trigger/props";
import type { ClPopupPassThrough } from "../cl-popup/props";
import { t } from "@/locale";
@@ -82,9 +68,6 @@ defineSlots<{
append(): any;
}>();
// 值类型
type Value = string[] | number[] | number | string | null;
// 组件属性定义
const props = defineProps({
// 透传样式配置
@@ -94,7 +77,7 @@ const props = defineProps({
},
// 选择器的值
modelValue: {
type: [Array, Number, String] as PropType<Value>,
type: [Array, Number, String] as PropType<ClSelectValue>,
default: null
},
// 选择器标题
@@ -169,6 +152,12 @@ type PassThrough = {
// 解析透传样式配置
const pt = computed(() => parsePt<PassThrough>(props.pt));
// 解析触发器透传样式配置
const ptTrigger = computed(() => parseToObject(pt.value.trigger));
// 解析弹窗透传样式配置
const ptPopup = computed(() => parseToObject(pt.value.popup));
// 当前选中的值
const value = ref<any[]>([]);
@@ -248,7 +237,7 @@ function getValue() {
}
// 解析值
function setValue(val: Value) {
function setValue(val: ClSelectValue) {
// 声明选中值数组
let _value: any[];
@@ -348,10 +337,10 @@ function onChange(a: number[]) {
const visible = ref(false);
// 选择回调函数
let callback: ((value: Value) => void) | null = null;
let callback: ((value: ClSelectValue) => void) | null = null;
// 打开选择器
function open(cb: ((value: Value) => void) | null = null) {
function open(cb: ((value: ClSelectValue) => void) | null = null) {
visible.value = true;
// 设置值
@@ -400,7 +389,7 @@ function confirm() {
// 监听modelValue变化
watch(
computed(() => props.modelValue),
(val: Value) => {
(val: ClSelectValue) => {
setValue(val);
},
{

View File

@@ -1,4 +1,4 @@
import type { ClSelectOption } from "../../types";
import type { ClSelectOption, ClSelectValue } from "../../types";
import type { ClSelectTriggerPassThrough } from "../cl-select-trigger/props";
import type { ClPopupPassThrough } from "../cl-popup/props";
@@ -10,7 +10,7 @@ export type ClSelectPassThrough = {
export type ClSelectProps = {
className?: string;
pt?: ClSelectPassThrough;
modelValue?: Value;
modelValue?: ClSelectValue;
title?: string;
placeholder?: string;
options?: ClSelectOption[];

View File

@@ -1,4 +1,4 @@
import type { ClActionSheetItem, ClActionSheetOptions, PassThroughProps, Type, ClButtonType, Size, ClCalendarDateConfig, ClCalendarMode, ClListViewItem, ClFilterItemType, ClSelectOption, ClFormLabelPosition, ClFormRule, ClFormValidateError, ClInputType, ClListItem, Justify, ClListViewGroup, ClListViewVirtualItem, ClListViewRefresherStatus, ClConfirmAction, ClConfirmOptions, ClToastOptions, ClPopupDirection, ClQrcodeMode, ClSelectDateShortcut, ClTabsItem, ClTextType, ClTreeItem, ClTreeNodeInfo, ClUploadItem } from "./types";
import type { ClActionSheetItem, ClActionSheetOptions, PassThroughProps, Type, ClButtonType, Size, ClCalendarDateConfig, ClCalendarMode, ClListViewItem, ClFilterItemType, ClSelectOption, ClFormLabelPosition, ClFormRule, ClFormValidateError, ClInputType, ClListItem, Justify, ClListViewGroup, ClListViewVirtualItem, ClListViewRefresherStatus, ClConfirmAction, ClConfirmOptions, ClToastOptions, ClPopupDirection, ClQrcodeMode, ClSelectValue, ClSelectDateShortcut, ClTabsItem, ClTextType, ClTreeItem, ClTreeNodeInfo, ClUploadItem } from "./types";
import { type UiInstance } from "./hooks";
import { type QrcodeOptions } from "./draw";

View File

@@ -33,6 +33,8 @@ export type ClCheckboxOption = {
disabled?: boolean;
};
export type ClSelectValue = string[] | number[] | number | string | null;
export type ClSelectOption = {
label: string;
value: any;