144 lines
3.7 KiB
Markdown
144 lines
3.7 KiB
Markdown
# 9.10 数据录入组件
|
||
|
||
:::tip 概述
|
||
本节介绍前端项目中常用的数据录入组件,包括表单(BasicForm)、弹窗表单和上传组件的使用方法。
|
||
:::
|
||
|
||
## Form 表单组件
|
||
|
||
```vue
|
||
<template>
|
||
<BasicForm @register="registerForm" />
|
||
</template>
|
||
|
||
<script setup>
|
||
import { BasicForm, useForm } from '@/components/Form';
|
||
|
||
const [registerForm] = useForm({
|
||
schemas: [
|
||
{
|
||
field: 'name',
|
||
label: '名称',
|
||
component: 'NInput',
|
||
required: true,
|
||
},
|
||
{
|
||
field: 'status',
|
||
label: '状态',
|
||
component: 'NSelect',
|
||
componentProps: {
|
||
options: [
|
||
{ label: '在用', value: 1 },
|
||
{ label: '停用', value: 2 },
|
||
],
|
||
},
|
||
},
|
||
],
|
||
});
|
||
</script>
|
||
```
|
||
|
||
:::tip 前端校验与后端 FormRequest 的关系
|
||
`schemas` 的 `required`/校验规则是**体验层**(即时提示);后端 `Http/Requests/*.php` 的 `rules()` 才是**最终防线**。两边规则应保持一致(如 max 长度、in 枚举值),以后端为准。
|
||
:::
|
||
|
||
## Modal 弹窗组件
|
||
|
||
```vue
|
||
<template>
|
||
<basicModal @register="registerModal" @on-ok="handleSubmit" @on-close="closeModal" />
|
||
</template>
|
||
|
||
<script setup>
|
||
import { basicModal, useModal } from '@/components/Modal';
|
||
|
||
// useModal 传入弹窗配置,返回 [register, { openModal, closeModal, setSubLoading }]
|
||
const [registerModal, { openModal, closeModal }] = useModal({
|
||
title: '新增案例演示',
|
||
subBtuText: '确定',
|
||
width: 600,
|
||
});
|
||
|
||
// 打开弹窗
|
||
const handleAdd = () => {
|
||
openModal();
|
||
};
|
||
|
||
// 提交(on-ok 事件触发;getFieldsValue 来自 useForm 返回的 [register, { getFieldsValue }])
|
||
const handleSubmit = async () => {
|
||
const values = getFieldsValue();
|
||
await exampleAdd(values);
|
||
closeModal();
|
||
};
|
||
</script>
|
||
```
|
||
|
||
## Upload 上传组件
|
||
|
||
图片字段使用 `UploadImg`(生成页面 `edit.vue` 的实际写法,`v-model:image-url` 绑定相对路径):
|
||
|
||
```vue
|
||
<template>
|
||
<UploadImg
|
||
v-model:image-url="formData.avatar"
|
||
@changeFileName="(name) => (formData.avatarImgName = name)"
|
||
name="tool"
|
||
:fileSize="20"
|
||
:fileType="['image/jpeg', 'image/png', 'image/jpg', 'image/gif', 'image/webp']"
|
||
/>
|
||
</template>
|
||
|
||
<script setup>
|
||
import UploadImg from '@/components/Upload/Image.vue';
|
||
// 上传接口:POST /api/upload/uploadFile(需认证 + sys:upload:file 权限)
|
||
</script>
|
||
```
|
||
|
||
多文件场景可用 `BasicUpload`(`:value` 传路径数组,`@uploadChange` 回传更新后的数组,见 [G. 前端组件速查](/zh/appendix/components.html))。
|
||
|
||
:::tip 上传字段值
|
||
绑定值建议存 `filePath`(相对路径),Service 的 `fileFields` 归一化入库、读取时自动补全域名。详见 [7.1 文件上传全流程](/zh/tools/upload.html)。
|
||
:::
|
||
|
||
## Editor 富文本编辑器
|
||
|
||
```vue
|
||
<template>
|
||
<Editor v-model="formData.content" />
|
||
</template>
|
||
|
||
<script setup>
|
||
import Editor from '@/components/Editor/index.vue';
|
||
</script>
|
||
```
|
||
|
||
(后端需在 Service 配置 `contentFields` 启用 `[IMG_URL]` 占位处理,见 [7.3 富文本处理](/zh/tools/rich-text.html)。)
|
||
|
||
## Password 密码强度组件
|
||
|
||
```vue
|
||
<template>
|
||
<Password v-model="formData.password" />
|
||
</template>
|
||
|
||
<script setup>
|
||
import { Password } from '@/components/Password';
|
||
</script>
|
||
```
|
||
|
||
(后端密码策略为 bcrypt 双重加盐,`BCRYPT_ROUNDS=12`,见 [5.6 密码加密服务](/zh/core/password.html)。)
|
||
|
||
## ChinaArea 行政区划组件
|
||
|
||
```vue
|
||
<template>
|
||
<ChinaArea v-model="formData.city" />
|
||
</template>
|
||
|
||
<script setup>
|
||
import ChinaArea from '@/components/ChinaArea/index.vue';
|
||
</script>
|
||
```
|
||
|
||
(数据来自后端 `/api/city/*` 级联接口,`city` 值为四层数组 `[省,市,区,街道]`,见 [6.9 行政区划管理](/zh/modules/city.html)。)
|