小程序初始提交
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
<template>
|
||||
<view
|
||||
class="cl-checkbox"
|
||||
:class="[
|
||||
{
|
||||
'cl-checkbox--disabled': isDisabled,
|
||||
'cl-checkbox--checked': isChecked
|
||||
},
|
||||
pt.className
|
||||
]"
|
||||
@tap="onTap"
|
||||
>
|
||||
<cl-icon
|
||||
v-if="showIcon"
|
||||
:name="iconName"
|
||||
:size="pt.icon?.size ?? 40"
|
||||
:pt="{
|
||||
className: parseClass([
|
||||
'cl-checkbox__icon mr-1',
|
||||
{
|
||||
'text-primary-500': isChecked
|
||||
},
|
||||
pt.icon?.className
|
||||
])
|
||||
}"
|
||||
></cl-icon>
|
||||
|
||||
<cl-text
|
||||
:pt="{
|
||||
className: parseClass([
|
||||
'cl-checkbox__label',
|
||||
{
|
||||
'text-primary-500': isChecked
|
||||
},
|
||||
pt.label?.className
|
||||
])
|
||||
}"
|
||||
v-if="showLabel"
|
||||
>
|
||||
<slot>{{ label }}</slot>
|
||||
</cl-text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
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"
|
||||
});
|
||||
|
||||
// 定义组件属性
|
||||
const props = defineProps({
|
||||
// 透传样式配置
|
||||
pt: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
// 绑定值 - 当前选中的值
|
||||
modelValue: {
|
||||
type: [Array, Boolean] as PropType<any[] | boolean>,
|
||||
default: () => []
|
||||
},
|
||||
// 标签文本
|
||||
label: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
// 选项值 - 该单选框对应的值
|
||||
value: {
|
||||
type: null
|
||||
},
|
||||
// 是否禁用
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 选中时的图标
|
||||
activeIcon: {
|
||||
type: String,
|
||||
default: "checkbox-line"
|
||||
},
|
||||
// 未选中时的图标
|
||||
inactiveIcon: {
|
||||
type: String,
|
||||
default: "checkbox-blank-line"
|
||||
},
|
||||
// 是否显示图标
|
||||
showIcon: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
});
|
||||
|
||||
// 定义组件事件
|
||||
const emit = defineEmits(["update:modelValue", "change"]);
|
||||
|
||||
const slots = useSlots();
|
||||
const { disabled } = useForm();
|
||||
|
||||
// 是否禁用
|
||||
const isDisabled = computed(() => props.disabled || disabled.value);
|
||||
|
||||
// 透传样式类型定义
|
||||
type PassThrough = {
|
||||
className?: string;
|
||||
icon?: ClIconProps;
|
||||
label?: PassThroughProps;
|
||||
};
|
||||
|
||||
// 解析透传样式配置
|
||||
const pt = computed(() => parsePt<PassThrough>(props.pt));
|
||||
|
||||
// 是否为选中状态
|
||||
const isChecked = computed(() => {
|
||||
if (Array.isArray(props.modelValue)) {
|
||||
return props.modelValue.includes(props.value!);
|
||||
}
|
||||
|
||||
if (typeof props.modelValue == "boolean") {
|
||||
return props.modelValue;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
// 是否显示标签
|
||||
const showLabel = computed(() => props.label != "" || get(slots, "default") != null);
|
||||
|
||||
// 图标名称
|
||||
const iconName = computed(() => {
|
||||
// 选中状态
|
||||
if (isChecked.value) {
|
||||
return props.activeIcon;
|
||||
}
|
||||
|
||||
// 默认状态
|
||||
return props.inactiveIcon;
|
||||
});
|
||||
|
||||
/**
|
||||
* 点击事件处理函数
|
||||
* 在非禁用状态下切换选中状态
|
||||
*/
|
||||
function onTap() {
|
||||
if (!isDisabled.value) {
|
||||
let val = props.modelValue;
|
||||
|
||||
if (Array.isArray(val)) {
|
||||
if (isChecked.value) {
|
||||
val = pull(val, props.value!);
|
||||
} else {
|
||||
val.push(props.value!);
|
||||
}
|
||||
} else {
|
||||
val = !val;
|
||||
}
|
||||
|
||||
emit("update:modelValue", val);
|
||||
emit("change", val);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.cl-checkbox {
|
||||
@apply flex flex-row items-center;
|
||||
|
||||
&--disabled {
|
||||
@apply opacity-50;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,20 @@
|
||||
import type { PassThroughProps } from "../../types";
|
||||
import type { ClIconProps } from "../cl-icon/props";
|
||||
|
||||
export type ClCheckboxPassThrough = {
|
||||
className?: string;
|
||||
icon?: ClIconProps;
|
||||
label?: PassThroughProps;
|
||||
};
|
||||
|
||||
export type ClCheckboxProps = {
|
||||
className?: string;
|
||||
pt?: ClCheckboxPassThrough;
|
||||
modelValue?: any[] | boolean;
|
||||
label?: string;
|
||||
value?: any;
|
||||
disabled?: boolean;
|
||||
activeIcon?: string;
|
||||
inactiveIcon?: string;
|
||||
showIcon?: boolean;
|
||||
};
|
||||
Reference in New Issue
Block a user