wip: 表单BUG修复中
This commit is contained in:
parent
9c724dc9aa
commit
289c1c2cf5
|
@ -2,7 +2,7 @@
|
||||||
NODE_ENV=development
|
NODE_ENV=development
|
||||||
|
|
||||||
# 接口前缀
|
# 接口前缀
|
||||||
VITE_API_BASEPATH=base
|
VITE_API_BASE_PATH=base
|
||||||
|
|
||||||
# 打包路径
|
# 打包路径
|
||||||
VITE_BASE_PATH=/
|
VITE_BASE_PATH=/
|
||||||
|
|
2
.env.dev
2
.env.dev
|
@ -2,7 +2,7 @@
|
||||||
NODE_ENV=production
|
NODE_ENV=production
|
||||||
|
|
||||||
# 接口前缀
|
# 接口前缀
|
||||||
VITE_API_BASEPATH=dev
|
VITE_API_BASE_PATH=dev
|
||||||
|
|
||||||
# 打包路径
|
# 打包路径
|
||||||
VITE_BASE_PATH=/dist-dev/
|
VITE_BASE_PATH=/dist-dev/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
NODE_ENV=production
|
NODE_ENV=production
|
||||||
|
|
||||||
# 接口前缀
|
# 接口前缀
|
||||||
VITE_API_BASEPATH=pro
|
VITE_API_BASE_PATH=pro
|
||||||
|
|
||||||
# 打包路径
|
# 打包路径
|
||||||
VITE_BASE_PATH=/vue-element-plus-admin/
|
VITE_BASE_PATH=/vue-element-plus-admin/
|
||||||
|
|
2
.env.pro
2
.env.pro
|
@ -2,7 +2,7 @@
|
||||||
NODE_ENV=production
|
NODE_ENV=production
|
||||||
|
|
||||||
# 接口前缀
|
# 接口前缀
|
||||||
VITE_API_BASEPATH=pro
|
VITE_API_BASE_PATH=pro
|
||||||
|
|
||||||
# 打包路径
|
# 打包路径
|
||||||
VITE_BASE_PATH=/
|
VITE_BASE_PATH=/
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
NODE_ENV=production
|
NODE_ENV=production
|
||||||
|
|
||||||
# 接口前缀
|
# 接口前缀
|
||||||
VITE_API_BASEPATH=test
|
VITE_API_BASE_PATH=test
|
||||||
|
|
||||||
# 打包路径
|
# 打包路径
|
||||||
VITE_BASE_PATH=/dist-test/
|
VITE_BASE_PATH=/dist-test/
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
"ts:check": "vue-tsc --noEmit",
|
"ts:check": "vue-tsc --noEmit",
|
||||||
"build:pro": "vite build --mode pro",
|
"build:pro": "vite build --mode pro",
|
||||||
"build:gitee": "vite build --mode gitee",
|
"build:gitee": "vite build --mode gitee",
|
||||||
"build:dev": "npm run ts:check && vite build --mode dev",
|
"build:dev": "vite build --mode dev",
|
||||||
"build:test": "npm run ts:check && vite build --mode test",
|
"build:test": "npm run ts:check && vite build --mode test",
|
||||||
"serve:pro": "vite preview --mode pro",
|
"serve:pro": "vite preview --mode pro",
|
||||||
"serve:dev": "vite preview --mode dev",
|
"serve:dev": "vite preview --mode dev",
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import request from '@/config/axios'
|
import request from '@/config/axios'
|
||||||
|
|
||||||
// 获取所有字典
|
// 获取所有字典
|
||||||
export const getDictApi = (): Promise<IResponse> => {
|
export const getDictApi = () => {
|
||||||
return request.get({ url: '/dict/list' })
|
return request.get({ url: '/dict/list' })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 模拟获取某个字典
|
// 模拟获取某个字典
|
||||||
export const getDictOneApi = async (): Promise<IResponse> => {
|
export const getDictOneApi = async () => {
|
||||||
return request.get({ url: '/dict/one' })
|
return request.get({ url: '/dict/one' })
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,15 @@
|
||||||
<script lang="tsx">
|
<script lang="tsx">
|
||||||
import { PropType, defineComponent, ref, computed, unref, watch, onMounted } from 'vue'
|
import {
|
||||||
import { ElForm, ElFormItem, ElRow, ElCol, ElTooltip } from 'element-plus'
|
PropType,
|
||||||
|
defineComponent,
|
||||||
|
ref,
|
||||||
|
computed,
|
||||||
|
unref,
|
||||||
|
watch,
|
||||||
|
onMounted,
|
||||||
|
defineAsyncComponent
|
||||||
|
} from 'vue'
|
||||||
|
import { ElForm, ElFormItem, ElRow, ElCol } from 'element-plus'
|
||||||
import { componentMap } from './helper/componentMap'
|
import { componentMap } from './helper/componentMap'
|
||||||
import { propTypes } from '@/utils/propTypes'
|
import { propTypes } from '@/utils/propTypes'
|
||||||
import { getSlot } from '@/utils/tsxHelper'
|
import { getSlot } from '@/utils/tsxHelper'
|
||||||
|
@ -9,8 +18,7 @@ import {
|
||||||
setGridProp,
|
setGridProp,
|
||||||
setComponentProps,
|
setComponentProps,
|
||||||
setItemComponentSlots,
|
setItemComponentSlots,
|
||||||
initModel,
|
initModel
|
||||||
setFormItemSlots
|
|
||||||
} from './helper'
|
} from './helper'
|
||||||
import { useRenderSelect } from './components/useRenderSelect'
|
import { useRenderSelect } from './components/useRenderSelect'
|
||||||
import { useRenderRadio } from './components/useRenderRadio'
|
import { useRenderRadio } from './components/useRenderRadio'
|
||||||
|
@ -19,7 +27,6 @@ import { useDesign } from '@/hooks/web/useDesign'
|
||||||
import { findIndex } from '@/utils'
|
import { findIndex } from '@/utils'
|
||||||
import { set } from 'lodash-es'
|
import { set } from 'lodash-es'
|
||||||
import { FormProps } from './types'
|
import { FormProps } from './types'
|
||||||
import { Icon } from '@/components/Icon'
|
|
||||||
import {
|
import {
|
||||||
FormSchema,
|
FormSchema,
|
||||||
FormSetProps,
|
FormSetProps,
|
||||||
|
@ -125,6 +132,11 @@ export default defineComponent({
|
||||||
return unref(elFormRef) as ComponentRef<typeof ElForm>
|
return unref(elFormRef) as ComponentRef<typeof ElForm>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getOptions = async (fn: Function) => {
|
||||||
|
const options = await fn()
|
||||||
|
console.log('=====:', options)
|
||||||
|
}
|
||||||
|
|
||||||
expose({
|
expose({
|
||||||
setValues,
|
setValues,
|
||||||
formModel,
|
formModel,
|
||||||
|
@ -139,6 +151,7 @@ export default defineComponent({
|
||||||
watch(
|
watch(
|
||||||
() => unref(getProps).schema,
|
() => unref(getProps).schema,
|
||||||
(schema = []) => {
|
(schema = []) => {
|
||||||
|
console.log('@@####')
|
||||||
formModel.value = initModel(schema, unref(formModel))
|
formModel.value = initModel(schema, unref(formModel))
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -182,95 +195,108 @@ export default defineComponent({
|
||||||
|
|
||||||
// 渲染formItem
|
// 渲染formItem
|
||||||
const renderFormItem = (item: FormSchema) => {
|
const renderFormItem = (item: FormSchema) => {
|
||||||
const formItemSlots = {
|
const formItemSlots: Recordable = {
|
||||||
default: () => {
|
default: () => {
|
||||||
if (slots[item.field]) {
|
if (slots[item.field]) {
|
||||||
return getSlot(slots, item.field, formModel.value)
|
return getSlot(slots, item.field, formModel.value)
|
||||||
} else {
|
} else {
|
||||||
const Com = componentMap[item.component as string] as ReturnType<
|
console.log(item.field)
|
||||||
typeof defineComponent
|
const Com = componentMap[item.component as string] as ReturnType<typeof defineComponent>
|
||||||
>
|
|
||||||
|
|
||||||
const { autoSetPlaceholder } = unref(getProps)
|
const { autoSetPlaceholder } = unref(getProps)
|
||||||
|
|
||||||
const componentSlots = (item?.componentProps as any)?.slots || {}
|
const componentSlots = (item?.componentProps as any)?.slots || {}
|
||||||
const slotsMap: Recordable = {
|
const slotsMap: Recordable = {
|
||||||
...setItemComponentSlots(componentSlots)
|
...setItemComponentSlots(componentSlots)
|
||||||
}
|
}
|
||||||
// 如果是select组件,并且没有自定义模板,自动渲染options
|
// // 如果是select组件,并且没有自定义模板,自动渲染options
|
||||||
if (item.component === ComponentNameEnum.SELECT) {
|
if (item.component === ComponentNameEnum.SELECT) {
|
||||||
slotsMap.default = !componentSlots.default
|
// 如果有optionApi,优先使用optionApi
|
||||||
? () => renderSelectOptions(item)
|
if (item.optionApi) {
|
||||||
: () => {
|
// 内部自动调用接口,不影响其他渲染
|
||||||
return componentSlots.default(
|
getOptions(item.optionApi)
|
||||||
unref((item?.componentProps as SelectComponentProps)?.options)
|
}
|
||||||
)
|
slotsMap.default = !componentSlots.default
|
||||||
}
|
? () => renderSelectOptions(item)
|
||||||
}
|
: () => {
|
||||||
|
return componentSlots.default(
|
||||||
// 虚拟列表
|
unref((item?.componentProps as SelectComponentProps)?.options)
|
||||||
if (item.component === ComponentNameEnum.SELECT_V2 && componentSlots.default) {
|
)
|
||||||
slotsMap.default = ({ item }) => {
|
|
||||||
return componentSlots.default(item)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 单选框组和按钮样式
|
// 虚拟列表
|
||||||
if (
|
if (item.component === ComponentNameEnum.SELECT_V2 && componentSlots.default) {
|
||||||
item.component === ComponentNameEnum.RADIO_GROUP ||
|
slotsMap.default = ({ item }) => {
|
||||||
item.component === ComponentNameEnum.RADIO_BUTTON
|
return componentSlots.default(item)
|
||||||
) {
|
|
||||||
slotsMap.default = !componentSlots.default
|
|
||||||
? () => renderRadioOptions(item)
|
|
||||||
: () => {
|
|
||||||
return componentSlots.default(
|
|
||||||
unref((item?.componentProps as CheckboxGroupComponentProps)?.options)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 多选框组和按钮样式
|
|
||||||
if (
|
|
||||||
item.component === ComponentNameEnum.CHECKBOX_GROUP ||
|
|
||||||
item.component === ComponentNameEnum.CHECKBOX_BUTTON
|
|
||||||
) {
|
|
||||||
slotsMap.default = !componentSlots.default
|
|
||||||
? () => renderCheckboxOptions(item)
|
|
||||||
: () => {
|
|
||||||
return componentSlots.default(
|
|
||||||
unref((item?.componentProps as RadioGroupComponentProps)?.options)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Com
|
|
||||||
vModel={formModel.value[item.field]}
|
|
||||||
{...(autoSetPlaceholder && setTextPlaceholder(item))}
|
|
||||||
{...setComponentProps(item)}
|
|
||||||
style={item.componentProps?.style || {}}
|
|
||||||
>
|
|
||||||
{{ ...slotsMap }}
|
|
||||||
</Com>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 单选框组和按钮样式
|
||||||
|
if (
|
||||||
|
item.component === ComponentNameEnum.RADIO_GROUP ||
|
||||||
|
item.component === ComponentNameEnum.RADIO_BUTTON
|
||||||
|
) {
|
||||||
|
slotsMap.default = !componentSlots.default
|
||||||
|
? () => renderRadioOptions(item)
|
||||||
|
: () => {
|
||||||
|
return componentSlots.default(
|
||||||
|
unref((item?.componentProps as CheckboxGroupComponentProps)?.options)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 多选框组和按钮样式
|
||||||
|
if (
|
||||||
|
item.component === ComponentNameEnum.CHECKBOX_GROUP ||
|
||||||
|
item.component === ComponentNameEnum.CHECKBOX_BUTTON
|
||||||
|
) {
|
||||||
|
slotsMap.default = !componentSlots.default
|
||||||
|
? () => renderCheckboxOptions(item)
|
||||||
|
: () => {
|
||||||
|
return componentSlots.default(
|
||||||
|
unref((item?.componentProps as RadioGroupComponentProps)?.options)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const Comp = () => {
|
||||||
|
return (
|
||||||
|
<Com
|
||||||
|
vModel={formModel.value[item.field]}
|
||||||
|
{...(autoSetPlaceholder && setTextPlaceholder(item))}
|
||||||
|
{...setComponentProps(item)}
|
||||||
|
style={item.componentProps?.style || {}}
|
||||||
|
>
|
||||||
|
{{ ...slotsMap }}
|
||||||
|
</Com>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return <>{Comp()}</>
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (item?.formItemProps?.slots?.label) {
|
if (item?.formItemProps?.slots?.label) {
|
||||||
formItemSlots.label = (...args: any[]) => {
|
formItemSlots.label = (...args: any[]) => {
|
||||||
return item.formItemProps.slots.label(...args)
|
return (item?.formItemProps?.slots as any)?.label(...args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (item?.formItemProps?.slots?.error) {
|
if (item?.formItemProps?.slots?.error) {
|
||||||
formItemSlots.error = (...args: any[]) => {
|
formItemSlots.error = (...args: any[]) => {
|
||||||
return item.formItemProps.slots.error(...args)
|
return (item?.formItemProps?.slots as any)?.error(...args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<ElFormItem {...(item.formItemProps || {})} prop={item.field} label={item.label || ''}>
|
<ElFormItem {...(item.formItemProps || {})} prop={item.field} label={item.label || ''}>
|
||||||
{{
|
{formItemSlots}
|
||||||
...formItemSlots
|
{/* {{
|
||||||
}}
|
default: () => {
|
||||||
|
console.log(item.field)
|
||||||
|
|
||||||
|
return '2222'
|
||||||
|
}
|
||||||
|
}} */}
|
||||||
</ElFormItem>
|
</ElFormItem>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -820,7 +820,7 @@ export interface FormSchema {
|
||||||
/**
|
/**
|
||||||
* @returns 远程加载下拉项
|
* @returns 远程加载下拉项
|
||||||
*/
|
*/
|
||||||
api?: <T = any>() => AxiosPromise<T>
|
optionApi?: any
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FormProps {
|
export interface FormProps {
|
||||||
|
|
|
@ -32,10 +32,6 @@ const emit = defineEmits(['update:modelValue'])
|
||||||
// 设置input的type属性
|
// 设置input的type属性
|
||||||
const textType = ref<'password' | 'text'>('password')
|
const textType = ref<'password' | 'text'>('password')
|
||||||
|
|
||||||
const changeTextType = () => {
|
|
||||||
textType.value = unref(textType) === 'text' ? 'password' : 'text'
|
|
||||||
}
|
|
||||||
|
|
||||||
// 输入框的值
|
// 输入框的值
|
||||||
const valueRef = ref(props.modelValue)
|
const valueRef = ref(props.modelValue)
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import {
|
||||||
AxiosRequestHeaders,
|
AxiosRequestHeaders,
|
||||||
AxiosError,
|
AxiosError,
|
||||||
InternalAxiosRequestConfig
|
InternalAxiosRequestConfig
|
||||||
} from './type'
|
} from './types'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import qs from 'qs'
|
import qs from 'qs'
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import config from './config'
|
||||||
|
|
||||||
const { defaultHeaders } = config
|
const { defaultHeaders } = config
|
||||||
|
|
||||||
const request = (option: any) => {
|
const request = (option: AxiosConfig) => {
|
||||||
const { url, method, params, data, headersType, responseType } = option
|
const { url, method, params, data, headersType, responseType } = option
|
||||||
return service.request({
|
return service.request({
|
||||||
url: url,
|
url: url,
|
||||||
|
@ -19,17 +19,17 @@ const request = (option: any) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
get: <T = any>(option: any) => {
|
get: <T = any>(option: AxiosConfig) => {
|
||||||
return request({ method: 'get', ...option }) as unknown as T
|
return request({ method: 'get', ...option }) as Promise<IResponse<T>>
|
||||||
},
|
},
|
||||||
post: <T = any>(option: any) => {
|
post: <T = any>(option: AxiosConfig) => {
|
||||||
return request({ method: 'post', ...option }) as unknown as T
|
return request({ method: 'post', ...option }) as Promise<IResponse<T>>
|
||||||
},
|
},
|
||||||
delete: <T = any>(option: any) => {
|
delete: <T = any>(option: AxiosConfig) => {
|
||||||
return request({ method: 'delete', ...option }) as unknown as T
|
return request({ method: 'delete', ...option }) as Promise<IResponse<T>>
|
||||||
},
|
},
|
||||||
put: <T = any>(option: any) => {
|
put: <T = any>(option: AxiosConfig) => {
|
||||||
return request({ method: 'put', ...option }) as unknown as T
|
return request({ method: 'put', ...option }) as Promise<IResponse<T>>
|
||||||
},
|
},
|
||||||
cancelRequest: (url: string | string[]) => {
|
cancelRequest: (url: string | string[]) => {
|
||||||
return service.cancelRequest(url)
|
return service.cancelRequest(url)
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import config, { defaultRequestInterceptors, defaultResponseInterceptors } from './config'
|
import config, { defaultRequestInterceptors, defaultResponseInterceptors } from './config'
|
||||||
|
|
||||||
import { AxiosInstance, InternalAxiosRequestConfig, RequestConfig, AxiosResponse } from './type'
|
import { AxiosInstance, InternalAxiosRequestConfig, RequestConfig, AxiosResponse } from './types'
|
||||||
|
|
||||||
const { interceptors, baseUrl } = config
|
const { interceptors, baseUrl } = config
|
||||||
export const PATH_URL = baseUrl[import.meta.env.VITE_API_BASEPATH]
|
export const PATH_URL = baseUrl[import.meta.env.VITE_API_BASE_PATH]
|
||||||
|
|
||||||
const { requestInterceptors, responseInterceptors } = interceptors
|
const { requestInterceptors, responseInterceptors } = interceptors
|
||||||
|
|
||||||
|
|
|
@ -283,7 +283,9 @@ export default {
|
||||||
verifyReset: 'Verify reset',
|
verifyReset: 'Verify reset',
|
||||||
// 富文本编辑器
|
// 富文本编辑器
|
||||||
richText: 'Rich text',
|
richText: 'Rich text',
|
||||||
form: 'Form'
|
form: 'Form',
|
||||||
|
// 远程加载
|
||||||
|
remoteLoading: 'Remote loading'
|
||||||
},
|
},
|
||||||
guideDemo: {
|
guideDemo: {
|
||||||
guide: 'Guide',
|
guide: 'Guide',
|
||||||
|
|
|
@ -282,7 +282,9 @@ export default {
|
||||||
verifyReset: '验证重置',
|
verifyReset: '验证重置',
|
||||||
// 富文本编辑器
|
// 富文本编辑器
|
||||||
richText: '富文本编辑器',
|
richText: '富文本编辑器',
|
||||||
form: '表单'
|
form: '表单',
|
||||||
|
// 远程加载
|
||||||
|
remoteLoading: '远程加载'
|
||||||
},
|
},
|
||||||
guideDemo: {
|
guideDemo: {
|
||||||
guide: '引导页',
|
guide: '引导页',
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -9,7 +9,7 @@ declare module '*.vue' {
|
||||||
|
|
||||||
interface ImportMetaEnv {
|
interface ImportMetaEnv {
|
||||||
readonly VITE_APP_TITLE: string
|
readonly VITE_APP_TITLE: string
|
||||||
readonly VITE_API_BASEPATH: string
|
readonly VITE_API_BASE_PATH: string
|
||||||
readonly VITE_BASE_PATH: string
|
readonly VITE_BASE_PATH: string
|
||||||
readonly VITE_DROP_DEBUGGER: string
|
readonly VITE_DROP_DEBUGGER: string
|
||||||
readonly VITE_DROP_CONSOLE: string
|
readonly VITE_DROP_CONSOLE: string
|
||||||
|
|
Loading…
Reference in New Issue