Browse Source

fix(ApiSelect): update code and fix validator error

main
刘凯 11 months ago
parent
commit
da27ad744a
  1. 38
      src/components/Form/src/components/ApiSelect.vue
  2. 11
      src/components/Form/src/components/FormItem.vue
  3. 1
      src/components/Form/src/helper.ts

38
src/components/Form/src/components/ApiSelect.vue

@ -3,19 +3,14 @@ import type { PropType } from 'vue'
import { computed, ref, unref, watch } from 'vue' import { computed, ref, unref, watch } from 'vue'
import { Select } from 'ant-design-vue' import { Select } from 'ant-design-vue'
import type { SelectValue } from 'ant-design-vue/es/select' import type { SelectValue } from 'ant-design-vue/es/select'
import { get, omit } from 'lodash-es' import { get, isEqual, omit } from 'lodash-es'
import { LoadingOutlined } from '@ant-design/icons-vue' import { LoadingOutlined } from '@ant-design/icons-vue'
import { isFunction } from '@/utils/is' import { isFunction } from '@/utils/is'
import { useRuleFormItem } from '@/hooks/component/useFormItem' import { useRuleFormItem } from '@/hooks/component/useFormItem'
import { useI18n } from '@/hooks/web/useI18n' import { useI18n } from '@/hooks/web/useI18n'
import { propTypes } from '@/utils/propTypes' import { propTypes } from '@/utils/propTypes'
interface OptionsItem { interface OptionsItem { label?: string, value?: string, disabled?: boolean, [name: string]: any }
label?: string
value?: string
disabled?: boolean
[key: string]: any
}
defineOptions({ name: 'ApiSelect', inheritAttrs: false }) defineOptions({ name: 'ApiSelect', inheritAttrs: false })
@ -39,13 +34,15 @@ const props = defineProps({
default: [], default: [],
}, },
}) })
const emit = defineEmits(['options-change', 'change', 'update:value']) const emit = defineEmits(['options-change', 'change', 'update:value'])
const options = ref<OptionsItem[]>([])
const optionsRef = ref<OptionsItem[]>([])
const loading = ref(false) const loading = ref(false)
// //
const isFirstLoaded = ref(false) const isFirstLoaded = ref(false)
const emitData = ref<OptionsItem[]>([]) const emitData = ref<OptionsItem[]>([])
const { t } = useI18n() const { t } = useI18n()
// Embedded in the form, just use the hook binding to perform form verification // Embedded in the form, just use the hook binding to perform form verification
@ -54,7 +51,7 @@ const [state] = useRuleFormItem(props, 'value', 'change', emitData)
const getOptions = computed(() => { const getOptions = computed(() => {
const { labelField, valueField, numberToString } = props const { labelField, valueField, numberToString } = props
const data = unref(options).reduce((prev, next: any) => { const data = unref(optionsRef).reduce((prev, next: any) => {
if (next) { if (next) {
const value = get(next, valueField) const value = get(next, valueField)
prev.push({ prev.push({
@ -77,8 +74,10 @@ watch(
watch( watch(
() => props.params, () => props.params,
() => { (value, oldValue) => {
!unref(isFirstLoaded) && fetch() if (isEqual(value, oldValue))
return
fetch()
}, },
{ deep: true, immediate: props.immediate }, { deep: true, immediate: props.immediate },
) )
@ -87,33 +86,33 @@ async function fetch() {
const api = props.api const api = props.api
if (!api || !isFunction(api) || loading.value) if (!api || !isFunction(api) || loading.value)
return return
options.value = [] optionsRef.value = []
try { try {
loading.value = true loading.value = true
const res = await api(props.params) const res = await api(props.params)
isFirstLoaded.value = true isFirstLoaded.value = true
if (Array.isArray(res)) { if (Array.isArray(res)) {
options.value = res optionsRef.value = res
emitChange() emitChange()
return return
} }
if (props.resultField) if (props.resultField)
options.value = get(res, props.resultField) || [] optionsRef.value = get(res, props.resultField) || []
emitChange() emitChange()
} }
catch (error) { catch (error) {
console.warn(error) console.warn(error)
// reset status
isFirstLoaded.value = false
} }
finally { finally {
loading.value = false loading.value = false
// reset status
isFirstLoaded.value = false
} }
} }
async function handleFetch(open: boolean) { async function handleFetch(visible: boolean) {
if (open) { if (visible) {
if (props.alwaysLoad) if (props.alwaysLoad)
await fetch() await fetch()
else if (!props.immediate && !unref(isFirstLoaded)) else if (!props.immediate && !unref(isFirstLoaded))
@ -126,7 +125,6 @@ function emitChange() {
} }
function handleChange(_, ...args) { function handleChange(_, ...args) {
emit('change', args[0] ? args[0].value : undefined)
emitData.value = args emitData.value = args
} }
</script> </script>

11
src/components/Form/src/components/FormItem.vue

@ -197,7 +197,10 @@ export default defineComponent({
*/ */
if (getRequired) { if (getRequired) {
if (!rules || rules.length === 0) { if (!rules || rules.length === 0) {
rules = [{ required: getRequired, validator }] const trigger = NO_AUTO_LINK_COMPONENTS.includes(component || 'Input')
? 'blur'
: 'change'
rules = [{ required: getRequired, validator, trigger }]
} }
else { else {
const requiredIndex: number = rules.findIndex(rule => Reflect.has(rule, 'required')) const requiredIndex: number = rules.findIndex(rule => Reflect.has(rule, 'required'))
@ -265,12 +268,12 @@ export default defineComponent({
const on = { const on = {
[eventKey]: (...args: Nullable<Recordable<any>>[]) => { [eventKey]: (...args: Nullable<Recordable<any>>[]) => {
const [e] = args const [e] = args
if (propsData[eventKey])
propsData[eventKey](...args)
const target = e ? e.target : null const target = e ? e.target : null
const value = target ? (isCheck ? target.checked : target.value) : e const value = target ? (isCheck ? target.checked : target.value) : e
props.setFormModel(field, value, props.schema) props.setFormModel(field, value, props.schema)
if (propsData[eventKey])
propsData[eventKey](...args)
}, },
} }
const Comp = componentMap.get(component) as ReturnType<typeof defineComponent> const Comp = componentMap.get(component) as ReturnType<typeof defineComponent>

1
src/components/Form/src/helper.ts

@ -85,4 +85,5 @@ export const NO_AUTO_LINK_COMPONENTS: ComponentType[] = [
'AutoComplete', 'AutoComplete',
'RadioButtonGroup', 'RadioButtonGroup',
'ImageUpload', 'ImageUpload',
'ApiSelect',
] ]

Loading…
Cancel
Save