Skip to content

Commit

Permalink
fix(Collapse): 手风琴模式下,modelValue 为 string
Browse files Browse the repository at this point in the history
  • Loading branch information
1zumii committed Dec 1, 2023
1 parent 53557fe commit cde8070
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 61 deletions.
60 changes: 49 additions & 11 deletions components/collapse/collapse.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,75 @@
</template>

<script lang="ts">
import { provide, defineComponent, computed } from 'vue';
import { provide, defineComponent, computed, watch } from 'vue';
import { isNil } from 'lodash-es';
import { useTheme } from '../_theme/useTheme';
import { useNormalModel } from '../_util/use/useModel';
import { collapseEmits, collapseProps } from './collapseExpose';
import { useNamespace } from './useNamespace';
import { arrowPositionKey, collapseContextKey } from './common';
import { COMPONENT_NAME, arrowPositionKey, collapseContextKey } from './common';
import type { CollapseActiveName } from './common';
export default defineComponent({
name: 'FCollapse',
name: COMPONENT_NAME,
props: collapseProps,
emits: collapseEmits,
setup(props, { emit }) {
useTheme();
const [activeNames, setActiveNames] = useNormalModel(props, emit);
const activeNames = computed<(string | number)[]>({
get: () => {
if (props.accordion) {
if (Array.isArray(props.modelValue)) {
console.warn(
`${COMPONENT_NAME}: 手风琴模式下 modelValue 不支持数组`,
);
return [];
}
return isNil(props.modelValue) ? [] : [props.modelValue];
} else {
if (!Array.isArray(props.modelValue)) {
console.warn(
`${COMPONENT_NAME}: 非手风琴模式下 modelValue 仅支持数组`,
);
return [];
}
return props.modelValue;
}
},
set: (names) => {
if (props.accordion) {
emit('update:modelValue', names[0]);
} else {
emit('update:modelValue', names);
}
},
});
// 手风琴模式变化时,重置 modelValue
watch(
() => props.accordion,
() => {
activeNames.value = [];
},
);
const handleItemClick = (name: CollapseActiveName) => {
let _activeNames = [...activeNames.value];
const index = _activeNames.indexOf(name);
if (props.accordion) {
setActiveNames([activeNames.value[0] === name ? '' : name]);
_activeNames = index > -1 ? [] : [name];
} else {
const _activeNames = [...activeNames.value];
const index = _activeNames.indexOf(name);
if (index > -1) {
_activeNames.splice(index, 1);
} else {
_activeNames.push(name);
}
setActiveNames(_activeNames);
}
activeNames.value = _activeNames;
};
provide(collapseContextKey, {
Expand All @@ -51,10 +89,10 @@ export default defineComponent({
arrow: props?.arrow,
embedded: computed(() => props?.embedded),
});
return {
rootKls,
activeNames,
setActiveNames,
};
},
});
Expand Down
4 changes: 0 additions & 4 deletions components/collapse/collapseExpose.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ type Arrayable<T> = T | T[];
export type CollapseModelValue = Arrayable<CollapseActiveName>;
export type Mutable<T> = { -readonly [P in keyof T]: T[P] }; // 移除只读特性

const mutable = <T extends readonly any[] | Record<string, unknown>>(val: T) =>
val as Mutable<typeof val>;

export const emitChangeFn = (value: CollapseModelValue) =>
typeof isNumber(value) || isString(value) || Array.isArray(value);

Expand All @@ -23,7 +20,6 @@ export const collapseProps = {
},
modelValue: {
type: definePropType<CollapseModelValue>([Array, String, Number]),
default: () => mutable([] as const), // 常量
},
embedded: {
type: Boolean,
Expand Down
2 changes: 2 additions & 0 deletions components/collapse/common.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { InjectionKey, PropType, Ref } from 'vue';

export const COMPONENT_NAME = 'FCollapse';

export const definePropType = <T>(val: any): PropType<T> => val;

export const generateId = (): number => Math.floor(Math.random() * 10000);
Expand Down
28 changes: 15 additions & 13 deletions docs/.vitepress/components/collapse/accordion.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
<template>
<div class="demo-collapse">
<FCollapse v-model="activeName" accordion :embedded="false">
<FSpace vertical>
<FSwitch v-model="accordion">手风琴模式</FSwitch>
<FCollapse
v-model="activeName"
:accordion="accordion"
:embedded="false"
>
<FCollapseItem title="Consistency" name="1">
<div>
岁月静好,浅笑安然。打开记忆的闸门,仿佛又回到了那年那月那时光,仿佛又见到你送给我的那盆清香茉莉,在细雨潇潇的夜晚,所呈现出来的洁净和楚楚动人。以前的过往总是在记忆深处,以固有的姿态,以从未稍离的执着提醒我,生命中有一种存在,叫以前。
Expand All @@ -22,17 +27,14 @@
</div>
</FCollapseItem>
</FCollapse>
</div>
</FSpace>
</template>

<script>
import { ref } from 'vue';
export default {
setup() {
const activeName = ref('1');
return {
activeName,
};
},
};
<script setup>
import { ref, watch } from 'vue';
const accordion = ref(true);
const activeName = ref('1');
watch(activeName, (name) => console.log('activeName', name));
</script>
7 changes: 2 additions & 5 deletions docs/.vitepress/components/collapse/arrowleft.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="demo-collapse">
<FCollapse v-model="activeNames" :arrow="'left'" @change="handleChange">
<FCollapse v-model="activeNames" :arrow="'left'">
<FCollapseItem title="Consistency" name="1">
<div>
岁月静好,浅笑安然。打开记忆的闸门,仿佛又回到了那年那月那时光,仿佛又见到你送给我的那盆清香茉莉,在细雨潇潇的夜晚,所呈现出来的洁净和楚楚动人。以前的过往总是在记忆深处,以固有的姿态,以从未稍离的执着提醒我,生命中有一种存在,叫以前。
Expand Down Expand Up @@ -31,12 +31,9 @@ import { ref } from 'vue';
export default {
setup() {
const activeNames = ref(['1']);
const handleChange = (value) => {
console.log('[collapse.arrowleft] [handleChange] value:', value);
};
return {
activeNames,
handleChange,
};
},
};
Expand Down
7 changes: 2 additions & 5 deletions docs/.vitepress/components/collapse/basic.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="demo-collapse">
<FCollapse v-model="activeNames" @change="handleChange">
<FCollapse v-model="activeNames">
<FCollapseItem title="Consistency" name="1">
<div>
岁月静好,浅笑安然。打开记忆的闸门,仿佛又回到了那年那月那时光,仿佛又见到你送给我的那盆清香茉莉,在细雨潇潇的夜晚,所呈现出来的洁净和楚楚动人。以前的过往总是在记忆深处,以固有的姿态,以从未稍离的执着提醒我,生命中有一种存在,叫以前。
Expand Down Expand Up @@ -31,12 +31,9 @@ import { ref } from 'vue';
export default {
setup() {
const activeNames = ref(['1']);
const handleChange = (value) => {
console.log('[collapse.basic] [handleChange] value:', value);
};
return {
activeNames,
handleChange,
};
},
};
Expand Down
10 changes: 1 addition & 9 deletions docs/.vitepress/components/collapse/embedded.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
<template>
<div class="demo-collapse">
<FSwitch v-model="embedded"></FSwitch>
<FCollapse
v-model="activeNames"
:embedded="embedded"
@change="handleChange"
>
<FCollapse v-model="activeNames" :embedded="embedded">
<FCollapseItem title="Consistency" name="1">
<div>
岁月静好,浅笑安然。打开记忆的闸门,仿佛又回到了那年那月那时光,仿佛又见到你送给我的那盆清香茉莉,在细雨潇潇的夜晚,所呈现出来的洁净和楚楚动人。以前的过往总是在记忆深处,以固有的姿态,以从未稍离的执着提醒我,生命中有一种存在,叫以前。
Expand Down Expand Up @@ -36,14 +32,10 @@ import { ref } from 'vue';
export default {
setup() {
const activeNames = ref(['1']);
const handleChange = (value) => {
console.log('[collapse.embedded] [handleChange] value:', value);
};
const embedded = ref(false);
return {
embedded,
activeNames,
handleChange,
};
},
};
Expand Down
22 changes: 8 additions & 14 deletions docs/.vitepress/components/collapse/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,10 @@ embedded 控制背景色

| 属性名 | 详情 | 类型 | 可选值 | 默认值 |
| --------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------- | ------ | ------ |
| model-value / v-model | 当前激活的面板(如果是手风琴模式,绑定值类型需要为 string,否则为 array) | string (accordion mode) / array (non-accordion mode) |||
| accordion | 是否手风琴模式 | boolean || false |
| arrow | 箭头位置 ( left, right ) ,默认右边 | string || right |
| embedded | 内容使用更深的背景色展现嵌入效果 | boolean || true |

## Collapse 事件

| 属性名 | 说明 | 回调参数 |
| ------ | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| change | 当前激活面板改变时触发(如果是手风琴模式,参数 activeNames 类型为 string,否则为 array) | (activeNames: array (non-accordion mode) / string (accordion mode)) |
| model-value / v-model | 当前激活的面板(如果是手风琴模式,绑定值类型需要为 string,否则为 array) | string (accordion mode) / array (non-accordion mode) | - | - |
| accordion | 是否手风琴模式 | boolean | - | false |
| arrow | 箭头位置 ( left, right ) ,默认右边 | string | - | right |
| embedded | 内容使用更深的背景色展现嵌入效果 | boolean | - | true |

## Collapse 插槽

Expand All @@ -69,13 +63,13 @@ embedded 控制背景色

| 属性名 | 说明 | 类型 | 可选值 | 默认值 |
| -------- | ---------- | ------------- | ------ | ------ |
| name | 唯一标志符 | string/number | | |
| title | 面板标题 | string | | |
| disabled | 是否禁用 | boolean | | |
| name | 唯一标志符 | string/number | - | - |
| title | 面板标题 | string | - | - |
| disabled | 是否禁用 | boolean | - | - |

## Collapse Item 插槽

| 属性名 | 说明 |
| ------ | ---------------- |
| | 折叠项的内容 |
| - | 折叠项的内容 |
| title | 折叠项标题的内容 |

0 comments on commit cde8070

Please sign in to comment.