From d71bc5d6f515e38681152d8ce5463fc38046c403 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=87=AF=E9=BE=99?= <502431556@qq.com> Date: Thu, 16 Dec 2021 14:32:20 +0800 Subject: [PATCH] wip(VForm): VForm component development --- pnpm-lock.yaml | 21 ++++++-- src/App.vue | 84 +++++++++++++++++++++++-------- src/components/Form/src/VForm.vue | 19 +++++-- src/components/Form/src/helper.ts | 68 ++++++++++++++++++++++--- 4 files changed, 156 insertions(+), 36 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 071e8af..8d58a5c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,6 +24,7 @@ specifiers: less: ^4.1.2 lint-staged: ^12.1.2 lodash-es: ^4.17.21 + normalize.css: ^8.0.1 pinia: ^2.0.6 postcss: ^8.4.4 postcss-html: ^1.3.0 @@ -54,6 +55,7 @@ dependencies: '@vueuse/core': registry.npmmirror.com/@vueuse/core/7.1.2_vue@3.2.24 element-plus: registry.npmmirror.com/element-plus/1.2.0-beta.6_vue@3.2.24 lodash-es: registry.nlark.com/lodash-es/4.17.21 + normalize.css: registry.nlark.com/normalize.css/8.0.1 pinia: registry.npmmirror.com/pinia/2.0.6_typescript@4.5.2+vue@3.2.24 vue: registry.npmmirror.com/vue/3.2.24 vue-i18n: registry.npmmirror.com/vue-i18n/9.1.9_vue@3.2.24 @@ -3347,6 +3349,17 @@ packages: version: 0.2.0 dev: true + registry.nlark.com/normalize.css/8.0.1: + resolution: + { + integrity: sha1-m5iiCHOLnMJjTKrLxC0THJdIe/M=, + registry: https://registry.npm.taobao.org/, + tarball: https://registry.nlark.com/normalize.css/download/normalize.css-8.0.1.tgz + } + name: normalize.css + version: 8.0.1 + dev: false + registry.nlark.com/nth-check/2.0.1: resolution: { @@ -6961,7 +6974,7 @@ packages: { integrity: sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=, registry: https://registry.npm.taobao.org/, - tarball: https://registry.npmmirror.com/acorn/download/acorn-7.4.1.tgz?cache=0&sync_timestamp=1637226362293&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Facorn%2Fdownload%2Facorn-7.4.1.tgz + tarball: https://registry.npmmirror.com/acorn/download/acorn-7.4.1.tgz?cache=0&sync_timestamp=1637225943828&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Facorn%2Fdownload%2Facorn-7.4.1.tgz } name: acorn version: 7.4.1 @@ -6974,7 +6987,7 @@ packages: { integrity: sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw==, registry: https://registry.npm.taobao.org/, - tarball: https://registry.npmmirror.com/acorn/download/acorn-8.6.0.tgz?cache=0&sync_timestamp=1637226362293&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Facorn%2Fdownload%2Facorn-8.6.0.tgz + tarball: https://registry.npmmirror.com/acorn/download/acorn-8.6.0.tgz?cache=0&sync_timestamp=1637225943828&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Facorn%2Fdownload%2Facorn-8.6.0.tgz } name: acorn version: 8.6.0 @@ -7912,7 +7925,7 @@ packages: { integrity: sha1-MOvR73wv3/AcOk8VEESvJfqwUj4=, registry: https://registry.npm.taobao.org/, - tarball: https://registry.npmmirror.com/eslint-visitor-keys/download/eslint-visitor-keys-1.3.0.tgz?cache=0&sync_timestamp=1636378498011&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Feslint-visitor-keys%2Fdownload%2Feslint-visitor-keys-1.3.0.tgz + tarball: https://registry.npmmirror.com/eslint-visitor-keys/download/eslint-visitor-keys-1.3.0.tgz?cache=0&sync_timestamp=1636378941796&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Feslint-visitor-keys%2Fdownload%2Feslint-visitor-keys-1.3.0.tgz } name: eslint-visitor-keys version: 1.3.0 @@ -7924,7 +7937,7 @@ packages: { integrity: sha1-9lMoJZMFknOSyTjtROsKXJsr0wM=, registry: https://registry.npm.taobao.org/, - tarball: https://registry.npmmirror.com/eslint-visitor-keys/download/eslint-visitor-keys-2.1.0.tgz?cache=0&sync_timestamp=1636378498011&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Feslint-visitor-keys%2Fdownload%2Feslint-visitor-keys-2.1.0.tgz + tarball: https://registry.npmmirror.com/eslint-visitor-keys/download/eslint-visitor-keys-2.1.0.tgz?cache=0&sync_timestamp=1636378941796&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Feslint-visitor-keys%2Fdownload%2Feslint-visitor-keys-2.1.0.tgz } name: eslint-visitor-keys version: 2.1.0 diff --git a/src/App.vue b/src/App.vue index d8f7959..39dcb5c 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,42 +1,86 @@ - - - - - - {{ t('common.inputText') }} + + + + + + + + + Http:// + .com + diff --git a/src/components/Form/src/VForm.vue b/src/components/Form/src/VForm.vue index cc95e83..879b598 100644 --- a/src/components/Form/src/VForm.vue +++ b/src/components/Form/src/VForm.vue @@ -4,7 +4,7 @@ import { ElForm, ElFormItem, ElRow, ElCol } from 'element-plus' import { COMPONENT_MAP } from './componentMap' import { propTypes } from '@/utils/propTypes' import { getSlot } from '@/utils/tsxHelper' -import { setTextPlaceholder, setGridProp } from './helper' +import { setTextPlaceholder, setGridProp, setComponentProps, setItemComponentSlots } from './helper' export default defineComponent({ name: 'VForm', @@ -12,7 +12,7 @@ export default defineComponent({ // 生成Form的布局结构数组 schema: { type: Array as PropType, - require: true, + required: true, default: () => [] }, // 是否需要栅格布局 @@ -25,7 +25,9 @@ export default defineComponent({ // 是否自动设置placeholder autoSetPlaceholder: propTypes.bool.def(true), // 是否自定义内容 - isCustom: propTypes.bool.def(false) + isCustom: propTypes.bool.def(false), + // 表单label宽度 + labelWidth: propTypes.oneOfType([String, Number]).def(130) }, setup(props, { slots }) { const formRef = ref>() @@ -81,8 +83,15 @@ export default defineComponent({ typeof defineComponent > return ( - - {item.options ? renderOptions() : null} + + {{ + default: () => (item.options ? renderOptions() : null), + ...setItemComponentSlots(slots, item?.componentProps?.slots, item.field) + }} ) }} diff --git a/src/components/Form/src/helper.ts b/src/components/Form/src/helper.ts index 9ee1285..92a92de 100644 --- a/src/components/Form/src/helper.ts +++ b/src/components/Form/src/helper.ts @@ -1,5 +1,9 @@ import { useI18n } from '@/hooks/web/useI18n' const { t } = useI18n() +import { shallowRef } from 'vue' +import { isFunction } from '@/utils/is' +import { Slots } from 'vue' +import { getSlot } from '@/utils/tsxHelper' interface PlaceholderMoel { placeholder?: string @@ -52,14 +56,64 @@ export function setTextPlaceholder(schema: VFormSchema): PlaceholderMoel { */ export function setGridProp(col: ColProps = {}): ColProps { const colProps: ColProps = { - ...{ - xs: 24, - sm: 12, - md: 12, - lg: 12, - xl: 8 - }, + // 如果有span,代表用户优先级更高,所以不需要默认栅格 + ...(col.span + ? {} + : { + xs: 24, + sm: 12, + md: 12, + lg: 12, + xl: 8 + }), ...col } return colProps } + +type ComponentPropsModel = { + clearable: boolean +} & Recordable + +/** + * + * @param props 传入的组件属性 + * @returns 默认添加 clearable 属性 + */ +export function setComponentProps(props: Recordable = {}): ComponentPropsModel { + for (const key in props) { + // 如果传入的是组件,需要让其失去响应式,避免不必要的性能开销 + // 这样判断好像还不太合理。后续看看没有更合理的判断方法 + if (props[key]?.render && isFunction(props[key]?.render)) { + props[key] = shallowRef(props[key]?.render()) + } + } + const componentProps: ComponentPropsModel = { + clearable: true, + ...props + } + return componentProps +} + +/** + * + * @param slots 插槽 + * @param slotsProps 插槽属性 + * @param field 字段名 + */ +export function setItemComponentSlots( + slots: Slots, + slotsProps: Recordable = {}, + field: string +): Recordable { + const slotObj: Recordable = {} + for (const key in slotsProps) { + if (slotsProps[key]) { + // 由于组件有可能重复,需要有一个唯一的前缀 + slotObj[key] = () => { + return getSlot(slots, `${field}-${key}`) + } + } + } + return slotObj +}