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>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import zhCNOptions from './area-zh-CN';
|
||||
import enUSOptions from './area-en-US';
|
||||
<script lang="ts">
|
||||
import { computed, reactive, toRefs } from 'vue';
|
||||
import { CascaderOption } from '..';
|
||||
import { useTranslate } from '@demo/use-translate';
|
||||
import { deepClone } from '../../utils/deep-clone';
|
||||
import zhCNOptions from './area-zh-CN';
|
||||
import enUSOptions from './area-en-US';
|
||||
|
||||
const i18n = {
|
||||
'zh-CN': {
|
||||
@ -147,10 +148,17 @@ const i18n = {
|
||||
},
|
||||
};
|
||||
|
||||
type StateItem = {
|
||||
show: boolean;
|
||||
value: string | number | null;
|
||||
result: string;
|
||||
options?: CascaderOption[];
|
||||
};
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const t = useTranslate(i18n);
|
||||
const state = reactive({
|
||||
const state = reactive<Record<string, StateItem>>({
|
||||
base: {
|
||||
show: false,
|
||||
value: '',
|
||||
@ -182,7 +190,7 @@ export default {
|
||||
|
||||
const customFieldOptions = computed(() => {
|
||||
const options = deepClone(t('options'));
|
||||
const adjustFieldName = (item) => {
|
||||
const adjustFieldName = (item: CascaderOption) => {
|
||||
if ('text' in item) {
|
||||
item.name = item.text;
|
||||
delete item.text;
|
||||
@ -201,15 +209,21 @@ export default {
|
||||
return options;
|
||||
});
|
||||
|
||||
const loadDynamicOptions = ({ value }) => {
|
||||
const loadDynamicOptions = ({ value }: CascaderOption) => {
|
||||
if (value === '330000') {
|
||||
setTimeout(() => {
|
||||
state.async.options[0].children = t('asyncOptions2');
|
||||
state.async.options![0].children = t('asyncOptions2');
|
||||
}, 500);
|
||||
}
|
||||
};
|
||||
|
||||
const onFinish = (type, { value, selectedOptions }) => {
|
||||
const onFinish = (
|
||||
type: string,
|
||||
{
|
||||
value,
|
||||
selectedOptions,
|
||||
}: { value: number | string; selectedOptions: CascaderOption[] }
|
||||
) => {
|
||||
const result = selectedOptions
|
||||
.map((option) => option.text || option.name)
|
||||
.join('/');
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { nextTick, reactive, watch } from 'vue';
|
||||
import { nextTick, PropType, reactive, watch } from 'vue';
|
||||
import { createNamespace } from '../utils';
|
||||
|
||||
// Components
|
||||
@ -8,15 +8,34 @@ import Icon from '../icon';
|
||||
|
||||
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({
|
||||
props: {
|
||||
title: String,
|
||||
modelValue: [Number, String],
|
||||
fieldNames: Object,
|
||||
fieldNames: Object as PropType<CascaderFieldNames>,
|
||||
placeholder: String,
|
||||
activeColor: String,
|
||||
options: {
|
||||
type: Array,
|
||||
type: Array as PropType<CascaderOption[]>,
|
||||
default: () => [],
|
||||
},
|
||||
closeable: {
|
||||
@ -29,7 +48,7 @@ export default createComponent({
|
||||
|
||||
setup(props, { slots, emit }) {
|
||||
const state = reactive({
|
||||
tabs: [],
|
||||
tabs: [] as CascaderTab[],
|
||||
activeTab: 0,
|
||||
});
|
||||
|
||||
@ -40,7 +59,10 @@ export default createComponent({
|
||||
...props.fieldNames,
|
||||
};
|
||||
|
||||
const getSelectedOptionsByValue = (options, value) => {
|
||||
const getSelectedOptionsByValue = (
|
||||
options: CascaderOption[],
|
||||
value: string | number
|
||||
): CascaderOption[] | undefined => {
|
||||
for (let i = 0; i < options.length; 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;
|
||||
|
||||
if (state.tabs.length > tabIndex + 1) {
|
||||
@ -165,15 +187,19 @@ export default createComponent({
|
||||
</div>
|
||||
);
|
||||
|
||||
const renderOptions = (options, selectedOption, tabIndex) => {
|
||||
const renderOption = (option) => {
|
||||
const renderOptions = (
|
||||
options: CascaderOption[],
|
||||
selectedOption: CascaderOption | null,
|
||||
tabIndex: number
|
||||
) => {
|
||||
const renderOption = (option: CascaderOption) => {
|
||||
const isSelected =
|
||||
selectedOption && option[valueKey] === selectedOption[valueKey];
|
||||
|
||||
return (
|
||||
<li
|
||||
class={bem('option', { selected: isSelected })}
|
||||
style={{ color: isSelected ? props.activeColor : null }}
|
||||
style={{ color: isSelected ? props.activeColor : undefined }}
|
||||
onClick={() => {
|
||||
onSelect(option, tabIndex);
|
||||
}}
|
||||
@ -189,8 +215,8 @@ export default createComponent({
|
||||
return <ul class={bem('options')}>{options.map(renderOption)}</ul>;
|
||||
};
|
||||
|
||||
const renderTab = (item, tabIndex) => {
|
||||
const { options, selectedOption } = item;
|
||||
const renderTab = (tab: CascaderTab, tabIndex: number) => {
|
||||
const { options, selectedOption } = tab;
|
||||
const title = selectedOption
|
||||
? selectedOption[textKey]
|
||||
: props.placeholder || t('select');
|
Loading…
x
Reference in New Issue
Block a user