types(Cascader): use tsx (#8080)

This commit is contained in:
neverland 2021-02-04 15:53:36 +08:00 committed by GitHub
parent 1aa791bd6d
commit aeeeae8d2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 19 deletions

View File

@ -99,12 +99,13 @@
</demo-block> </demo-block>
</template> </template>
<script> <script lang="ts">
import zhCNOptions from './area-zh-CN';
import enUSOptions from './area-en-US';
import { computed, reactive, toRefs } from 'vue'; import { computed, reactive, toRefs } from 'vue';
import { CascaderOption } from '..';
import { useTranslate } from '@demo/use-translate'; import { useTranslate } from '@demo/use-translate';
import { deepClone } from '../../utils/deep-clone'; import { deepClone } from '../../utils/deep-clone';
import zhCNOptions from './area-zh-CN';
import enUSOptions from './area-en-US';
const i18n = { const i18n = {
'zh-CN': { 'zh-CN': {
@ -147,10 +148,17 @@ const i18n = {
}, },
}; };
type StateItem = {
show: boolean;
value: string | number | null;
result: string;
options?: CascaderOption[];
};
export default { export default {
setup() { setup() {
const t = useTranslate(i18n); const t = useTranslate(i18n);
const state = reactive({ const state = reactive<Record<string, StateItem>>({
base: { base: {
show: false, show: false,
value: '', value: '',
@ -182,7 +190,7 @@ export default {
const customFieldOptions = computed(() => { const customFieldOptions = computed(() => {
const options = deepClone(t('options')); const options = deepClone(t('options'));
const adjustFieldName = (item) => { const adjustFieldName = (item: CascaderOption) => {
if ('text' in item) { if ('text' in item) {
item.name = item.text; item.name = item.text;
delete item.text; delete item.text;
@ -201,15 +209,21 @@ export default {
return options; return options;
}); });
const loadDynamicOptions = ({ value }) => { const loadDynamicOptions = ({ value }: CascaderOption) => {
if (value === '330000') { if (value === '330000') {
setTimeout(() => { setTimeout(() => {
state.async.options[0].children = t('asyncOptions2'); state.async.options![0].children = t('asyncOptions2');
}, 500); }, 500);
} }
}; };
const onFinish = (type, { value, selectedOptions }) => { const onFinish = (
type: string,
{
value,
selectedOptions,
}: { value: number | string; selectedOptions: CascaderOption[] }
) => {
const result = selectedOptions const result = selectedOptions
.map((option) => option.text || option.name) .map((option) => option.text || option.name)
.join('/'); .join('/');

View File

@ -1,4 +1,4 @@
import { nextTick, reactive, watch } from 'vue'; import { nextTick, PropType, reactive, watch } from 'vue';
import { createNamespace } from '../utils'; import { createNamespace } from '../utils';
// Components // Components
@ -8,15 +8,34 @@ import Icon from '../icon';
const [createComponent, bem, t] = createNamespace('cascader'); const [createComponent, bem, t] = createNamespace('cascader');
export type CascaderOption = {
text?: string;
value?: string | number;
children?: CascaderOption[];
// for custom filed names
[key: string]: any;
};
type CascaderTab = {
options: CascaderOption[];
selectedOption: CascaderOption | null;
};
type CascaderFieldNames = {
text: string;
value: string;
children: string;
};
export default createComponent({ export default createComponent({
props: { props: {
title: String, title: String,
modelValue: [Number, String], modelValue: [Number, String],
fieldNames: Object, fieldNames: Object as PropType<CascaderFieldNames>,
placeholder: String, placeholder: String,
activeColor: String, activeColor: String,
options: { options: {
type: Array, type: Array as PropType<CascaderOption[]>,
default: () => [], default: () => [],
}, },
closeable: { closeable: {
@ -29,7 +48,7 @@ export default createComponent({
setup(props, { slots, emit }) { setup(props, { slots, emit }) {
const state = reactive({ const state = reactive({
tabs: [], tabs: [] as CascaderTab[],
activeTab: 0, activeTab: 0,
}); });
@ -40,7 +59,10 @@ export default createComponent({
...props.fieldNames, ...props.fieldNames,
}; };
const getSelectedOptionsByValue = (options, value) => { const getSelectedOptionsByValue = (
options: CascaderOption[],
value: string | number
): CascaderOption[] | undefined => {
for (let i = 0; i < options.length; i++) { for (let i = 0; i < options.length; i++) {
const option = options[i]; const option = options[i];
@ -109,7 +131,7 @@ export default createComponent({
]; ];
}; };
const onSelect = (option, tabIndex) => { const onSelect = (option: CascaderOption, tabIndex: number) => {
state.tabs[tabIndex].selectedOption = option; state.tabs[tabIndex].selectedOption = option;
if (state.tabs.length > tabIndex + 1) { if (state.tabs.length > tabIndex + 1) {
@ -165,15 +187,19 @@ export default createComponent({
</div> </div>
); );
const renderOptions = (options, selectedOption, tabIndex) => { const renderOptions = (
const renderOption = (option) => { options: CascaderOption[],
selectedOption: CascaderOption | null,
tabIndex: number
) => {
const renderOption = (option: CascaderOption) => {
const isSelected = const isSelected =
selectedOption && option[valueKey] === selectedOption[valueKey]; selectedOption && option[valueKey] === selectedOption[valueKey];
return ( return (
<li <li
class={bem('option', { selected: isSelected })} class={bem('option', { selected: isSelected })}
style={{ color: isSelected ? props.activeColor : null }} style={{ color: isSelected ? props.activeColor : undefined }}
onClick={() => { onClick={() => {
onSelect(option, tabIndex); onSelect(option, tabIndex);
}} }}
@ -189,8 +215,8 @@ export default createComponent({
return <ul class={bem('options')}>{options.map(renderOption)}</ul>; return <ul class={bem('options')}>{options.map(renderOption)}</ul>;
}; };
const renderTab = (item, tabIndex) => { const renderTab = (tab: CascaderTab, tabIndex: number) => {
const { options, selectedOption } = item; const { options, selectedOption } = tab;
const title = selectedOption const title = selectedOption
? selectedOption[textKey] ? selectedOption[textKey]
: props.placeholder || t('select'); : props.placeholder || t('select');