feat(useForm): Add useForm

This commit is contained in:
陈凯龙 2022-01-07 17:38:24 +08:00
parent eb68f1d919
commit 357fc44e51
13 changed files with 489 additions and 91 deletions

View File

@ -31,6 +31,7 @@
"animate.css": "^4.1.1",
"element-plus": "1.3.0-beta.1",
"lodash-es": "^4.17.21",
"mockjs": "^1.1.0",
"pinia": "^2.0.9",
"vue": "3.2.26",
"vue-i18n": "9.1.9",
@ -74,6 +75,7 @@
"typescript": "4.5.4",
"vite": "2.7.10",
"vite-plugin-eslint": "^1.3.0",
"vite-plugin-mock": "^2.9.6",
"vite-plugin-purge-icons": "^0.7.0",
"vite-plugin-style-import": "^1.4.1",
"vite-plugin-svg-icons": "^1.1.0",

View File

@ -14,7 +14,6 @@ specifiers:
'@vitejs/plugin-vue': ^2.0.1
'@vitejs/plugin-vue-jsx': ^1.3.3
'@vueuse/core': ^7.5.1
'@windicss/plugin-animations': ^1.0.9
'@zxcvbn-ts/core': ^1.2.0
animate.css: ^4.1.1
autoprefixer: ^10.4.1
@ -29,6 +28,7 @@ specifiers:
less: ^4.1.2
lint-staged: ^12.1.4
lodash-es: ^4.17.21
mockjs: ^1.1.0
pinia: ^2.0.9
postcss: ^8.4.5
postcss-html: ^1.3.0
@ -44,6 +44,7 @@ specifiers:
typescript: 4.5.4
vite: 2.7.10
vite-plugin-eslint: ^1.3.0
vite-plugin-mock: ^2.9.6
vite-plugin-purge-icons: ^0.7.0
vite-plugin-style-import: ^1.4.1
vite-plugin-svg-icons: ^1.1.0
@ -64,6 +65,7 @@ dependencies:
animate.css: registry.npmmirror.com/animate.css/4.1.1
element-plus: registry.npmmirror.com/element-plus/1.3.0-beta.1_vue@3.2.26
lodash-es: registry.nlark.com/lodash-es/4.17.21
mockjs: registry.npmmirror.com/mockjs/1.1.0
pinia: registry.npmmirror.com/pinia/2.0.9_typescript@4.5.4+vue@3.2.26
vue: registry.npmmirror.com/vue/3.2.26
vue-i18n: registry.npmmirror.com/vue-i18n/9.1.9_vue@3.2.26
@ -83,7 +85,6 @@ devDependencies:
'@typescript-eslint/parser': registry.npmmirror.com/@typescript-eslint/parser/5.8.1_eslint@8.6.0+typescript@4.5.4
'@vitejs/plugin-vue': registry.npmmirror.com/@vitejs/plugin-vue/2.0.1_vite@2.7.10+vue@3.2.26
'@vitejs/plugin-vue-jsx': registry.npmmirror.com/@vitejs/plugin-vue-jsx/1.3.3
'@windicss/plugin-animations': registry.npmmirror.com/@windicss/plugin-animations/1.0.9
autoprefixer: registry.npmmirror.com/autoprefixer/10.4.1_postcss@8.4.5
commitizen: registry.npmmirror.com/commitizen/4.2.4_@types+node@17.0.5
eslint: registry.npmmirror.com/eslint/8.6.0
@ -108,6 +109,7 @@ devDependencies:
typescript: registry.npmmirror.com/typescript/4.5.4
vite: registry.npmmirror.com/vite/2.7.10_less@4.1.2
vite-plugin-eslint: registry.nlark.com/vite-plugin-eslint/1.3.0_vite@2.7.10
vite-plugin-mock: registry.npmmirror.com/vite-plugin-mock/2.9.6_mockjs@1.1.0+vite@2.7.10
vite-plugin-purge-icons: registry.nlark.com/vite-plugin-purge-icons/0.7.0_vite@2.7.10
vite-plugin-style-import: registry.npmmirror.com/vite-plugin-style-import/1.4.1_vite@2.7.10
vite-plugin-svg-icons: registry.npmmirror.com/vite-plugin-svg-icons/1.1.0_vite@2.7.10
@ -274,7 +276,7 @@ packages:
'@iconify/iconify': registry.npmmirror.com/@iconify/iconify/2.0.0-rc.6
axios: registry.npmmirror.com/axios/0.21.4_debug@4.3.3
debug: registry.npmmirror.com/debug/4.3.3
fast-glob: registry.npmmirror.com/fast-glob/3.2.7
fast-glob: registry.nlark.com/fast-glob/3.2.7
fs-extra: registry.nlark.com/fs-extra/9.1.0
transitivePeerDependencies:
- supports-color
@ -572,6 +574,21 @@ packages:
engines: { node: '>=12' }
dev: true
registry.nlark.com/anymatch/3.1.2:
resolution:
{
integrity: sha1-wFV8CWrzLxBhmPT04qODU343hxY=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.nlark.com/anymatch/download/anymatch-3.1.2.tgz
}
name: anymatch
version: 3.1.2
engines: { node: '>= 8' }
dependencies:
normalize-path: registry.nlark.com/normalize-path/3.0.0
picomatch: registry.npmmirror.com/picomatch/2.3.0
dev: true
registry.nlark.com/argparse/1.0.10:
resolution:
{
@ -818,6 +835,18 @@ packages:
pascalcase: registry.npmmirror.com/pascalcase/0.1.1
dev: true
registry.nlark.com/binary-extensions/2.2.0:
resolution:
{
integrity: sha1-dfUC7q+f/eQvyYgpZFvk6na9ni0=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.nlark.com/binary-extensions/download/binary-extensions-2.2.0.tgz
}
name: binary-extensions
version: 2.2.0
engines: { node: '>=8' }
dev: true
registry.nlark.com/bluebird/3.7.2:
resolution:
{
@ -891,6 +920,18 @@ packages:
fill-range: registry.nlark.com/fill-range/7.0.1
dev: true
registry.nlark.com/builtin-modules/3.2.0:
resolution:
{
integrity: sha1-RdXbmefuXmvE82LgCL+RerUEmIc=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.nlark.com/builtin-modules/download/builtin-modules-3.2.0.tgz
}
name: builtin-modules
version: 3.2.0
engines: { node: '>=6' }
dev: true
registry.nlark.com/cachedir/2.2.0:
resolution:
{
@ -1456,6 +1497,18 @@ packages:
version: 0.1.4
dev: true
registry.nlark.com/deepmerge/4.2.2:
resolution:
{
integrity: sha1-RNLqNnm49NT/ujPwPYZfwee/SVU=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.nlark.com/deepmerge/download/deepmerge-4.2.2.tgz
}
name: deepmerge
version: 4.2.2
engines: { node: '>=0.10.0' }
dev: true
registry.nlark.com/define-property/0.2.5:
resolution:
{
@ -2563,7 +2616,7 @@ packages:
dependencies:
array-union: registry.nlark.com/array-union/2.1.0
dir-glob: registry.nlark.com/dir-glob/3.0.1
fast-glob: registry.npmmirror.com/fast-glob/3.2.7
fast-glob: registry.nlark.com/fast-glob/3.2.7
ignore: registry.npmmirror.com/ignore/5.2.0
merge2: registry.nlark.com/merge2/1.4.1
slash: registry.nlark.com/slash/3.0.0
@ -2982,6 +3035,20 @@ packages:
version: 0.2.1
dev: true
registry.nlark.com/is-binary-path/2.1.0:
resolution:
{
integrity: sha1-6h9/O4DwZCNug0cPhsCcJU+0Wwk=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.nlark.com/is-binary-path/download/is-binary-path-2.1.0.tgz
}
name: is-binary-path
version: 2.1.0
engines: { node: '>=8' }
dependencies:
binary-extensions: registry.nlark.com/binary-extensions/2.2.0
dev: true
registry.nlark.com/is-data-descriptor/0.1.4:
resolution:
{
@ -3815,7 +3882,7 @@ packages:
engines: { node: '>=8.6' }
dependencies:
braces: registry.nlark.com/braces/3.0.2
picomatch: registry.nlark.com/picomatch/2.3.0
picomatch: registry.npmmirror.com/picomatch/2.3.0
dev: true
registry.nlark.com/mimic-fn/1.2.0:
@ -4011,7 +4078,7 @@ packages:
version: 2.5.0
dependencies:
hosted-git-info: registry.npmmirror.com/hosted-git-info/2.8.9
resolve: registry.nlark.com/resolve/1.20.0
resolve: registry.npmmirror.com/resolve/1.20.0
semver: registry.nlark.com/semver/5.7.1
validate-npm-package-license: registry.nlark.com/validate-npm-package-license/3.0.4
dev: true
@ -4416,6 +4483,17 @@ packages:
version: 1.0.7
dev: true
registry.nlark.com/path-to-regexp/6.2.0:
resolution:
{
integrity: sha1-97OAMzYQTDRoia3s5hRmkjBkXzg=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.nlark.com/path-to-regexp/download/path-to-regexp-6.2.0.tgz
}
name: path-to-regexp
version: 6.2.0
dev: true
registry.nlark.com/path-type/4.0.0:
resolution:
{
@ -4686,7 +4764,7 @@ packages:
jstransformer: registry.nlark.com/jstransformer/1.0.0
pug-error: registry.npmmirror.com/pug-error/2.0.0
pug-walk: registry.nlark.com/pug-walk/2.0.0
resolve: registry.nlark.com/resolve/1.20.0
resolve: registry.npmmirror.com/resolve/1.20.0
dev: true
registry.nlark.com/pug-lexer/5.0.1:
@ -4887,6 +4965,20 @@ packages:
util-deprecate: registry.nlark.com/util-deprecate/1.0.2
dev: true
registry.nlark.com/readdirp/3.6.0:
resolution:
{
integrity: sha1-dKNwvYVxFuJFspzJc0DNQxoCpsc=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.nlark.com/readdirp/download/readdirp-3.6.0.tgz
}
name: readdirp
version: 3.6.0
engines: { node: '>=8.10.0' }
dependencies:
picomatch: registry.npmmirror.com/picomatch/2.3.0
dev: true
registry.nlark.com/redent/3.0.0:
resolution:
{
@ -7535,6 +7627,45 @@ packages:
version: 2.11.0
dev: false
registry.npmmirror.com/@rollup/plugin-node-resolve/13.1.3:
resolution:
{
integrity: sha512-BdxNk+LtmElRo5d06MGY4zoepyrXX1tkzX2hrnPEZ53k78GuOMWLqmJDGIIOPwVRIFZrLQOo+Yr6KtCuLIA0AQ==,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/@rollup/plugin-node-resolve/download/@rollup/plugin-node-resolve-13.1.3.tgz
}
name: '@rollup/plugin-node-resolve'
version: 13.1.3
engines: { node: '>= 10.0.0' }
peerDependencies:
rollup: ^2.42.0
dependencies:
'@rollup/pluginutils': registry.npmmirror.com/@rollup/pluginutils/3.1.0
'@types/resolve': registry.npmmirror.com/@types/resolve/1.17.1
builtin-modules: registry.nlark.com/builtin-modules/3.2.0
deepmerge: registry.nlark.com/deepmerge/4.2.2
is-module: registry.npmmirror.com/is-module/1.0.0
resolve: registry.npmmirror.com/resolve/1.20.0
dev: true
registry.npmmirror.com/@rollup/pluginutils/3.1.0:
resolution:
{
integrity: sha1-cGtFJO5tyLEDs8mVUz5a1oDAK5s=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/@rollup/pluginutils/download/@rollup/pluginutils-3.1.0.tgz
}
name: '@rollup/pluginutils'
version: 3.1.0
engines: { node: '>= 8.0.0' }
peerDependencies:
rollup: ^1.20.0||^2.0.0
dependencies:
'@types/estree': registry.npmmirror.com/@types/estree/0.0.39
estree-walker: registry.npmmirror.com/estree-walker/1.0.1
picomatch: registry.npmmirror.com/picomatch/2.3.0
dev: true
registry.npmmirror.com/@rollup/pluginutils/4.1.2:
resolution:
{
@ -7562,6 +7693,17 @@ packages:
engines: { node: '>=10.13.0' }
dev: true
registry.npmmirror.com/@types/estree/0.0.39:
resolution:
{
integrity: sha1-4Xfmme4bjCLSMXTKqnQiZEOJUJ8=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/@types/estree/download/@types/estree-0.0.39.tgz
}
name: '@types/estree'
version: 0.0.39
dev: true
registry.npmmirror.com/@types/json-schema/7.0.9:
resolution:
{
@ -7619,6 +7761,17 @@ packages:
version: 1.2.2
dev: true
registry.npmmirror.com/@types/mockjs/1.0.4:
resolution:
{
integrity: sha1-5waVHV4ztPCku3Ox+LEk4m8IHeA=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/@types/mockjs/download/@types/mockjs-1.0.4.tgz
}
name: '@types/mockjs'
version: 1.0.4
dev: true
registry.npmmirror.com/@types/node/17.0.5:
resolution:
{
@ -7652,6 +7805,19 @@ packages:
version: 4.0.0
dev: true
registry.npmmirror.com/@types/resolve/1.17.1:
resolution:
{
integrity: sha1-Ov1q2JZ8d+Q3bFmKgt3Vj0bsRdY=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/@types/resolve/download/@types/resolve-1.17.1.tgz
}
name: '@types/resolve'
version: 1.17.1
dependencies:
'@types/node': registry.npmmirror.com/@types/node/17.0.5
dev: true
registry.npmmirror.com/@types/svgo/2.6.0:
resolution:
{
@ -8234,17 +8400,6 @@ packages:
- supports-color
dev: true
registry.npmmirror.com/@windicss/plugin-animations/1.0.9:
resolution:
{
integrity: sha1-q9fILZBuvX1hzcYqMBm2DoxXynI=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/@windicss/plugin-animations/download/@windicss/plugin-animations-1.0.9.tgz
}
name: '@windicss/plugin-animations'
version: 1.0.9
dev: true
registry.npmmirror.com/@windicss/plugin-utils/1.6.1:
resolution:
{
@ -8258,7 +8413,7 @@ packages:
'@antfu/utils': registry.npmmirror.com/@antfu/utils/0.3.0
'@windicss/config': registry.npmmirror.com/@windicss/config/1.6.1
debug: registry.npmmirror.com/debug/4.3.3
fast-glob: registry.npmmirror.com/fast-glob/3.2.7
fast-glob: registry.nlark.com/fast-glob/3.2.7
magic-string: registry.nlark.com/magic-string/0.25.7
micromatch: registry.npmmirror.com/micromatch/4.0.4
windicss: registry.npmmirror.com/windicss/3.4.2
@ -8623,6 +8778,28 @@ packages:
version: 0.7.0
dev: true
registry.npmmirror.com/chokidar/3.5.2:
resolution:
{
integrity: sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/chokidar/download/chokidar-3.5.2.tgz
}
name: chokidar
version: 3.5.2
engines: { node: '>= 8.10.0' }
dependencies:
anymatch: registry.nlark.com/anymatch/3.1.2
braces: registry.nlark.com/braces/3.0.2
glob-parent: registry.npmmirror.com/glob-parent/5.1.2
is-binary-path: registry.nlark.com/is-binary-path/2.1.0
is-glob: registry.npmmirror.com/is-glob/4.0.3
normalize-path: registry.nlark.com/normalize-path/3.0.0
readdirp: registry.nlark.com/readdirp/3.6.0
optionalDependencies:
fsevents: registry.npmmirror.com/fsevents/2.3.2
dev: true
registry.npmmirror.com/cli-truncate/2.1.0:
resolution:
{
@ -8724,7 +8901,6 @@ packages:
name: commander
version: 8.3.0
engines: { node: '>= 12' }
dev: true
registry.npmmirror.com/commitizen/4.2.4:
resolution:
@ -9413,6 +9589,19 @@ packages:
dev: true
optional: true
registry.npmmirror.com/esbuild/0.11.3:
resolution:
{
integrity: sha512-BzVRHcCtFepjS9WcqRjqoIxLqgpK21a8J4Zi4msSGxDxiXVO1IbcqT1KjhdDDnJxKfe7bvzZrvMEX+bVO0Elcw==,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/esbuild/download/esbuild-0.11.3.tgz
}
name: esbuild
version: 0.11.3
hasBin: true
requiresBuild: true
dev: true
registry.npmmirror.com/esbuild/0.13.15:
resolution:
{
@ -9767,6 +9956,17 @@ packages:
engines: { node: '>=4.0' }
dev: true
registry.npmmirror.com/estree-walker/1.0.1:
resolution:
{
integrity: sha1-MbxdYSyWtwQQa0d+bdXYqhOMtwA=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/estree-walker/download/estree-walker-1.0.1.tgz
}
name: estree-walker
version: 1.0.1
dev: true
registry.npmmirror.com/estree-walker/2.0.2:
resolution:
{
@ -9833,24 +10033,6 @@ packages:
strip-final-newline: registry.nlark.com/strip-final-newline/2.0.0
dev: true
registry.npmmirror.com/fast-glob/3.2.7:
resolution:
{
integrity: sha1-/Wy3otfpqnp4RhEehaGW1rL3ZqE=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/fast-glob/download/fast-glob-3.2.7.tgz
}
name: fast-glob
version: 3.2.7
engines: { node: '>=8' }
dependencies:
'@nodelib/fs.stat': registry.npmmirror.com/@nodelib/fs.stat/2.0.5
'@nodelib/fs.walk': registry.nlark.com/@nodelib/fs.walk/1.2.8
glob-parent: registry.npmmirror.com/glob-parent/5.1.2
merge2: registry.nlark.com/merge2/1.4.1
micromatch: registry.npmmirror.com/micromatch/4.0.4
dev: true
registry.npmmirror.com/find-up/4.1.0:
resolution:
{
@ -10251,6 +10433,17 @@ packages:
is-extglob: registry.nlark.com/is-extglob/2.1.1
dev: true
registry.npmmirror.com/is-module/1.0.0:
resolution:
{
integrity: sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/is-module/download/is-module-1.0.0.tgz
}
name: is-module
version: 1.0.0
dev: true
registry.npmmirror.com/is-regexp/2.1.0:
resolution:
{
@ -10686,6 +10879,20 @@ packages:
dev: true
optional: true
registry.npmmirror.com/mockjs/1.1.0:
resolution:
{
integrity: sha512-eQsKcWzIaZzEZ07NuEyO4Nw65g0hdWAyurVol1IPl1gahRwY+svqzfgfey8U8dahLwG44d6/RwEzuK52rSa/JQ==,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/mockjs/download/mockjs-1.1.0.tgz
}
name: mockjs
version: 1.1.0
hasBin: true
dependencies:
commander: registry.npmmirror.com/commander/8.3.0
dev: false
registry.npmmirror.com/mrmime/1.0.0:
resolution:
{
@ -11177,6 +11384,20 @@ packages:
deprecated: https://github.com/lydell/resolve-url#deprecated
dev: true
registry.npmmirror.com/resolve/1.20.0:
resolution:
{
integrity: sha1-YpoBP7P3B1XW8LeTXMHCxTeLGXU=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/resolve/download/resolve-1.20.0.tgz
}
name: resolve
version: 1.20.0
dependencies:
is-core-module: registry.npmmirror.com/is-core-module/2.8.0
path-parse: registry.nlark.com/path-parse/1.0.7
dev: true
registry.npmmirror.com/rimraf/3.0.2:
resolution:
{
@ -11837,6 +12058,37 @@ packages:
deprecated: Please see https://github.com/lydell/urix#deprecated
dev: true
registry.npmmirror.com/vite-plugin-mock/2.9.6_mockjs@1.1.0+vite@2.7.10:
resolution:
{
integrity: sha1-BN0j3muqBS+qW5rTF1FMkNYgXiU=,
registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/vite-plugin-mock/download/vite-plugin-mock-2.9.6.tgz
}
id: registry.npmmirror.com/vite-plugin-mock/2.9.6
name: vite-plugin-mock
version: 2.9.6
engines: { node: '>=12.0.0' }
peerDependencies:
mockjs: '>=1.1.0'
vite: '>=2.0.0'
dependencies:
'@rollup/plugin-node-resolve': registry.npmmirror.com/@rollup/plugin-node-resolve/13.1.3
'@types/mockjs': registry.npmmirror.com/@types/mockjs/1.0.4
chalk: registry.npmmirror.com/chalk/4.1.2
chokidar: registry.npmmirror.com/chokidar/3.5.2
connect: registry.nlark.com/connect/3.7.0
debug: registry.npmmirror.com/debug/4.3.3
esbuild: registry.npmmirror.com/esbuild/0.11.3
fast-glob: registry.nlark.com/fast-glob/3.2.7
mockjs: registry.npmmirror.com/mockjs/1.1.0
path-to-regexp: registry.nlark.com/path-to-regexp/6.2.0
vite: registry.npmmirror.com/vite/2.7.10_less@4.1.2
transitivePeerDependencies:
- rollup
- supports-color
dev: true
registry.npmmirror.com/vite-plugin-style-import/1.4.1_vite@2.7.10:
resolution:
{

View File

@ -1,8 +1,8 @@
import Form from './src/Form.vue'
export interface FormExpose {
count: number
sayHello: () => void
setValues: (data: FormSetValuesType[]) => void
formModel: Recordable
}
export { Form }

View File

@ -1,5 +1,5 @@
<script lang="tsx">
import { PropType, defineComponent, ref, computed, unref, watch } from 'vue'
import { PropType, defineComponent, ref, computed, unref, watch, onMounted } from 'vue'
import { ElForm, ElFormItem, ElRow, ElCol } from 'element-plus'
import { componentMap } from './componentMap'
import { propTypes } from '@/utils/propTypes'
@ -39,9 +39,10 @@ export default defineComponent({
// label
labelWidth: propTypes.oneOfType([String, Number]).def(130)
},
setup(props, { slots }) {
emits: ['register'],
setup(props, { slots, expose, emit }) {
// element form
const formRef = ref<ComponentRef<typeof ElForm>>()
const elFormRef = ref<ComponentRef<typeof ElForm>>()
const getProps = computed(() => props)
const { schema, isCol, isCustom, autoSetPlaceholder } = unref(getProps)
//
@ -56,6 +57,25 @@ export default defineComponent({
}
)
onMounted(() => {
emit('register', elFormRef.value?.$parent, elFormRef.value)
})
//
function setValues(data: FormSetValuesType[]) {
if (!data.length) return
const formData: Recordable = {}
for (const v of data) {
formData[v.field] = v.value
}
formModel.value = Object.assign(unref(formModel), formData)
}
expose({
setValues,
formModel
})
// formModel
watch(
() => schema,
@ -113,7 +133,7 @@ export default defineComponent({
slotsMap.default = () => renderOptions(item)
}
return (
<ElFormItem {...(item.formItemProps || {})} prop={item.field} label={item.label}>
<ElFormItem {...(item.formItemProps || {})} prop={item.field} label={item.label || ''}>
{{
...setFormItemSlots(slots, item.field),
default: () => {
@ -174,7 +194,7 @@ export default defineComponent({
}
return () => (
<ElForm ref={formRef} {...getFormBindValue()} model={formModel} class="v-form">
<ElForm ref={elFormRef} {...getFormBindValue()} model={formModel} class="v-form">
{{
//
default: () => (isCustom ? getSlot(slots, 'default') : renderWrap())

View File

@ -124,7 +124,7 @@ export function initModel(schema: FormSchema[], formModel: Recordable) {
// 如果是hidden就删除对应的值
if (v.hidden) {
delete model[v.field]
} else {
} else if (v.component && v.component !== 'Divider') {
const hasField = Reflect.has(model, v.field)
// 如果先前已经有值存在,则不进行重新赋值,而是采用现有的值
model[v.field] = hasField ? model[v.field] : v.value !== void 0 ? v.value : ''

View File

@ -7,12 +7,20 @@ import { useConfigGlobal } from '@/hooks/web/useConfigGlobal'
import { zxcvbn } from '@zxcvbn-ts/core'
import type { ZxcvbnResult } from '@zxcvbn-ts/core'
defineProps({
const props = defineProps({
//
strength: propTypes.bool.def(false),
modelValue: propTypes.string.def('')
})
watch(
() => props.modelValue,
(val: string) => {
if (val === unref(valueRef)) return
valueRef.value = val
}
)
const { configGlobal } = useConfigGlobal()
const emit = defineEmits(['update:modelValue'])
@ -30,7 +38,7 @@ function changeTextType() {
}
//
const valueRef = ref('')
const valueRef = ref(props.modelValue)
//
watch(

86
src/hooks/web/useForm.ts Normal file
View File

@ -0,0 +1,86 @@
import type { Form, FormExpose } from '@/components/Form'
import type { ElForm } from 'element-plus'
import { ref, unref, nextTick } from 'vue'
export function useForm() {
// From实例
const formRef = ref<typeof Form & FormExpose>()
// ElForm实例
const elFormRef = ref<ComponentRef<typeof ElForm>>()
/**
* @param ref Form实例
* @param elRef ElForm实例
*/
function register(ref: typeof Form & FormExpose, elRef: ComponentRef<typeof ElForm>) {
formRef.value = ref
elFormRef.value = elRef
}
async function getForm() {
const form = unref(formRef)
if (!form) {
console.error('The form is not registered. Please use the register method to register')
}
await nextTick()
return form
}
// 一些内置的方法
const methods: {
setValues: (data: FormSetValuesType[]) => void
getFormData: () => Promise<Recordable | undefined>
setSchema: (schemaProps: FormSetValuesType[]) => void
addSchema: (formSchema: FormSchema, index?: number) => void
delSchema: (index: number) => void
} = {
/**
* @param field
* @param value
*/
setValues: async (data: FormSetValuesType[]) => {
const form = await getForm()
form?.setValues(data)
},
/**
* @param schemaProps schemaProps
*/
setSchema: async (schemaProps: FormSetPropsType[]) => {
const form = await getForm()
form?.setSchema(schemaProps)
},
/**
* @param formSchema
* @param index
*/
addSchema: async (formSchema: FormSchema, index?: number) => {
const form = await getForm()
form?.addSchema(formSchema, index)
},
/**
* @param index
*/
delSchema: async (index: number) => {
const form = await getForm()
form?.delSchema(index)
},
/**
* @returns form data
*/
getFormData: async (): Promise<Recordable | undefined> => {
const form = await getForm()
return form?.formModel || undefined
}
}
return {
register,
elFormRef,
methods
}
}

View File

@ -0,0 +1,3 @@
declare interface ConfigGlobalTypes {
size?: ElememtPlusSzie
}

View File

@ -1,7 +1,6 @@
import type { CSSProperties } from 'vue'
declare global {
// Form types start
declare type ComponentName =
| 'Radio'
| 'RadioButton'
@ -24,7 +23,7 @@ declare global {
| 'SelectV2'
| 'InputPassword'
type ColProps = {
declare type ColProps = {
span?: number
xs?: number
sm?: number
@ -34,15 +33,7 @@ declare global {
tag?: string
}
declare type FormValueTypes = string | number | string[] | number[] | boolean | undefined | null
// declare interface FormItemRule extends RuleItem {
// trigger?: string
// }
// declare type FormRulesMap<T extends string = string> = Partial<
// Record<T, FormItemRule | FormItemRule[]>
// >
declare type FormValueType = string | number | string[] | number[] | boolean | undefined | null
declare type FormItemProps = {
labelWidth?: string | number
@ -56,7 +47,7 @@ declare global {
declare type ComponentOptions = {
label?: string
value?: FormValueTypes
value?: FormValueType
disabled?: boolean
key?: string | number
children?: ComponentOptions[]
@ -88,36 +79,19 @@ declare global {
// 渲染的组件
component?: ComponentName
// 初始值
value?: FormValueTypes
value?: FormValueType
// 是否隐藏
hidden?: boolean
}
// Form types end
// ConfigGlobal types start
declare interface ConfigGlobalTypes {
size?: ElememtPlusSzie
}
// ConfigGlobal types end
// Icon type start
declare interface IconTypes {
size?: number
color?: string
icon: string
}
// Icon type end
// LocaleDropdown type start
declare interface Language {
el: Recordable
name: string
declare type FormSetValuesType = {
field: string
value: FormValueType
}
declare interface LocaleDropdownType {
lang: LocaleType
name?: string
elLocale?: Language
declare type FormSetPropsType = {
field: string
path: string
value: any
}
// LocaleDropdown type end
}

5
src/types/componentType/icon.d.ts vendored Normal file
View File

@ -0,0 +1,5 @@
declare interface IconTypes {
size?: number
color?: string
icon: string
}

View File

@ -0,0 +1,10 @@
declare interface Language {
el: Recordable
name: string
}
declare interface LocaleDropdownType {
lang: LocaleType
name?: string
elLocale?: Language
}

View File

@ -1,9 +1,10 @@
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { reactive, ref, unref } from 'vue'
import { Form } from '@/components/Form'
import { useI18n } from '@/hooks/web/useI18n'
import { ElButton, ElCheckbox, ElLink } from 'element-plus'
import { required } from '@/utils/formRules'
import { useForm } from '@/hooks/web/useForm'
const { t } = useI18n()
@ -22,6 +23,7 @@ const schema = reactive<FormSchema[]>([
{
field: 'username',
label: t('login.username'),
value: 'admin',
component: 'Input',
colProps: {
span: 24
@ -30,6 +32,7 @@ const schema = reactive<FormSchema[]>([
{
field: 'password',
label: t('login.password'),
value: 'admin',
component: 'InputPassword',
colProps: {
span: 24
@ -71,10 +74,34 @@ const schema = reactive<FormSchema[]>([
const iconSize = 30
const remember = ref(false)
const { register, elFormRef, methods } = useForm()
const loading = ref(false)
//
async function signIn() {
const formRef = unref(elFormRef)
const validate = await formRef?.validate()?.catch(() => {})
if (validate) {
loading.value = true
const { getFormData } = methods
const formData = await getFormData()
console.log(formData)
loading.value = false
}
}
</script>
<template>
<Form :schema="schema" :rules="rules" label-position="top" hide-required-asterisk size="large">
<Form
:schema="schema"
:rules="rules"
label-position="top"
hide-required-asterisk
size="large"
@register="register"
>
<template #title>
<h2 class="text-2xl font-bold text-center w-[100%]">{{ t('login.login') }}</h2>
</template>
@ -87,7 +114,7 @@ const remember = ref(false)
</template>
<template #login>
<ElButton type="primary" class="w-[100%]">{{ t('login.login') }}</ElButton>
<ElButton type="primary" class="w-[100%]" @click="signIn">{{ t('login.login') }}</ElButton>
</template>
<template #otherIcon>

View File

@ -9,6 +9,7 @@ import VueI18n from '@intlify/vite-plugin-vue-i18n'
import StyleImport, { ElementPlusResolve } from 'vite-plugin-style-import'
import ViteSvgIcons from 'vite-plugin-svg-icons'
import PurgeIcons from 'vite-plugin-purge-icons'
import { viteMockServe } from 'vite-plugin-mock'
// https://vitejs.dev/config/
const root = process.cwd()
@ -22,8 +23,7 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
let env = null
if (command === 'serve') {
env = loadEnv(process.argv[3], root)
}
else {
} else {
env = loadEnv(mode, root)
}
return {
@ -56,7 +56,18 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
symbolId: 'icon-[dir]-[name]',
svgoOptions: true
}),
PurgeIcons()
PurgeIcons(),
viteMockServe({
ignore: /^\_/,
mockPath: 'mock',
localEnabled: !(command === 'serve'),
prodEnabled: command !== 'serve',
injectCode: `
import { setupProdMockServer } from '../mock/_createProductionServer'
setupProdMockServer()
`
})
],
css: {