feat:新增 form 组件
This commit is contained in:
151
resources/admin/components/catchForm/hooks/useSelect.js
Normal file
151
resources/admin/components/catchForm/hooks/useSelect.js
Normal file
@@ -0,0 +1,151 @@
|
||||
import { ref, reactive, computed, watch, onMounted, inject } from 'vue'
|
||||
import { isEqual, isPlainObject, debounce } from 'lodash'
|
||||
import { getDataByPath } from '/admin/components/catchForm/support'
|
||||
import { $selectData, $global } from '/admin/components/catchForm/config/symbol'
|
||||
|
||||
const useSelect = (props, emits) => {
|
||||
const selectData = inject($selectData)
|
||||
|
||||
const { request } = inject($global)
|
||||
|
||||
const selectVal = computed({
|
||||
get() {
|
||||
return props.modelValue
|
||||
},
|
||||
set(val) {
|
||||
emits('update:modelValue', val)
|
||||
}
|
||||
})
|
||||
|
||||
const currentOptions = ref([])
|
||||
|
||||
const loading = ref(false)
|
||||
|
||||
const isMax = ref(false)
|
||||
|
||||
const stateParams = reactive({
|
||||
pageNum: 1,
|
||||
pageSize: 10
|
||||
// filters: {},
|
||||
})
|
||||
|
||||
const fetchData = debounce(async () => {
|
||||
if (isMax.value || !props.api) return
|
||||
|
||||
const { url, method, data, dataPath } = props.api
|
||||
|
||||
loading.value = true
|
||||
|
||||
let res = null
|
||||
if (method === 'get') {
|
||||
res = await request.get(url, data)
|
||||
} else {
|
||||
res = await request.post(url, data)
|
||||
}
|
||||
|
||||
const resData = getDataByPath(res, dataPath)
|
||||
|
||||
if (resData.length !== stateParams.pageSize) {
|
||||
isMax.value = true
|
||||
}
|
||||
|
||||
const resDataParse = resData.map(item => {
|
||||
if (isPlainObject(item)) {
|
||||
return item
|
||||
}
|
||||
return { label: item, value: item }
|
||||
})
|
||||
|
||||
currentOptions.value = [...currentOptions.value, ...resDataParse]
|
||||
|
||||
stateParams.pageNum++
|
||||
|
||||
loading.value = false
|
||||
}, 300)
|
||||
|
||||
onMounted(() => {
|
||||
const { mode, options } = props
|
||||
if (mode === 'static') {
|
||||
currentOptions.value = options
|
||||
isMax.value = true
|
||||
}
|
||||
if (mode === 'remote') {
|
||||
fetchData()
|
||||
}
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.api,
|
||||
(newVal, oldVal) => {
|
||||
// bug:这里发生只api内存地址变化,实际api无变化也会触发监听。暂时使用深层对比解决
|
||||
if (!isEqual(newVal, oldVal)) {
|
||||
currentOptions.value = []
|
||||
isMax.value = false
|
||||
stateParams.pageNum = 1
|
||||
fetchData()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
watch(currentOptions, newVal => {
|
||||
const { autoSelectedFirst, modelValue, valueKey, multiple, sort } = props
|
||||
// 自动选中第一项
|
||||
if (autoSelectedFirst && newVal.length && !modelValue?.length) {
|
||||
const firstValue = multiple ? [newVal[0][valueKey]] : newVal[0][valueKey]
|
||||
emits('update:modelValue', firstValue)
|
||||
selectChange(firstValue)
|
||||
}
|
||||
|
||||
if (sort) {
|
||||
currentOptions.value = currentOptions.value.sort((a, b) => a.value - b.value)
|
||||
}
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.options,
|
||||
newVal => {
|
||||
if (props.mode === 'static') {
|
||||
currentOptions.value = newVal
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
watch(
|
||||
() => props.mode,
|
||||
newVal => {
|
||||
if (newVal === 'static') {
|
||||
currentOptions.value = props.options
|
||||
}
|
||||
if (newVal === 'remote') {
|
||||
currentOptions.value = []
|
||||
fetchData()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const selectChange = val => {
|
||||
const { valueKey, multiple, name } = props
|
||||
|
||||
let valueData = {}
|
||||
|
||||
if (multiple) {
|
||||
// 多选就过滤出vals对应的源数据
|
||||
valueData = currentOptions.value.filter(item => {
|
||||
return val.includes(item[valueKey])
|
||||
})
|
||||
} else {
|
||||
// 单选找到单项对应的源数据
|
||||
valueData = currentOptions.value.find(item => item[valueKey] === val)
|
||||
}
|
||||
|
||||
// 如果接到了selectData,给顶级组件保存当前值对应得数据源
|
||||
if (selectData) {
|
||||
selectData[name] = valueData
|
||||
}
|
||||
emits('onChangeSelect', selectData)
|
||||
}
|
||||
|
||||
return { selectVal, selectChange, currentOptions, loading, fetchData, isMax }
|
||||
}
|
||||
|
||||
export default useSelect
|
Reference in New Issue
Block a user