大家好,我是aehyok🎋,一个住在深圳城市的佛系码农🧚🏻♀️,如果你喜欢我的文章📚,可以通过点赞帮我聚集灵力⭐️。
个人github仓库地址: https:github.com/aehyok
本文讲解代码仓库地址 : https:github.com/aehyok/vue-… 目前基于dev分支进行开发和测试
本demo已部署腾讯云 vue.tuokecat.com(服务器配置较低,如有访问比较慢,请耐心等待)
table封装路径为根路径下的 vue-qiankun/common/components/form/
form表单json配置生成器
- 1、 在PC端日常的使用中,使用最多的莫过于表单和列表了,故此对table列表和form表单进行了统一的封装,通过json配置就可以快速适配table列表和form表单。
- 2、本章节主要记录自己的form表单封装
- 3、封装思路
- A、根据布局,一行一列默认可不设置(columnSpan设置为24),一行两列可设置参数columnSpan设置为12,后续以此类推
- B、根据不同的字段类型,分别对应子组件进行渲染
- C、子组件根据不同的类型,以及配置的类型字段进行渲染和数据绑定
- D、子组件可以设置必填项和rules表单验证规则
- E、可以通过设置字段的值,去控制其他字段的展示和隐藏
- F、下拉等字典类型数据,可统一设置读取接口数据,也可以根据需要进行传递当前数组数据
- G、图片上传可设置上传接口,并可设置上传多张图片
- H、富文本编辑器也可以作为组件嵌入表单
- I、 ......
先来一个完整的效果展示
- 1、form表单配置json
{ "formListItem": [ { "name": "name1", "type": "text", "title": "栏目标题", "required": true }, { "name": "name", "type": "text", "title": "栏目名称" }, { "name": "total", "type": "number", "title": "栏目数量", "required": true }, { "name": "count", "type": "number", "title": "浏览数量" }, { "name": "descript", "type": "textarea", "title": "备注", "required": true, "rows": 3 }, { "name": "content", "type": "textarea", "title": "内容", "rows": 3 }, { "name": "startDate", "type": "date", "title": "开始日期", "required": true }, { "name": "endDate", "type": "date", "title": "结束日期" }, { "name": "isValid", "type": "switch", "title": "是否有效" }, { "name": "isExpired", "type": "switch", "title": "是否过期", "required": true }, { "name": "type", "type": "radio", "dictionary": [ { "code": 1, "name": "横版栏目" }, { "code": 2, "name": "竖版栏目" } ], "title": "栏目类型", "controls": [ { "value": 1, "showCondition": [ { "name": "show", "type": "radio", "dictionary": [ { "code": 1, "name": "China" }, { "code": 2, "name": "English" } ], "title": "测试类型", "required": true }, { "name": "image1", "type": "ImageTypeView", "title": "文件" } ] }, { "value": 2, "showCondition": [ { "name": "isValids", "type": "switch", "title": "是否有效" } ] } ] }, { "name": "requireType", "type": "radio", "dictionary": [ { "code": 1, "name": "类型一" }, { "code": 2, "name": "类型二" } ], "title": "图文类型", "required": true }, { "name": "range", "type": "checkbox", "title": "发布范围", "dictionary": [ { "code": 1, "name": "范围一" }, { "code": 2, "name": "范围二" } ], "required": true }, { "name": "dateRange", "type": "daterange", "title": "日期范围" }, { "name": "creType", "type": "select", "dictionary": [ { "code": 1, "name": "身份证" }, { "code": 2, "name": "居住证" } ], "title": "证件类型" }, { "name": "image", "type": "image", "title": "头像" } ], "formData": { "name": "主菜单栏目", "total": null, "count": null, "createDate": 1606730360386, "type": 1, "creType": "", "range": [], "isExpired": false, "isValid": true } }
- 2、 最后的效果图片
效果展示的在线预览页面为 vue.tuokecat.com/#/webpack-a…
具体代码可根据路由进行搜索
字段配置详细介绍
1、静态文本 static
```javascript { type: "static", // 字段类型只读文本 name: "name", //与后台对接字段 title: "名称", // 前端展示字段 }, ```
2、文本框 text
```javascript { type: "text", // 字段类型文本框 name: "name", //与后台对接字段 title: "域名", // 前端展示字段 required: true, // 必填项设置 maxlength: 50, // 字符串长度限制 showwordlimit: true, // 是否显示字符串长度 placeholder:"请输入10个字符以内的名称", // 占位文本提示 append: ".com", // 文本框后置内容 // rules // 数组 rules: [ { pattern: /(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/, message: '请输入数字最多两位小数' } ], }, ```
3、文本域 textarea
```javascript { type: "textarea", // 字段类型文本域 name: "name", //与后台对接字段 title: "备注", // 前端展示字段 required: true, // 必填项设置 placeholder:"请输入10个字符以内的名称", // 占位文本提示 rows: 4, // 输入框行数 minlength: 100, // 最小输入长度 maxlength: 5000, // 最大输入长度 showwordlimit: true, // 是否显示字符串长度 // rules // 数组 rules: [ { pattern: /(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/, message: '请输入数字最多两位小数' } ], }, ```
4、下拉框 select
```javascript { type: "select", // 字段类型下拉框 name: "options", //与后台对接字段 title: "类型", // 前端展示字段 required: true, // 必填项设置 placeholder:"请选择类型", // 占位文本提示 // dictionary 可直接传递下拉数据,也可以传递字典中的typeCode,通过内部接口获取 dictionary: 7010, // 7010为字典中维护的typecode dictionary:[ { code: 1, name:"图片", }, { code: 2, name:"视频" } ], multiple: true, // 下拉列表可以多选 // rules // 正则匹配 rules: [ { pattern: /(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/, message: '只能选择*******' } ], // 点击下来触发切换联动的事件,为一个函数 changeFunction: function(){} }, ```
5、富文本 editor
```javascript { type: "editor", // 字段类型富文本 name: "content", //与后台对接字段 title: "内容", // 前端展示字段 required: true, // 必填项设置 placeholder:"请选择类型", // 占位文本提示 // rules // 正则匹配 rules: [ { pattern: /(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/, message: '只能选择*******' } ], maxLength:5000, // 富文本框最大长度,默认5000 }, ```
6、数值框 number
```javascript { type: "number", // 字段类型数值 name: "num", //与后台对接字段 title: "总数", // 前端展示字段 required: true, // 必填项设置 placeholder:"请输入10个字符以内的名称", // 占位文本提示 precision: 2, // 小数点后的位数 // rules // 数组 rules: [ { pattern: /(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/, message: '请输入数字最多两位小数' } ], }, ```
7、省市区三级级联选择 citySelect
```javascript { type: "citySelect", // 字段类型省市区 name: "region", //与后台对接字段 title: "户籍地", // 前端展示字段 required: true, // 必填项设置 placeholder:"请输入10个字符以内的名称", // 占位文本提示 // rules // 数组 rules: [ { pattern: /(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/, message: '请输入数字最多两位小数' } ], }, ```
8、 图片上传 image
```javascript { type: "image", // 字段类型图片 name: "images", //与后台对接字段 title: "上传图片", // 前端展示字段 required: true, // 必填项设置 placeholder:"请上传图片", // 占位文本提示 // rules // 数组 rules: [ { pattern: /(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/, message: '请输入数字最多两位小数' } ], }, ```
9、 视频上传 video
```javascript { type: "video", // 字段类型视频 name: "images", //与后台对接字段 title: "上传视频", // 前端展示字段 required: true, // 必填项设置 placeholder:"请上传视频", // 占位文本提示 // rules // 数组 rules: [ { pattern: /(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/, message: '请输入数字最多两位小数' } ], }, ```
10、 日期 date
```javascript { type: "date", // 字段类型日期 name: "date", //与后台对接字段 title: "日期", // 前端展示字段 required: true, // 必填项设置 placeholder:"请选择日期", // 占位文本提示 // rules // 数组 rules: [ { pattern: /(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/, message: '请输入数字最多两位小数' } ], }, ```
11、 日期范围 daterange
```javascript { type: "daterange", // 字段类型日期 name: "date", //与后台对接字段 title: "日期范围", // 前端展示字段 required: true, // 必填项设置 placeholder:"请选择日期", // 占位文本提示 // rules // 数组 rules: [ { pattern: /(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/, message: '请输入数字最多两位小数' } ], }, ```
附上整个调用的所有代码
- 1、template 模板代码
<template> <div> <sl-table :list="list" @handleSelectionChange="handleSelectionChange" :columns="columns" :operates="operates" v-model:pageModel="pageModel" @search="search" > </sl-table> </div> </template>
- 2、'script'标签代码
import SlTable from '../../../common/components/table/index.vue' import { defineComponent, reactive, toRefs } from "vue"; import { list_test, columns_test } from "./tableConfig"; export default defineComponent({ components: { SlTable }, setup() { // 选中行 const handleSelectionChange = (val) => { console.log("handleSelectionChange-val:", val); }; // 编辑 const handleDetail = (index, row, idx) => { console.log("index:", index, idx); console.log("row:", row); }; // 删除 const handleDel = (index, row) => { console.log(" index:", index); console.log(" row:", row); }; const state = reactive({ pageModel: { page: 1, limit: 10, total: 17 }, list: [], // table数据 columns: [], // 需要展示的列 operates: { width: 200, fixed: "right", list: [ { id: "1", label: "查看", type: "text", show: true, disabled: false, method: (index, row, ss) => { handleDetail(index, row, ss); } }, { id: "2", label: "删除", type: "text", show: true, disabled: false, method: (index, row) => { handleDel(index, row); } } ] } // 列操作按钮 }); state.list = list_test; state.columns = columns_test; const search = () => { state.list = [...state.list]; console.log(state.pageModel, "state.pageModel"); }; return { ...toRefs(state), handleSelectionChange, search }; } });
- 3、其中模拟数据和字段配置在单独的文件中tableConfig
const list_test = [ { id: "24", title: "编号3", state: 0, createTime:"2021-09-23T17:57:09", remark: "自定义" }, { id: "23", title: "编号4", state: 1, createTime:"2021-09-23T17:57:19", remark: "自定义" }, { id: "23", title: "编号5", state: 2, createTime:"2021-09-23T17:57:29", remark: "自定义" }, { id: "23", title: "编号5", state: 1, createTime:"2021-09-23T17:57:39", remark: "自定义111" }, { id: "223", title: "编号3", state: 1, createTime:"2021-09-23T17:57:49", remark: "22222" }, { id: "2444", title: "编号3", state: 0, createTime:"2021-09-23T17:57:59", remark: "333333" }, { id: "24", title: "编号3", state: 0, createTime:"2021-09-23T17:57:09", remark: "自定义" }, { id: "23", title: "编号4", state: 1, createTime:"2021-09-23T17:57:19", remark: "自定义" }, { id: "23", title: "编号5", state: 2, createTime:"2021-09-23T17:57:29", remark: "自定义" }, { id: "23", title: "编号5", state: 1, createTime:"2021-09-23T17:57:39", remark: "自定义111" }, { id: "223", title: "编号3", state: 1, createTime:"2021-09-23T17:57:49", remark: "22222" }, { id: "2444", title: "编号3", state: 0, createTime:"2021-09-23T17:57:59", remark: "333333" } ] const columns_test = [ { type:'checkbox', }, { prop: "id", label: "编号", type:'index', align: "center" }, { prop: "title", label: "标题", align: "center", }, { prop: "createTime", label: "创建时间", align: "center", dateFormat: "yyyy-MM-dd HH:mm:ss", sortable: true }, { prop: "state", label: "状态", align: "center", dictionary: [ { code: 0, name: "待审核"}, { code: 1, name: "已审核"}, { code: 2, name: "审核中"}, ] }, { prop:"custom", label:"自定义", align: "center", html: (row, column) => { return row.title==="编号3" ? `<span style="color: red;">${ row.remark }</span>`:`未定义` } } ] export { list_test, columns_test }
最后的最后
github.com/aehyok/vue-…本文中不涉及到代码,有关代码问题可以访问文章开头的微前端github demo 仓库,github仓库将会保持持续更新,不断优化小demo。
github.com/aehyok/2021最后自己每天工作中的笔记记录仓库,主要以文章链接和问题处理方案为主。