form-create: 封装通用选择器 hook

This commit is contained in:
puhui999 2024-05-01 19:53:35 +08:00
parent c1c21d826d
commit b4d85b782e
8 changed files with 114 additions and 63 deletions

View File

@ -1,3 +0,0 @@
import DictSelect from './src/DictSelect.vue'
export { DictSelect }

View File

@ -1,46 +0,0 @@
<!-- 数据字典 Select 选择器 -->
<template>
<el-select class="w-1/1" v-bind="attrs">
<template v-if="valueType === 'int'">
<el-option
v-for="(dict, index) in getIntDictOptions(dictType)"
:key="index"
:label="dict.label"
:value="dict.value"
/>
</template>
<template v-if="valueType === 'str'">
<el-option
v-for="(dict, index) in getStrDictOptions(dictType)"
:key="index"
:label="dict.label"
:value="dict.value"
/>
</template>
<template v-if="valueType === 'bool'">
<el-option
v-for="(dict, index) in getBoolDictOptions(dictType)"
:key="index"
:label="dict.label"
:value="dict.value"
/>
</template>
</el-select>
</template>
<script lang="ts" setup>
import { getBoolDictOptions, getIntDictOptions, getStrDictOptions } from '@/utils/dict'
//
interface Props {
dictType: string //
valueType: string //
}
withDefaults(defineProps<Props>(), {
dictType: '',
valueType: 'str'
})
const attrs = useAttrs()
defineOptions({ name: 'DictSelect' })
</script>

View File

@ -1,25 +1,41 @@
import request from '@/config/axios'
import { isEmpty } from '@/utils/is'
import { CurrencySelectProps } from '@/components/FormCreate/src/type'
import { getBoolDictOptions, getIntDictOptions, getStrDictOptions } from '@/utils/dict'
export const useCurrencySelect = (option: CurrencySelectProps) => {
return defineComponent({
name: option.name,
props: {
// 字典类型
// 选项标签
labelField: {
type: String,
default: () => option.labelField ?? ''
default: () => option.labelField ?? 'label'
},
// 字典值类型
// 选项的值
valueField: {
type: String,
default: () => option.valueField ?? ''
default: () => option.valueField ?? 'value'
},
// api 接口
restful: {
type: String,
default: () => option.restful ?? ''
},
// 字典类型
dictType: {
type: String,
default: ''
},
// 字典值类型 'str' | 'int' | 'bool'
dictValueType: {
type: String,
default: 'str'
},
// 选择器类型,下拉框 select、多选框 checkbox、单选框 radio
selectType: {
type: String,
default: 'select'
}
},
setup(props) {
@ -27,6 +43,12 @@ export const useCurrencySelect = (option: CurrencySelectProps) => {
const options = ref<any[]>([]) // 下拉数据
const getOptions = async () => {
options.value = []
// 字典选择器
if (option.isDict) {
options.value = getDictOptions()
return
}
// 接口选择器
if (isEmpty(props.restful)) {
return
}
@ -41,17 +63,78 @@ export const useCurrencySelect = (option: CurrencySelectProps) => {
}
console.log(`接口[${props.restful}] 返回结果不是一个数组`)
}
// 获得字典配置
const getDictOptions = () => {
switch (props.dictValueType) {
case 'str':
return getStrDictOptions(props.dictType)
case 'int':
return getIntDictOptions(props.dictType)
case 'bool':
return getBoolDictOptions(props.dictType)
default:
return []
}
}
onMounted(async () => {
await getOptions()
})
const buildSelect = () => {
return (
<>
<el-select class="w-1/1" {...attrs}>
{options.value.map((item, index) => (
<el-option key={index} label={item.label} value={item.value} />
))}
</el-select>
</>
)
}
const buildCheckbox = () => {
if (isEmpty(options.value)) {
options.value = [
{ label: '选项1', value: '选项1' },
{ label: '选项2', value: '选项2' }
]
}
return (
<>
<el-checkbox-group class="w-1/1" {...attrs}>
{options.value.map((item, index) => (
<el-checkbox key={index} label={item.label} value={item.value} />
))}
</el-checkbox-group>
</>
)
}
const buildRadio = () => {
if (isEmpty(options.value)) {
options.value = [
{ label: '选项1', value: '选项1' },
{ label: '选项2', value: '选项2' }
]
}
return (
<>
<el-radio-group class="w-1/1" {...attrs}>
{options.value.map((item, index) => (
<el-radio key={index} value={item.value}>
{item.label}
</el-radio>
))}
</el-radio-group>
</>
)
}
return () => (
<>
<el-select className="w-1/1" {...attrs}>
{options.value.map((item, index) => (
<el-option key={index} label={item.label} value={item.value} />
))}
</el-select>
{props.selectType === 'select'
? buildSelect()
: props.selectType === 'radio'
? buildRadio()
: props.selectType === 'checkbox'
? buildCheckbox()
: buildSelect()}
</>
)
}

View File

@ -1,4 +1,15 @@
const selectRule = [
{
type: 'select',
field: 'selectType',
title: '选择器类型',
value: 'select',
options: [
{ label: '下拉框', value: 'select' },
{ label: '单选框', value: 'radio' },
{ label: '多选框', value: 'checkbox' }
]
},
{ type: 'switch', field: 'multiple', title: '是否多选' },
{
type: 'switch',

View File

@ -46,7 +46,7 @@ export const useDictSelectRule = () => {
},
{
type: 'select',
field: 'valueType',
field: 'dictValueType',
title: '字典值类型',
value: 'str',
options: [

View File

@ -35,9 +35,10 @@ export interface DragRule {
// 通用下拉组件 Props 类型
export interface CurrencySelectProps {
name: string // 组件名称
labelField?: string // 字典类型
valueField?: string // 字典值类型
labelField?: string // 选项标签
valueField?: string // 选项的值
restful?: string // api 接口
isDict?: boolean // 是否字典选择器
}
// 选择组件规则配置类型

View File

@ -67,6 +67,8 @@ export const useFormCreateDesigner = async (designer: Ref) => {
designer.value?.removeMenuItem('fc-editor')
// 移除自带的下拉选择器组件,使用 currencySelectRule 替代
designer.value?.removeMenuItem('select')
designer.value?.removeMenuItem('radio')
designer.value?.removeMenuItem('checkbox')
const components = [
editorRule,
uploadFileRule,

View File

@ -19,7 +19,6 @@ import formCreate from '@form-create/element-ui'
import install from '@form-create/element-ui/auto-import'
//======================= 自定义组件 =======================
import { UploadFile, UploadImg, UploadImgs } from '@/components/UploadFile'
import { DictSelect } from '@/components/DictSelect'
import { useCurrencySelect } from '@/components/FormCreate'
import { Editor } from '@/components/Editor'
@ -38,6 +37,10 @@ const DeptSelect = useCurrencySelect({
const RestfulSelect = useCurrencySelect({
name: 'RestfulSelect'
})
const DictSelect = useCurrencySelect({
name: 'DictSelect',
isDict: true
})
const components = [
ElAside,
ElPopconfirm,