mirror of
https://github.com/bufanyun/hotgo.git
synced 2026-03-04 03:04:30 +08:00
版本预发布
This commit is contained in:
105
web/src/components/CitySelector/citySelector.vue
Normal file
105
web/src/components/CitySelector/citySelector.vue
Normal file
@@ -0,0 +1,105 @@
|
||||
<template>
|
||||
<n-cascader
|
||||
v-bind="$props"
|
||||
:value="valueLabel"
|
||||
:options="dataOptions"
|
||||
:placeholder="placeholder"
|
||||
:check-strategy="checkStrategy"
|
||||
clearable
|
||||
cascade
|
||||
:on-update:value="onValueChange"
|
||||
:on-load="handleLoad"
|
||||
:on-focus="focusLoad"
|
||||
remote
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { GetCityLabel, ProvincesSelect } from '@/api/apply/provinces';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import type { CascaderOption } from 'naive-ui';
|
||||
const emits = defineEmits(['update:value', 'update:label']);
|
||||
import { basicProps } from './props';
|
||||
const props = defineProps({
|
||||
...basicProps,
|
||||
});
|
||||
|
||||
const valueLabel = ref<string | null>(null);
|
||||
const dataOptions = ref([]);
|
||||
const placeholder = computed(() => {
|
||||
if (props.dataType === 'p') {
|
||||
return '请选择省份';
|
||||
} else if (props.dataType === 'pc') {
|
||||
return '请选择省市';
|
||||
} else {
|
||||
return '请选择省市区';
|
||||
}
|
||||
});
|
||||
|
||||
function onValueChange(
|
||||
value: string | number | Array<string | number> | null,
|
||||
option: CascaderOption | Array<CascaderOption | null> | null,
|
||||
pathValues: Array<CascaderOption | null>
|
||||
) {
|
||||
const tempPathValues = pathValues
|
||||
? pathValues.map((it: CascaderOption | null) => ({
|
||||
label: it?.label,
|
||||
value: it?.value,
|
||||
level: it?.level,
|
||||
}))
|
||||
: null;
|
||||
|
||||
emits('update:value', value);
|
||||
valueLabel.value = getLabel(tempPathValues);
|
||||
}
|
||||
|
||||
function getLabel(values): string | null {
|
||||
if (values === null || values === undefined) {
|
||||
return null;
|
||||
}
|
||||
let label = '';
|
||||
const length = values.length;
|
||||
for (let i = 0; i < length; i++) {
|
||||
const item = values[i];
|
||||
label += item.label;
|
||||
if (i + 1 < length) {
|
||||
label += props.separator;
|
||||
}
|
||||
}
|
||||
return label;
|
||||
}
|
||||
|
||||
watch(
|
||||
() => props.value,
|
||||
async () => {
|
||||
if (props.value === 0) {
|
||||
valueLabel.value = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (valueLabel.value === null) {
|
||||
valueLabel.value = await GetCityLabel({ id: props.value, spilt: props.separator });
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
|
||||
async function load(option) {
|
||||
const data = await ProvincesSelect({ dataType: props.dataType, ...option });
|
||||
return data.list;
|
||||
}
|
||||
|
||||
async function handleLoad(option: CascaderOption) {
|
||||
option.children = await load({ dataType: props.dataType, ...option });
|
||||
return;
|
||||
}
|
||||
|
||||
async function focusLoad() {
|
||||
if (dataOptions.value.length === 0) {
|
||||
dataOptions.value = await load({ dataType: props.dataType });
|
||||
}
|
||||
}
|
||||
</script>
|
||||
22
web/src/components/CitySelector/props.ts
Normal file
22
web/src/components/CitySelector/props.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import type { PropType } from 'vue';
|
||||
import { NCascader } from 'naive-ui';
|
||||
|
||||
export const basicProps = {
|
||||
...NCascader.props,
|
||||
defaultValue: {
|
||||
type: [Number, String, Array],
|
||||
default: null,
|
||||
},
|
||||
value: {
|
||||
type: [Number, String, Array],
|
||||
default: null,
|
||||
},
|
||||
dataType: {
|
||||
type: String as PropType<'p' | 'pc' | 'pca'>,
|
||||
default: 'pca',
|
||||
},
|
||||
checkStrategy: {
|
||||
type: String as PropType<'child' | 'all'>,
|
||||
default: 'child',
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user