添加 useForm 事件
This commit is contained in:
@@ -358,10 +358,6 @@ const visible = ref(false);
|
||||
* 检查禁用状态,如果未禁用则显示弹窗
|
||||
*/
|
||||
function open() {
|
||||
if (props.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
visible.value = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
class="cl-checkbox"
|
||||
:class="[
|
||||
{
|
||||
'cl-checkbox--disabled': disabled,
|
||||
'cl-checkbox--disabled': isDisabled,
|
||||
'cl-checkbox--checked': isChecked
|
||||
},
|
||||
pt.className
|
||||
@@ -47,6 +47,7 @@ import { computed, useSlots, type PropType } from "vue";
|
||||
import type { PassThroughProps } from "../../types";
|
||||
import { get, parseClass, parsePt, pull } from "@/cool";
|
||||
import type { ClIconProps } from "../cl-icon/props";
|
||||
import { useForm } from "../../hooks";
|
||||
|
||||
defineOptions({
|
||||
name: "cl-checkbox"
|
||||
@@ -99,6 +100,10 @@ const props = defineProps({
|
||||
const emit = defineEmits(["update:modelValue", "change"]);
|
||||
|
||||
const slots = useSlots();
|
||||
const { disabled } = useForm();
|
||||
|
||||
// 是否禁用
|
||||
const isDisabled = computed(() => props.disabled || disabled.value);
|
||||
|
||||
// 透传样式类型定义
|
||||
type PassThrough = {
|
||||
@@ -142,7 +147,7 @@ const iconName = computed(() => {
|
||||
* 在非禁用状态下切换选中状态
|
||||
*/
|
||||
function onTap() {
|
||||
if (!props.disabled) {
|
||||
if (!isDisabled.value) {
|
||||
let val = props.modelValue;
|
||||
|
||||
if (Array.isArray(val)) {
|
||||
@@ -166,7 +171,7 @@ function onTap() {
|
||||
@apply flex flex-row items-center;
|
||||
|
||||
&--disabled {
|
||||
@apply opacity-70;
|
||||
@apply opacity-50;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
class="cl-radio"
|
||||
:class="[
|
||||
{
|
||||
'cl-radio--disabled': disabled,
|
||||
'cl-radio--disabled': isDisabled,
|
||||
'cl-radio--checked': isChecked
|
||||
},
|
||||
pt.className
|
||||
@@ -47,6 +47,7 @@ import { computed, useSlots } from "vue";
|
||||
import type { PassThroughProps } from "../../types";
|
||||
import { get, parseClass, parsePt } from "@/cool";
|
||||
import type { ClIconProps } from "../cl-icon/props";
|
||||
import { useForm } from "../../hooks";
|
||||
|
||||
defineOptions({
|
||||
name: "cl-radio"
|
||||
@@ -108,6 +109,12 @@ type PassThrough = {
|
||||
// 解析透传样式配置
|
||||
const pt = computed(() => parsePt<PassThrough>(props.pt));
|
||||
|
||||
// cl-form 上下文
|
||||
const { disabled } = useForm();
|
||||
|
||||
// 是否禁用
|
||||
const isDisabled = computed(() => props.disabled || disabled.value);
|
||||
|
||||
// 是否为选中状态
|
||||
const isChecked = computed(() => props.modelValue == props.value);
|
||||
|
||||
@@ -130,7 +137,7 @@ const iconName = computed(() => {
|
||||
* 在非禁用状态下切换选中状态
|
||||
*/
|
||||
function onTap() {
|
||||
if (!props.disabled) {
|
||||
if (!isDisabled.value) {
|
||||
emit("update:modelValue", props.value);
|
||||
emit("change", props.value);
|
||||
}
|
||||
@@ -142,7 +149,7 @@ function onTap() {
|
||||
@apply flex flex-row items-center;
|
||||
|
||||
&--disabled {
|
||||
@apply opacity-70;
|
||||
@apply opacity-50;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<view class="cl-rate" :class="[pt.className]">
|
||||
<view class="cl-rate" :class="[{ 'cl-rate--disabled': isDisabled }, pt.className]">
|
||||
<view
|
||||
v-for="(item, index) in max"
|
||||
:key="index"
|
||||
@@ -48,6 +48,7 @@ import { computed } from "vue";
|
||||
import { parseClass, parsePt } from "@/cool";
|
||||
import type { PassThroughProps } from "../../types";
|
||||
import type { ClIconProps } from "../cl-icon/props";
|
||||
import { useForm } from "../../hooks";
|
||||
|
||||
defineOptions({
|
||||
name: "cl-rate"
|
||||
@@ -126,6 +127,12 @@ type PassThrough = {
|
||||
// 解析透传样式
|
||||
const pt = computed(() => parsePt<PassThrough>(props.pt));
|
||||
|
||||
// cl-form 上下文
|
||||
const { disabled } = useForm();
|
||||
|
||||
// 是否禁用
|
||||
const isDisabled = computed(() => props.disabled || disabled.value);
|
||||
|
||||
// 获取图标激活宽度
|
||||
function getIconActiveWidth(item: number) {
|
||||
// 如果评分值大于等于当前项,返回null表示完全填充
|
||||
@@ -144,7 +151,7 @@ function getIconActiveWidth(item: number) {
|
||||
|
||||
// 点击事件处理
|
||||
function onTap(index: number) {
|
||||
if (props.disabled) {
|
||||
if (isDisabled.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -176,11 +183,14 @@ function onTap(index: number) {
|
||||
.cl-rate {
|
||||
@apply flex flex-row items-center;
|
||||
|
||||
&--disabled {
|
||||
@apply opacity-50;
|
||||
}
|
||||
|
||||
&__item {
|
||||
@apply flex items-center justify-center relative duration-200;
|
||||
@apply flex items-center justify-center relative duration-200 overflow-hidden;
|
||||
transition-property: color;
|
||||
margin-right: 6rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
@tap="setRange(0)"
|
||||
>
|
||||
<cl-text
|
||||
v-if="values[0] != ''"
|
||||
v-if="values.length > 0 && values[0] != ''"
|
||||
:pt="{
|
||||
className: 'text-center'
|
||||
}"
|
||||
@@ -78,7 +78,7 @@
|
||||
@tap="setRange(1)"
|
||||
>
|
||||
<cl-text
|
||||
v-if="values[1] != ''"
|
||||
v-if="values.length > 1 && values[1] != ''"
|
||||
:pt="{
|
||||
className: 'text-center'
|
||||
}"
|
||||
@@ -393,10 +393,14 @@ const list = computed(() => {
|
||||
).toArray();
|
||||
// 解析结束日期为年月日时分秒数组
|
||||
const [endYear, endMonth, endDate, endHour, endMinute, endSecond] = dayUts(props.end).toArray();
|
||||
// 获取当前选中的年月日时分秒值
|
||||
const [year, month, date, hour, minute] = value.value;
|
||||
// 初始化年月日时分秒六个选项数组
|
||||
const arr = [[], [], [], [], [], []] as ClSelectOption[][];
|
||||
// 边界处理,如果value为空,返回空数组
|
||||
if (isEmpty(value.value)) {
|
||||
return arr;
|
||||
}
|
||||
// 获取当前选中的年月日时分秒值
|
||||
const [year, month, date, hour, minute] = value.value;
|
||||
// 判断是否为闰年
|
||||
const isLeapYear = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
|
||||
// 根据月份和是否闰年获取当月天数
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
class="cl-slider"
|
||||
:class="[
|
||||
{
|
||||
'cl-slider--disabled': disabled
|
||||
'cl-slider--disabled': isDisabled
|
||||
},
|
||||
pt.className
|
||||
]"
|
||||
@@ -62,14 +62,16 @@
|
||||
></view>
|
||||
</view>
|
||||
|
||||
<cl-text
|
||||
v-if="showValue"
|
||||
:pt="{
|
||||
className: parseClass(['text-center w-[100rpx]', pt.value?.className])
|
||||
}"
|
||||
>
|
||||
{{ displayValue }}
|
||||
</cl-text>
|
||||
<slot name="value" :value="displayValue">
|
||||
<cl-text
|
||||
v-if="showValue"
|
||||
:pt="{
|
||||
className: parseClass(['text-center w-[100rpx]', pt.value?.className])
|
||||
}"
|
||||
>
|
||||
{{ displayValue }}
|
||||
</cl-text>
|
||||
</slot>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -77,6 +79,7 @@
|
||||
import { computed, getCurrentInstance, nextTick, onMounted, ref, watch, type PropType } from "vue";
|
||||
import { parseClass, parsePt, rpx2px } from "@/cool";
|
||||
import type { PassThroughProps } from "../../types";
|
||||
import { useForm } from "../../hooks";
|
||||
|
||||
defineOptions({
|
||||
name: "cl-slider"
|
||||
@@ -157,6 +160,12 @@ type PassThrough = {
|
||||
// 计算样式穿透对象
|
||||
const pt = computed(() => parsePt<PassThrough>(props.pt));
|
||||
|
||||
// cl-form 上下文
|
||||
const { disabled } = useForm();
|
||||
|
||||
// 是否禁用
|
||||
const isDisabled = computed(() => props.disabled || disabled.value);
|
||||
|
||||
// 当前滑块的值,单值模式
|
||||
const value = ref<number>(props.modelValue);
|
||||
|
||||
@@ -356,7 +365,7 @@ function updateValue(newValue: number | number[]) {
|
||||
|
||||
// 触摸开始事件:获取轨道信息并初始化滑块位置
|
||||
async function onTouchStart(e: TouchEvent) {
|
||||
if (props.disabled) return;
|
||||
if (isDisabled.value) return;
|
||||
|
||||
// 先获取轨道的位置和尺寸信息,这是后续计算的基础
|
||||
await getTrackInfo();
|
||||
@@ -381,7 +390,7 @@ async function onTouchStart(e: TouchEvent) {
|
||||
|
||||
// 触摸移动事件:实时更新滑块位置
|
||||
function onTouchMove(e: TouchEvent) {
|
||||
if (props.disabled) return;
|
||||
if (isDisabled.value) return;
|
||||
|
||||
const clientX = e.touches[0].clientX;
|
||||
const calculatedValue = calculateValue(clientX);
|
||||
@@ -399,7 +408,7 @@ function onTouchMove(e: TouchEvent) {
|
||||
|
||||
// 触摸结束事件:完成拖动,触发最终的change事件
|
||||
function onTouchEnd() {
|
||||
if (props.disabled) return;
|
||||
if (isDisabled.value) return;
|
||||
|
||||
// 触发change事件,表示用户完成了一次完整的拖动操作
|
||||
if (props.range) {
|
||||
@@ -500,8 +509,7 @@ onMounted(() => {
|
||||
@apply flex flex-row items-center w-full overflow-visible;
|
||||
|
||||
&--disabled {
|
||||
opacity: 0.6;
|
||||
pointer-events: none;
|
||||
@apply opacity-50;
|
||||
}
|
||||
|
||||
&__inner {
|
||||
@@ -528,6 +536,8 @@ onMounted(() => {
|
||||
transform: translateY(-50%);
|
||||
pointer-events: none;
|
||||
z-index: 1;
|
||||
border-width: 4rpx;
|
||||
box-shadow: 0 0 2rpx 2rpx rgba(100, 100, 100, 0.1);
|
||||
|
||||
&--min {
|
||||
z-index: 2;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
class="cl-switch"
|
||||
:class="[
|
||||
{
|
||||
'cl-switch--disabled': disabled,
|
||||
'cl-switch--disabled': isDisabled,
|
||||
'cl-switch--checked': isChecked
|
||||
},
|
||||
|
||||
@@ -53,6 +53,7 @@ import { computed, ref, watch } from "vue";
|
||||
import { isDark, parseClass, parsePt } from "@/cool";
|
||||
import type { PassThroughProps } from "../../types";
|
||||
import { vibrate } from "@/uni_modules/cool-vibrate";
|
||||
import { useForm } from "../../hooks";
|
||||
|
||||
defineOptions({
|
||||
name: "cl-switch"
|
||||
@@ -107,6 +108,12 @@ type PassThrough = {
|
||||
// 解析透传样式配置
|
||||
const pt = computed(() => parsePt<PassThrough>(props.pt));
|
||||
|
||||
// cl-form 上下文
|
||||
const { disabled } = useForm();
|
||||
|
||||
// 是否禁用
|
||||
const isDisabled = computed(() => props.disabled || disabled.value);
|
||||
|
||||
// 绑定值
|
||||
const value = ref(props.modelValue);
|
||||
|
||||
@@ -147,7 +154,7 @@ const rect = computed<Rect>(() => {
|
||||
* 在非禁用且非加载状态下切换开关状态
|
||||
*/
|
||||
function onTap() {
|
||||
if (!props.disabled && !props.loading) {
|
||||
if (!isDisabled.value && !props.loading) {
|
||||
// 切换开关状态
|
||||
const val = !value.value;
|
||||
value.value = val;
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
:class="[
|
||||
isDark ? 'text-surface-50' : 'text-surface-700',
|
||||
{
|
||||
'truncate w-full': ellipsis
|
||||
'truncate w-full': ellipsis,
|
||||
'cl-text--pre-wrap': preWrap
|
||||
},
|
||||
{
|
||||
'!text-primary-500': color == 'primary',
|
||||
@@ -35,7 +36,8 @@
|
||||
:class="[
|
||||
isDark ? 'text-surface-50' : 'text-surface-700',
|
||||
{
|
||||
'truncate w-full': ellipsis
|
||||
'truncate w-full': ellipsis,
|
||||
'cl-text--pre-wrap': preWrap
|
||||
},
|
||||
{
|
||||
'!text-primary-500': color == 'primary',
|
||||
@@ -140,6 +142,11 @@ const props = defineProps({
|
||||
decode: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 是否保留单词
|
||||
preWrap: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
|
||||
@@ -268,5 +275,11 @@ const content = computed(() => {
|
||||
<style lang="scss" scoped>
|
||||
.cl-text {
|
||||
@apply text-md;
|
||||
|
||||
&--pre-wrap {
|
||||
// #ifdef H5
|
||||
white-space: pre-wrap;
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -145,6 +145,11 @@ const props = defineProps({
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 演示用,本地预览
|
||||
test: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
|
||||
@@ -330,6 +335,13 @@ function choose(index: number) {
|
||||
// 添加到列表并获取唯一ID
|
||||
const uid = append(file.path);
|
||||
|
||||
// 测试用,本地预览
|
||||
if (props.test) {
|
||||
update(uid, { url: file.path, progress: 100 });
|
||||
emit("success", file.path, uid);
|
||||
return;
|
||||
}
|
||||
|
||||
// 开始上传文件
|
||||
uploadFile(file, {
|
||||
// 上传进度回调
|
||||
|
||||
Reference in New Issue
Block a user