| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- <template>
- <FlexView direction="column">
- <slot />
- </FlexView>
- </template>
- <script setup lang="ts">
- import { provide, toRef, type Ref } from 'vue';
- import { useChildLinkParent } from '../composeabe/ChildItem';
- import FlexView from '../layout/FlexView.vue';
- import { ArrayUtils } from '@imengyu/imengyu-utils';
- export interface CollapseProps {
- /**
- * 当前展开面板的 name
- */
- modelValue: (number | string)[];
- /**
- * 是否开启手风琴模式
- * @default false
- */
- accordion?: boolean;
- /**
- * 动画时长(ms),为0时禁用动画
- * @default 300
- */
- animDuration?: number;
- }
- export interface CollapseInstance {
- /**
- * 展开指定面板
- * @param name 面板的 name,为空时表示所有面板
- */
- open(name?: number | string): void;
- /**
- * 关闭指定面板
- * @param name 面板的 name,为空时表示所有面板
- */
- close(name?: number | string): void;
- /**
- * 切换指定面板打开状态
- * @param name 面板的 name,为空时表示所有面板
- */
- toggle(name?: number | string): void;
- }
- const emit = defineEmits([ 'update:modelValue' ]);
- const props = withDefaults(defineProps<CollapseProps>(), {
- animDuration: 300,
- accordion: false,
- });
- const childNames: (number | string)[] = [];
- const {
- getPosition,
- } = useChildLinkParent({
- onClean: () => {
- //ArrayUtils.clear(childNames);
- },
- });
- export interface CollapseContext {
- activeName: Ref<(number|string)[]>,
- animDuration: Ref<number>,
- getPosition: (name?: string|number) => number,
- itemClick: (i: number | string) => void;
-
- }
- provide<CollapseContext>('CollapseContext', {
- activeName: toRef(props, 'modelValue'),
- animDuration: toRef(props, 'animDuration'),
- getPosition: (name) => {
- const position = getPosition().index;
- childNames.push(name ?? position);
- return position;
- },
- itemClick: (i) => {
- if (props.modelValue.includes(i)) {
- emit('update:modelValue', props.modelValue.filter((v) => v !== i));
- return;
- }
- if (props.accordion) {
- emit('update:modelValue', [i]);
- } else {
- emit('update:modelValue', [...props.modelValue, i]);
- }
- },
- });
- defineExpose<CollapseInstance>({
- open: (name?: number | string) => {
- if (name) {
- emit('update:modelValue', props.accordion ? [name] : [...props.modelValue, name]);
- return;
- }
- emit('update:modelValue', childNames);
- },
- close: (name?: number | string) => {
- if (name) {
- emit('update:modelValue', props.modelValue.filter((v) => v !== name));
- return;
- }
- emit('update:modelValue', []);
- },
- toggle: (name?: number | string) => {
- if (name) {
- emit('update:modelValue', props.modelValue.includes(name) ? props.modelValue.filter((v) => v !== name) : [...props.modelValue, name]);
- return;
- }
- emit('update:modelValue', childNames.filter((v) => !props.modelValue.includes(v)));
- },
- });
- </script>
|