mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
types(Cascader): use tsx (#8080)
This commit is contained in:
parent
1aa791bd6d
commit
aeeeae8d2b
@ -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('/');
|
||||||
|
@ -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');
|
Loading…
x
Reference in New Issue
Block a user