Skip to content

Commit a894fbf

Browse files
authored
refactor(components): [transfer] switch to script-setup syntax (element-plus#8343)
* refactor(components): [transfer] switch to script-setup syntax * chore: improve code * chore: improve type * fix: lost reactivity * chore: fix data error * chore: simplify code
1 parent 598f3ab commit a894fbf

File tree

16 files changed

+502
-523
lines changed

16 files changed

+502
-523
lines changed

packages/components/checkbox/src/checkbox.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ const useEvent = (
309309
}
310310
}
311311

312-
type CheckboxValueType = string | number | boolean
312+
export type CheckboxValueType = string | number | boolean
313313

314314
export const checkboxEmits = {
315315
[UPDATE_MODEL_EVENT]: (val: CheckboxValueType) =>

packages/components/transfer/__tests__/transfer.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { nextTick } from 'vue'
33
import { mount } from '@vue/test-utils'
44
import { describe, expect, it } from 'vitest'
5-
import Transfer from '../src/index.vue'
5+
import Transfer from '../src/transfer.vue'
66

77
describe('Transfer', () => {
88
const getTestData = () => {
Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
1-
import Transfer from './src/index.vue'
1+
import { withInstall } from '@element-plus/utils'
22

3-
import type { App } from 'vue'
4-
import type { SFCWithInstall } from '@element-plus/utils'
3+
import Transfer from './src/transfer.vue'
54

6-
Transfer.install = (app: App): void => {
7-
app.component(Transfer.name, Transfer)
8-
}
9-
10-
const _Transfer = Transfer as SFCWithInstall<typeof Transfer>
11-
12-
export default _Transfer
13-
export const ElTransfer = _Transfer
5+
export const ElTransfer = withInstall(Transfer)
6+
export default ElTransfer
147

158
export * from './src/transfer'
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export * from './use-check'
2+
export * from './use-checked-change'
3+
export * from './use-computed-data'
4+
export * from './use-move'
5+
export * from './use-props-alias'

packages/components/transfer/src/useCheck.ts renamed to packages/components/transfer/src/composables/use-check.ts

Lines changed: 31 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,40 @@
1-
// @ts-nocheck
2-
import { computed, getCurrentInstance, watch } from 'vue'
3-
4-
import type { ExtractPropTypes } from 'vue'
5-
import type { Key, TransferPanelState } from './transfer'
6-
7-
export const CHECKED_CHANGE_EVENT = 'checked-change'
8-
9-
export const useCheckProps = {
10-
data: {
11-
type: Array,
12-
default() {
13-
return []
14-
},
15-
},
16-
optionRender: Function,
17-
placeholder: String,
18-
title: String,
19-
filterable: Boolean,
20-
format: Object,
21-
filterMethod: Function,
22-
defaultChecked: Array,
23-
props: Object,
24-
}
1+
import { computed, watch } from 'vue'
2+
import { isFunction } from '@element-plus/utils'
3+
import { CHECKED_CHANGE_EVENT } from '../transfer-panel'
4+
import { usePropsAlias } from './use-props-alias'
5+
6+
import type { SetupContext } from 'vue'
7+
import type { CheckboxValueType } from '@element-plus/components/checkbox'
8+
import type { TransferKey } from '../transfer'
9+
import type {
10+
TransferPanelEmits,
11+
TransferPanelProps,
12+
TransferPanelState,
13+
} from '../transfer-panel'
2514

2615
export const useCheck = (
27-
props: ExtractPropTypes<typeof useCheckProps>,
28-
panelState: TransferPanelState
16+
props: TransferPanelProps,
17+
panelState: TransferPanelState,
18+
emit: SetupContext<TransferPanelEmits>['emit']
2919
) => {
30-
const { emit } = getCurrentInstance()
31-
32-
const labelProp = computed(() => props.props.label || 'label')
33-
34-
const keyProp = computed(() => props.props.key || 'key')
35-
36-
const disabledProp = computed(() => props.props.disabled || 'disabled')
20+
const propsAlias = usePropsAlias(props)
3721

3822
const filteredData = computed(() => {
3923
return props.data.filter((item) => {
40-
if (typeof props.filterMethod === 'function') {
24+
if (isFunction(props.filterMethod)) {
4125
return props.filterMethod(panelState.query, item)
4226
} else {
43-
const label = item[labelProp.value] || item[keyProp.value].toString()
27+
const label = String(
28+
item[propsAlias.value.label] || item[propsAlias.value.key]
29+
)
4430
return label.toLowerCase().includes(panelState.query.toLowerCase())
4531
}
4632
})
4733
})
4834

49-
const checkableData = computed(() => {
50-
return filteredData.value.filter((item) => !item[disabledProp.value])
51-
})
35+
const checkableData = computed(() =>
36+
filteredData.value.filter((item) => !item[propsAlias.value.disabled])
37+
)
5238

5339
const checkedSummary = computed(() => {
5440
const checkedLength = panelState.checked.length
@@ -73,16 +59,16 @@ export const useCheck = (
7359

7460
const updateAllChecked = () => {
7561
const checkableDataKeys = checkableData.value.map(
76-
(item) => item[keyProp.value]
62+
(item) => item[propsAlias.value.key]
7763
)
7864
panelState.allChecked =
7965
checkableDataKeys.length > 0 &&
8066
checkableDataKeys.every((item) => panelState.checked.includes(item))
8167
}
8268

83-
const handleAllCheckedChange = (value: Key[]) => {
69+
const handleAllCheckedChange = (value: CheckboxValueType) => {
8470
panelState.checked = value
85-
? checkableData.value.map((item) => item[keyProp.value])
71+
? checkableData.value.map((item) => item[propsAlias.value.key])
8672
: []
8773
}
8874

@@ -110,9 +96,9 @@ export const useCheck = (
11096
watch(
11197
() => props.data,
11298
() => {
113-
const checked = []
99+
const checked: TransferKey[] = []
114100
const filteredDataKeys = filteredData.value.map(
115-
(item) => item[keyProp.value]
101+
(item) => item[propsAlias.value.key]
116102
)
117103
panelState.checked.forEach((item) => {
118104
if (filteredDataKeys.includes(item)) {
@@ -134,9 +120,9 @@ export const useCheck = (
134120
)
135121
return
136122

137-
const checked = []
123+
const checked: TransferKey[] = []
138124
const checkableDataKeys = checkableData.value.map(
139-
(item) => item[keyProp.value]
125+
(item) => item[propsAlias.value.key]
140126
)
141127

142128
val.forEach((item) => {
@@ -153,9 +139,6 @@ export const useCheck = (
153139
)
154140

155141
return {
156-
labelProp,
157-
keyProp,
158-
disabledProp,
159142
filteredData,
160143
checkableData,
161144
checkedSummary,
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { LEFT_CHECK_CHANGE_EVENT, RIGHT_CHECK_CHANGE_EVENT } from '../transfer'
2+
3+
import type { SetupContext } from 'vue'
4+
import type {
5+
TransferCheckedState,
6+
TransferEmits,
7+
TransferKey,
8+
} from '../transfer'
9+
10+
export const useCheckedChange = (
11+
checkedState: TransferCheckedState,
12+
emit: SetupContext<TransferEmits>['emit']
13+
) => {
14+
const onSourceCheckedChange = (
15+
val: TransferKey[],
16+
movedKeys?: TransferKey[]
17+
) => {
18+
checkedState.leftChecked = val
19+
if (!movedKeys) return
20+
emit(LEFT_CHECK_CHANGE_EVENT, val, movedKeys)
21+
}
22+
23+
const onTargetCheckedChange = (
24+
val: TransferKey[],
25+
movedKeys?: TransferKey[]
26+
) => {
27+
checkedState.rightChecked = val
28+
if (!movedKeys) return
29+
emit(RIGHT_CHECK_CHANGE_EVENT, val, movedKeys)
30+
}
31+
32+
return {
33+
onSourceCheckedChange,
34+
onTargetCheckedChange,
35+
}
36+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { computed } from 'vue'
2+
import { usePropsAlias } from './use-props-alias'
3+
4+
import type { TransferDataItem, TransferKey, TransferProps } from '../transfer'
5+
6+
export const useComputedData = (props: TransferProps) => {
7+
const propsAlias = usePropsAlias(props)
8+
9+
const dataObj = computed(() =>
10+
props.data.reduce((o, cur) => (o[cur[propsAlias.value.key]] = cur) && o, {})
11+
)
12+
13+
const sourceData = computed(() =>
14+
props.data.filter(
15+
(item) => !props.modelValue.includes(item[propsAlias.value.key])
16+
)
17+
)
18+
19+
const targetData = computed(() => {
20+
if (props.targetOrder === 'original') {
21+
return props.data.filter((item) =>
22+
props.modelValue.includes(item[propsAlias.value.key])
23+
)
24+
} else {
25+
return props.modelValue.reduce(
26+
(arr: TransferDataItem[], cur: TransferKey) => {
27+
const val = dataObj.value[cur]
28+
if (val) {
29+
arr.push(val)
30+
}
31+
return arr
32+
},
33+
[]
34+
)
35+
}
36+
})
37+
38+
return {
39+
sourceData,
40+
targetData,
41+
}
42+
}

packages/components/transfer/src/useMove.ts renamed to packages/components/transfer/src/composables/use-move.ts

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,30 @@
1-
// @ts-nocheck
21
import { CHANGE_EVENT, UPDATE_MODEL_EVENT } from '@element-plus/constants'
2+
import { usePropsAlias } from './use-props-alias'
33

4-
import type { ComputedRef } from 'vue'
4+
import type { SetupContext } from 'vue'
55
import type {
6-
DataItem,
7-
Key,
86
TransferCheckedState,
7+
TransferDataItem,
8+
TransferDirection,
9+
TransferEmits,
10+
TransferKey,
911
TransferProps,
10-
} from './transfer'
12+
} from '../transfer'
1113

1214
export const useMove = (
1315
props: TransferProps,
1416
checkedState: TransferCheckedState,
15-
propsKey: ComputedRef<string>,
16-
emit
17+
emit: SetupContext<TransferEmits>['emit']
1718
) => {
18-
const _emit = (value, type: 'left' | 'right', checked: Key[]) => {
19+
const propsAlias = usePropsAlias(props)
20+
21+
const _emit = (
22+
value: TransferKey[],
23+
direction: TransferDirection,
24+
movedKeys: TransferKey[]
25+
) => {
1926
emit(UPDATE_MODEL_EVENT, value)
20-
emit(CHANGE_EVENT, value, type, checked)
27+
emit(CHANGE_EVENT, value, direction, movedKeys)
2128
}
2229

2330
const addToLeft = () => {
@@ -36,14 +43,14 @@ export const useMove = (
3643
let currentValue = props.modelValue.slice()
3744

3845
const itemsToBeMoved = props.data
39-
.filter((item: DataItem) => {
40-
const itemKey = item[propsKey.value]
46+
.filter((item: TransferDataItem) => {
47+
const itemKey = item[propsAlias.value.key]
4148
return (
4249
checkedState.leftChecked.includes(itemKey) &&
4350
!props.modelValue.includes(itemKey)
4451
)
4552
})
46-
.map((item) => item[propsKey.value])
53+
.map((item) => item[propsAlias.value.key])
4754

4855
currentValue =
4956
props.targetOrder === 'unshift'
@@ -52,8 +59,8 @@ export const useMove = (
5259

5360
if (props.targetOrder === 'original') {
5461
currentValue = props.data
55-
.filter((item) => currentValue.includes(item[propsKey.value]))
56-
.map((item) => item[propsKey.value])
62+
.filter((item) => currentValue.includes(item[propsAlias.value.key]))
63+
.map((item) => item[propsAlias.value.key])
5764
}
5865

5966
_emit(currentValue, 'right', checkedState.leftChecked)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { computed } from 'vue'
2+
3+
import type { TransferPropsAlias } from '../transfer'
4+
5+
export const usePropsAlias = (props: { props: TransferPropsAlias }) => {
6+
const initProps: Required<TransferPropsAlias> = {
7+
label: 'label',
8+
key: 'key',
9+
disabled: 'disabled',
10+
}
11+
12+
return computed(() => ({
13+
...initProps,
14+
...props.props,
15+
}))
16+
}

0 commit comments

Comments
 (0)