init.json指南
12003快速开始
jianghu-init JSON以JSON格式高效地管理页面结构和API接口,从而优化开发流程和提升工作效率。本指南主要介绍jianghu-init JSON的详细教程。
安装
在开始之前,请确保您已经安装了jianghu-init工具。可以通过以下命令进行安装:
npm uninstall -g @jianghujs/jianghu-init# 最新版本 3.2.5npm install -g @jianghujs/jianghu-init@latest
👉 jianghu-init 工具安装详解👈
在江湖项目中生成参考示例
- 首先,进入已有的江湖JS项目目录
👉 创建jianghujs项目 👈
- 使用以下命令生成参考示例:
cd my-jh-projectjianghu-init json --generateType=example
执行以上命令,当前项目数据库将添加 example_class 和 example_student 数据表、并在项目目录生成以下文件:
- app\view\init-json\component\exampleStudentOfClass.js
- app\view\init-json\page\exampleClass.js
- app\view\component\example\exampleStudentOfClass.html
- app\view\page\exampleClass.html
方便参考使用
步骤一:数据表生成配置文件
当有一个新的业务数据表之后,可以使用以下命令生成数据表的配置文件,例如,现在有一个名为class的数据表:
CREATE TABLE `class` (`id` int(11) NOT NULL AUTO_INCREMENT,`classId` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '班级ID',`className` varchar(255) DEFAULT NULL,`operation` varchar(255) COLLATE utf8mb4_bin DEFAULT 'insert' COMMENT '操作; insert, update, jhInsert, jhUpdate, jhDelete jhRestore',`operationByUserId` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '操作者userId',`operationByUser` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '操作者用户名',`operationAt` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '操作时间; E.g: 2021-05-28T10:24:54+08:00 ',PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
要为class数据表生成基础配置文件,可以使用以下命令:
jianghu-init json --generateType=json --pageType=jh-page --table=class --pageId=classManagement
执行命令之后,会在项目的app/view/init-json/page/目录下生成一个名为classManagement.js的配置文件。
步骤二:配置文件生成页面
上一步生成的配置文件,需要通过以下命令生成页面:
jianghu-init json --generateType=page --pageType=page --file=classManagement
执行以上命令,将会生成项目的app/view/page/目录下生成一个名为classManagement.html的页面文件,并自动配置页面对应的数据库表_page和_resouce的数据。
👉 开启dev模式,修改配置文件自动更新页面 👈
👉 配置字符串代码语法高亮 👈
配置协议
结构总览
{pageType: "jh-page", // 页面类型,可选值为jh-page、jh-mobile-page、jh-component选pageId: "pageId", // 页面唯一标识pageName: "班级页面", // 页面标题template: "jhTemplateV4", // 页面模板,默认为jhTemplateV4,手机端一般设置为jhMobileTemplateV4version: 'v3', // 版本 空 或者 v2resourceList: [],// 页面resource { actionId, resourceType, resourceData }headContent: [], // 页面头部,常用于配置 标题、面包屑条、服务端搜索、场景搜索等pageContent: [], // 页面内容区域actionContent: [], // 触发内容集合,一般会放新增、修改等弹框includeList: [], // 页面引入资源 { type, path }common: { // vue 原生变量 + uiAction {data, props, watch, methods, computed}data: {},computed: {},watch: {},methods: {},doUiAction: {}, // 自定义uiAction { [key]: [method1, method2, doUiAction1]}},style: '', // 自定义样式}
| 属性 | 类型 | 必填 | 描述 |
|---|---|---|---|
| pageType | string | ✅ | 页面类型,可选值为jh-page、jh-mobile-page、jh-component、 |
| pageId | string | ✅ | 页面唯一标识 |
| template | string | 否 | 模版 |
| version | string | 否 | 版本 (目前支持设定v2、v3) |
| resourceList | array | 否 | |
| headContent | array | ✅ | 面包屑 |
| pageContent | array | ✅ | 页面主体内容 |
| actionContent | array | ✅ | 触发内容(抽屉、弹窗、遮罩层等) |
| includeList | array | ✅ | 页面引入资源 { type, path } |
| common | object | ✅ | 变量、方法 |
| style | string | 否 | 、 |
HTML标签
在 headContent、pageCotent、actionContent 中,可以使用使用指定的对象结构来配置一个标签,也支持直接使用HTML字符串。
对象结构
pageContent: [{tag: 'v-row',attrs: {align: "center""@click": "doUiAction('updateItem')"},quickAttrs: ['no-gutters'],value: [{ tag: 'v-col', attrs: { cols: 12 }, value: '' },/*html*/`<v-col cols="12"></v-col>`]}]
| 属性 | 类型 | 必填 | 描述 |
|---|---|---|---|
| tag | string | 否 | 标签名称 |
| attr | object | ✅ | 标签属性,如class、@click等 |
| quickAttrs | array | 否 | 标签简洁属性,如 v-else small disabled等 |
| value | object | 否 | 标签内的HTML内容 |
HTML字符串
pageContent: [`<v-row align="center"><v-col cols="12"></v-col></v-row>`]
接口配置
配置江湖resource,定义的resouce将自动更新到数据库中,供前端调用。
resourceList: [{resourceHook: { "before": [], "after": [] }, // 无需设置时可省略actionId: 'balance-updateItem',desc: '修改班费余额',resourceType: 'sql',resourceData: { "table": "class", "operation": "update" }}]
👉 resouce详细配置文档 👈
资源引入
当页面需要引入组件、样式、脚本等资源时,可以通过includeList配置。支持对象结构和HTML字符串。
includeList: [{ type: 'css', path: "/<$ ctx.app.config.appId $>/public/lib/echarts.min.css" },{ type: 'script', path: "/<$ ctx.app.config.appId $>/public/lib/echarts.min.js" },{ type: 'html', path: "component/exampleChart/lineChart.html" },{ type: 'html', path: 'component/courseBatchDrawer.html', includeType: 'auto', attrs: { id: 'courseBatchDrawer' } },{ type: 'vueComponent', name: 'v-chart', component: 'VueCharts' },`<script src="/<$ ctx.app.config.appId $>/public/lib/echarts.min.js"></script>`]
| 属性 | 类型 | 必填 | 描述 |
|---|---|---|---|
| type | string | ✅ | 引入类型,可选 css、js、html、vueComponent |
| path | string | 否 | 引入路径,type为css、js、html时可用 |
| includeType | string | 否 | 引入类型,可选 auto,当值为auto时将自动添加标签内容添加到页面末端。type为css、js、html时可用 |
| attrs | object | 否 | 自定引入标签属性。type为html、includeType为auto时可用 |
| name | string | 否 | 组件名,type为vueComponent时可用 |
| component | string | 否 | 引入组件,type为vueComponent时可用 |
配置doUiAction
提供补充doUiAction方法的配置入口
pageContent: [{tag: 'v-btn',value: '测试doUiAction1',attrs: { '@click': 'doUiAction("doSomething")' },quickAttrs: ['small']},`<v-btn @click="doUiAction('doSomething')">测试doUiAction2</v-btn>`],common: {doUiAction: {startUpdataBalance: ['async.method1', 'method2'],doSomething: ['method3(123)', 'doUiAction.startUpdataBalance']},methods: {async method1 (id) {console.log('method1', id)},async method2 () {console.log('method2')},async method3(actionData) {console.log('method3')}}}
- 默认方法链使用 await 同步执行,可添加 async. 进行异步修饰 例:
doUiAction: {startUpdataBalance: ['async.method1', 'method2'],},// 实际执行case 'startUpdataBalance':this.method1(uiActionData);await this.method2(uiActionData);break;
- 默认方法链使用方法执行,可添加 doUiAction. 进行包含流程 例:
doUiAction: {doSomething: ['method3(123)', 'doUiAction.startUpdataBalance'],doSomething2: ['method3(123)', 'async.doUiAction.startUpdataBalance']},// 实际执行case 'doSomething':await this.method3(123, uiActionData);await this.doUiAction('startUpdataBalance', uiActionData);break;case 'doSomething2':await this.method3(123, uiActionData);this.doUiAction('startUpdataBalance', uiActionData);break;
调用链中支持配置方法名、方法名+参数、doUiAction方法名。
配置示例-PC端
基础页面
const content = {pageType: "jh-page", pageId: "classManagement", pageName: "classManagement页面", template: 'jhTemplateV4', version: 'v3',resourceList: [{actionId: "selectItemList",resourceType: "sql",desc: "✅查询列表-classManagement",resourceData: { table: "class", operation: "select" }},// ... insertItem/updateItem/deleteItem], // { actionId: '', resourceType: '', resourceData: {}, resourceHook: {}, desc: '' }headContent: [{ tag: 'jh-page-title', value: "classManagement", attrs: { cols: 12, sm: 6, md:4 }, helpBtn: true, slot: [] },{ tag: 'v-spacer' },{tag: 'jh-search',attrs: { cols: 12, sm: 6, md:8 },searchBtn: true,value: [{ tag: "v-text-field", model: "serverSearchWhereLike.className", attrs: {prefix: '前缀'} },],// v3 版本新增特性data: {serverSearchWhereLike: { name: '' },serverSearchWhere: { semester: '', segment: '小学' },}}],pageContent: [{tag: 'jh-table',attrs: { },colAttrs: { clos: 12 },cardAttrs: { class: 'rounded-lg elevation-0' },headActionList: [{ tag: 'v-btn', value: '新增', attrs: { color: 'success', class: 'mr-2', '@click': 'doUiAction("startCreateItem")', small: true } },{ tag: 'v-spacer' },// 默认筛选{tag: 'v-col',attrs: { cols: '12', sm: '6', md: '3', xs: 8, class: 'pa-0' },value: [{ tag: 'v-text-field', attrs: {prefix: '筛选', 'v-model': 'searchInput', class: 'jh-v-input', ':dense': true, ':filled': true, ':single-line': true} },],}],headers: [{ text: "id", value: "id", width: 80, sortable: true, class: "fixed", cellClass: "fixed" },{ text: "班级ID", value: "classId", width: 80, sortable: true },{ text: "className", value: "className", width: 80, sortable: true },{ text: "操作", value: "operation", width: 80, sortable: true },{ text: "操作者userId", value: "operationByUserId", width: 80, sortable: true },{ text: "操作者用户名", value: "operationByUser", width: 80, sortable: true },{ text: "操作时间", value: "operationAt", width: 80, sortable: true },{ text: "操作", value: "action", type: "action", width: 'window.innerWidth < 500 ? 70 : 120', align: "center", class: "fixed", cellClass: "fixed" },// width 表达式需要使用字符串包裹],value: [// vuetify table custom slot],rowActionList: [{ text: '编辑', icon: 'mdi-note-edit-outline', color: 'success', click: 'doUiAction("startUpdateItem", item)' }, // 简写支持 pc 和 移动端折叠{ text: '删除', icon: 'mdi-trash-can-outline', color: 'error', click: 'doUiAction("deleteItem", item)' } // 简写支持 pc 和 移动端折叠],}],actionContent: [{tag: 'jh-create-drawer',key: "create",attrs: {},title: '新增',headSlot: [{ tag: 'v-spacer'}],contentList: [{label: "新增",type: "form",formItemList: [{ label: "id", model: "id", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "班级ID", model: "classId", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "className", model: "className", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作", model: "operation", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作者userId", model: "operationByUserId", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作者用户名", model: "operationByUser", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作时间", model: "operationAt", tag: "v-text-field", rules: "validationRules.requireRules", },],action: [{tag: "v-btn",value: "新增",attrs: {color: "success",':small': true,'@click': "doUiAction('createItem')"}}],},]},{tag: 'jh-update-drawer',key: "update",attrs: {},title: '编辑',headSlot: [{ tag: 'v-spacer'}],contentList: [{label: "编辑",type: "form",formItemList: [{ label: "id", model: "id", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "班级ID", model: "classId", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "className", model: "className", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作", model: "operation", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作者userId", model: "operationByUserId", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作者用户名", model: "operationByUser", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作时间", model: "operationAt", tag: "v-text-field", rules: "validationRules.requireRules", },],action: [{tag: "v-btn",value: "编辑",attrs: {color: "success",':small': true,'@click': "doUiAction('updateItem')"}}],},{ label: "操作记录", type: "component", componentPath: "recordHistory", attrs: { table: 'class', pageId: 'classManagement', ':id': 'updateItem.id' } },]},],includeList: [], // { type: < js | css | html | vueComponent >, path: ''}common: {data: {constantObj: {},validationRules: {requireRules: [v => !!v || '必填',],},serverSearchWhereLike: { className: '' }, // 服务端like查询serverSearchWhere: { }, // 服务端查询serverSearchWhereIn: { }, // 服务端 in 查询filterMap: {}, // 结果筛选条件},dataExpression: {isMobile: 'window.innerWidth < 500'}, // data 表达式watch: {},computed: {tableDataComputed() {if(this.filterMap) {return this.tableData.filter(row => {for (const key in this.filterMap) {if (this.filterMap[key] && row[key] !== this.filterMap[key]) {return false;}}return true;});} else {return this.tableData;}},},doUiAction: {}, // 额外uiAction { [key]: [action1, action2]}methods: {}},};module.exports = content;
标题-只有页面标题
headContent: [{ tag: 'jh-page-title', value: "classManagement", attrs: { cols: 12, sm: 6, md:4 }, helpBtn: true, slot: [] }]
标题-服务端搜索
headContent: [{ tag: 'jh-page-title', value: "classManagement", attrs: { cols: 12, sm: 6, md:4 }, helpBtn: true, slot: [] },{ tag: 'v-spacer' },{tag: 'jh-search',attrs: { cols: 12, sm: 6, md:8 },value: [{ tag: "v-text-field", model: "serverSearchWhereLike.className", attrs: {prefix: '前缀'} },],searchBtn: true,data: {serverSearchWhereLike: { name: '' },}}]
标题-场景搜索
headContent: [{ tag: 'jh-page-title', value: "classManagement", attrs: { cols: 12, sm: 6, md:4 }, helpBtn: true, slot: [] },{ tag: 'v-spacer' },{tag: 'jh-scene',attrs: { ':showActionBtn': false, ':mobile': false,// "class": "mr-2"},// v3 版本新增特性data: {sceneCreateForm: {},serverSceneSearchWhere: {},serverSceneSearchWhereIn: {},serverSceneSearchWhereLike: {},serverSceneSearchWhereOptions: [],serverSceneSearchWhereOrOptions: [],currentSceneId: '公开',defaultSceneList: [{ name: "全部", where: {}, whereIn: { "articlePublishStatus": ["public", "draft"] } },{ name: "公开", where: { "articlePublishStatus": "public"}, whereIn: {} },{ name: "草稿", where: { "articlePublishStatus": "draft"}, whereIn: {} },{ name: "回收站", where: { "articlePublishStatus": "deleted"}, whereIn: {} },],maxSceneDisplay: 5,}},],
内容-数据表格
pageContent: [{tag: 'jh-table',props: {serverPagination: true // 开启服务端分页、服务端分页默认 limit 50},attrs: {},colAttrs: { clos: 12 },cardAttrs: { class: 'rounded-lg elevation-0' },headActionList: [{ tag: 'v-btn', value: '新增', attrs: { color: 'success', class: 'mr-2', '@click': 'doUiAction("startCreateItem")', small: true } },{ tag: 'v-spacer' }],headers: [{ text: "id", value: "id", width: 80, sortable: true, class: "fixed", cellClass: "fixed" },{ text: "班级ID", value: "classId", width: 80, sortable: true },{ text: "className", value: "className", width: 80, sortable: true },{ text: "操作", value: "operation", width: 80, sortable: true },{ text: "操作", value: "action", type: "action", width: 'window.innerWidth < 500 ? 70 : 120', align: "center", class: "fixed", cellClass: "fixed" },],value: [// v-table插槽// { tag: 'template', attrs: {'slot': 'body', 'slot-scope': "item"}, value: "<div>测试插槽</div>" },// { tag: 'template', attrs: {'slot': 'item.className', 'slot-scope': "{item, index}"}, value: "<div>{{item.className}}</div>" },],rowActionList: [{ text: '编辑', icon: 'mdi-note-edit-outline', color: 'success', click: 'doUiAction("startUpdateItem", item)' }, // 简写支持 pc 和 移动端折叠{ text: '删除', icon: 'mdi-trash-can-outline', color: 'error', click: 'doUiAction("deleteItem", item)' } // 简写支持 pc 和 移动端折叠],}]
内容-数据表格(启用列设置)
常用
pageContent: [{tag: 'jh-table',attrs: {}, // v-data-table attrscolAttrs: {}, // v-data-table 父元素 v-col attrscardAttrs: {}, // v-data-table 父元素 v-card attrsheaders: [], // v-data-table headersvalue: [],showTableColumnSettingBtn: true,headActionList: [], // 表格上方 v-col 插槽rowActionList: [], // 表格操作列操作按钮列表}],
模式设定
pageContent: [{tag: 'jh-table',attrs: {},value: [],showTableColumnSettingBtn: true,headActionList: [],rowActionList: [],}],common: {data: {columnSettingGroup: {'01模式': ["netName","stage","followUpDate","district","memberId","followUpBy","currentResidence","openVisitationStatus","totalVisitationCount","visitorAssignInfo","operationAt","action"],'02模式': ["netName","stage","duoxingRoomName","followUpDate","tag","projectList","followUpBy","district","memberId","currentResidence","operationAt","action"],'03模式': ["netName","orgId","orgName","roleId","isDefaultOrg"],},}}
| 属性 | 类型 | 必填 | 描述 |
|---|---|---|---|
| showTableColumnSettingBtn | boolean | 否 | 是否启用列设置,默认false |
弹框-新增编辑表单
actionContent: [{tag: 'jh-create-drawer',key: "create",attrs: {},title: '新增',headSlot: [{ tag: 'v-spacer'}],contentList: [{label: "新增",type: "form",formItemList: [{ label: "id", model: "id", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "班级ID", model: "classId", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "className", model: "className", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作", model: "operation", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作者userId", model: "operationByUserId", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作者用户名", model: "operationByUser", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作时间", model: "operationAt", tag: "v-text-field", rules: "validationRules.requireRules", },],action: [{tag: "v-btn",value: "新增",attrs: {color: "success",'@click': "doUiAction('createItem')"},quickAttrs: ['small']}],},]},{tag: 'jh-update-drawer',key: "update",props: {mergeForm: true // prepareFormData 将会合并对象表单},attrs: {},title: '编辑',headSlot: [{ tag: 'v-spacer'}],contentList: [{label: "编辑",type: "form",formItemList: [{ label: "id", model: "id", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "班级ID", model: "classId", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "className", model: "className", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作", model: "operation", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作者userId", model: "operationByUserId", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作者用户名", model: "operationByUser", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作时间", model: "operationAt", tag: "v-text-field", rules: "validationRules.requireRules", },],action: [{tag: "v-btn",value: "编辑",attrs: {color: "success",'@click': "doUiAction('updateItem')"},quickAttrs: ['small']}],},{ label: "操作记录", type: "component", componentPath: "recordHistory", attrs: { table: 'class', pageId: 'classManagement', ':id': 'updateItem.id' } },]},]
弹框-详情
pageContent: [`<v-btn @click="openTestDetailDrawer">打开测试详情弹框</v-btn>`,],actionContent: [{tag: 'jh-drawer',key: "testDetail",attrs: {},title: '测试详情',contentList: [{type: "form",formItemList: [{ tag: 'span', value: '课程信息', md: 12, attrs: {class: 'title pl-2'}},{ tag: 'div', md: 12, value: [/*html*/ `<div class="grey lighten-5"><v-row class="ma-0 pa-2"><v-col cols="12" md="3" v-for="(item, index) in courseInfoItems" :key="index"><span>{{item.title}}:{{item.value}}</span></v-col></v-row></div>`]}]}]}],"common": {data: {courseInfoItems: [{ title: '课程名称', value: 'IT初级课程' }]}}
弹框-自定义弹框
pageContent: [`<v-btn @click="openTestCustomDrawer">打开测试自定义弹框</v-btn>`,],actionContent: [{tag: 'jh-drawer',key: "testCustom",attrs: {},title: '测试自定义弹框',contentList: [`自定义内容`]}]
弹框-多标签
pageContent: [`<v-btn @click="openTestMultiTabDrawer">打开测试多标签弹框</v-btn>`,],actionContent: [{tag: 'jh-drawer',key: "testMultiTab",attrs: {},title: '测试多标签',contentList: [{ label: "操作记录", type: "component", componentPath: "recordHistory" },{ label: "学生列表", type: "component", componentPath: "example/studentOfClass", bind: ['classId'] },]}]
弹框-自定义按钮
pageContent: [`<v-btn @click="viewTestCustomBtn">打开测试自定义按钮弹框</v-btn>`],actionContent: [{tag: 'jh-create-drawer',key: "testCustomBtn",attrs: {},title: '测试自定义按钮',headSlot: [{ tag: 'v-spacer' },{ tag: 'v-btn', value: '自定义按钮', attrs: { color: 'success', class: 'mr-2', '@click': 'doUiAction("123")', small: true } },],contentList: [ /* 内容列表 */ ]}]
弹框-关闭弹框检查
actionContent: [{tag: 'jh-create-drawer',key: "create",attrs: {},title: '新增',isCheckFormBeforeClose: true,onCheckFormConfirm: 'doUiAction("createItem", { notConfirmed: true })',headSlot: [{ tag: 'v-spacer'}],contentList: [{label: "新增",type: "form",formItemList: [{ label: "id", model: "id", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "班级ID", model: "classId", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "className", model: "className", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作", model: "operation", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作者userId", model: "operationByUserId", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作者用户名", model: "operationByUser", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作时间", model: "operationAt", tag: "v-text-field", rules: "validationRules.requireRules", },],action: [{tag: "v-btn",value: "新增",attrs: {color: "success",':small': true,'@click': "doUiAction('createItem')"}}],},]}]
| 属性 | 类型 | 必填 | 描述 |
|---|---|---|---|
| key | string | ✅ | form标识,如:create、update 等 |
| title | string | ✅ | 抽屉标题 |
| props.mergeForm | boolean | 否 | 是否合并提交form |
| attrs | object | 否 | v-navigation-drawer 属性 |
| isCheckFormBeforeClose | boolean | 否 | 是否打开关闭弹框检查,默认false,注意检查的表单对象与弹框的key需要保持匹配,如 表单对象:createItem,弹框key:create |
| onCheckFormConfirm | string | 否 | 保存内容方法名称 |
| contentList | array | ✅ | 抽屉内容 |
配置示例-移动端
基础页面
const content = {pageType: "jh-mobile-page", pageId: "mobile/classManagement", pageName: "classManagement页面", template: "jhMobileTemplateV4", version: 'v2',resourceList: [{actionId: "selectItemList",resourceType: "sql",desc: "✅查询列表-classManagement",resourceData: { table: "class", operation: "select" }},// ... insertItem/updateItem/deleteItem], // { actionId: '', resourceType: '', resourceData: {}, resourceHook: {}, desc: '' }headContent: [{ tag: 'jh-page-title', value: "班级管理", helpBtn: true, slot: [] },{tag: 'jh-order',// v3 新特性data: {tableDataOrder: [ { column: "createAt", order: "desc" } ],tableDataOrderList: [{ text: "报名时间↓", value: [ { column: "createAt", order: "desc" } ] },{ text: "成绩分数↓", value: [ { column: "middleSchoolExamScore", order: "desc" } ] },{ text: "更新时间↓", value: [ { column: "operationAt", order: "desc" } ] },],}},{tag: 'jh-search',searchList: [{ tag: 'v-select', model: "serverSearchWhere.semester", colAttrs: { class: 'pb-0' }, attrs: { prefix: '学期:', color: 'success', ':items': 'constantObj.semester' } },{ tag: 'v-select', model: "serverSearchWhere.segment", colAttrs: { class: 'pb-0' }, attrs: { prefix: '学部:', color: 'success', ':items': 'constantObj.segment' } },{ tag: 'v-text-field', model: "serverSearchWhereLike.name", colAttrs: { class: 'pb-0' }, attrs: { label: '学生名字:', color: 'success' }, quickAttrs: ['clearable'] },],data: {serverSearchWhere: { semester: '', segment: '小学' },serverSearchWhereLike: { name: '' },}},{ tag: 'v-spacer'},{ tag: 'jh-mode', data: { viewMode: 'simple' } },],pageContent: [{tag: 'jh-list',props: {limit: 10,rightArrowText: '',},attrs: { cols: 12, class: 'p-0 pb-7', ':style': '`height: calc(100vh - 140px); overflow-y: auto;overscroll-behavior: contain`' },headers: [{text: "学生Id", value: "studentId", width: 80, isSimpleMode: true},{text: "姓名", value: "name", width: 90, isTitle: true, slot: [`<div v-if="item.isMonitor" class="ml-1"><v-icon color="warning" small>mdi-shield-star</v-icon><span>干部</span></div>`]},{text: "性别", value: "gender", width: 60, isSimpleMode: true},{text: "学生状态", value: "studentStatus", width: 80},{text: "年级", value: "level", width: 70},{text: "入学-推荐人", value: "recommendBy", width: 100, isDetailMode: true},{text: "入学-跟进人", value: "followUpByUserName", width: 100, isDetailMode: true},{text: "跟进阶段", value: "followUpStage", width: 80},{text: "报名时间", value: "createAt", width: 150},{text: "操作者", value: "operationByUser", width: 90},{text: "操作时间", value: "operationAt", width: 150},{text: '操作', value: 'action', align: 'center', sortable: false, width: 'window.innerWidth < 500 ? 90: 180', class: 'fixed', cellClass: 'fixed'},],rowActionList: [{ text: "编辑", icon: 'mdi-note-edit-outline', color: 'success', click: 'doUiAction("startUpdateItem", item)' }],},{tag: 'jh-action',attrs: { class: 'h-16 w-16 p-2 fixed right-4 bottom-32' },actionList: [{ tag: 'v-btn', value: '新增', icon: 'mdi-plus', color: 'success', click: "doUiAction('startCreateItem')" },{ tag: 'v-btn', value: '随机分配跟进人', icon: 'mdi-plus', color: 'success', click: "doUiAction('randomFollowUp')", ':disabled': '!tableSelected.length' },]}],actionContent: [{tag: 'jh-create-drawer',key: "create",attrs: {},title: '新增',headSlot: [{ tag: 'v-spacer'}],contentList: [{label: "新增",type: "form",formItemList: [{ label: "id", model: "id", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "班级ID", model: "classId", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "className", model: "className", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作", model: "operation", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作者userId", model: "operationByUserId", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作者用户名", model: "operationByUser", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作时间", model: "operationAt", tag: "v-text-field", rules: "validationRules.requireRules", },],action: [{tag: "v-btn",value: "新增",attrs: {color: "success",':small': true,'@click': "doUiAction('createItem')"}}],},]},{tag: 'jh-update-drawer',key: "update",attrs: {},title: '编辑',headSlot: [{ tag: 'v-spacer'}],contentList: [{label: "编辑",type: "form",formItemList: [{ label: "id", model: "id", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "班级ID", model: "classId", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "className", model: "className", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作", model: "operation", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作者userId", model: "operationByUserId", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作者用户名", model: "operationByUser", tag: "v-text-field", rules: "validationRules.requireRules", },{ label: "操作时间", model: "operationAt", tag: "v-text-field", rules: "validationRules.requireRules", },],action: [{tag: "v-btn",value: "编辑",attrs: {color: "success",':small': true,'@click': "doUiAction('updateItem')"}}],},{ label: "操作记录", type: "component", componentPath: "recordHistory", attrs: { table: 'class', pageId: 'classManagement', ':id': 'updateItem.id' } },]},{tag: 'jh-detail-drawer',key: "detail",attrs: {},title: "详情",headSlot: [],card: {tag: 'div',colAttrs: { class: 'pa-0' },value: `<div class="p-3 border-b" ><div class="flex justify-between mb-2 items-center"><div><span class="font-weight-bold text-base">{{ detailItem.name }}</span></div><span :class="'text-sm '">{{ detailItem.followUpStatus }}</span></div><div class="text-gray-500 flex justify-between">意向就读学部:{{ detailItem.segment }}</div><div class="text-gray-500 flex justify-between">报名日期:{{ detailItem.createAt }}</div></div><div class="pa-0 h-2 bg-gray-100" ></div>`},contentList: [{type: 'preview',md: 12,formItemList: [{ label: "性别", tag: "span", colAttrs: { class: 'border-b pb-2 flex justify-between' }, value: "{{ detailItem.gender }}" },{ label: "身份证件号", tag: "span", colAttrs: { class: 'border-b pb-2 flex justify-between' }, value: "{{ detailItem.icNumber }}" },{ label: "家庭住址", tag: "span", colAttrs: { class: 'border-b pb-2 flex justify-between' }, value: "{{ detailItem.residentialAddress }}" },{ label: "意向就读学部", tag: "span", colAttrs: { class: 'border-b pb-2 flex justify-between' }, value: "{{ detailItem.segment }}" },{ label: "意向就读年级", tag: "span", colAttrs: { class: 'border-b pb-2 flex justify-between' }, value: "{{ detailItem.level }}" },{ label: "意向就读方式", tag: "span", colAttrs: { class: 'border-b pb-2 flex justify-between' }, value: "{{ detailItem.afterSchoolCareType }}" },{ label: "原就读学校", tag: "span", colAttrs: { class: 'border-b pb-2 flex justify-between' }, value: "{{ detailItem.schoolRoll }}" },{ label: "中考分数", tag: "span", colAttrs: { class: 'border-b pb-2 flex justify-between' }, value: "{{ detailItem.middleSchoolExamScore }}" },{ label: "中考报名序号", tag: "span", colAttrs: { class: 'border-b pb-2 flex justify-between' }, value: "{{ detailItem.middleSchoolExamSequence }}" }],action: [{tag: 'v-btn',value: "编辑",attrs: {color: 'primary','@click': "doUiAction('startUpdateItem', detailItem); closeDetailDrawer()"},quickAttrs: ['small']}]}]},],includeList: [], // { type: < js | css | html | vueComponent >, path: ''}common: {data: {constantObj: {},validationRules: {requireRules: [v => !!v || '必填',],},filterMap: {}, // 结果筛选条件},dataExpression: {isMobile: 'window.innerWidth < 500'}, // data 表达式watch: {},computed: {tableDataComputed() {if(this.filterMap) {return this.tableData.filter(row => {for (const key in this.filterMap) {if (this.filterMap[key] && row[key] !== this.filterMap[key]) {return false;}}return true;});} else {return this.tableData;}},},doUiAction: {}, // 额外uiAction { [key]: [action1, action2]}async created() {await this.doUiAction('getTableData');},methods: {}},};module.exports = content;
标题-只有页面标题
headContent: [{ tag: 'jh-page-title', value: "班级管理" },],
标题-排序&筛选&模式切换
headContent: [{ tag: 'jh-page-title', value: "班级管理" },{tag: 'jh-order',data: {tableDataOrder: [ { column: "createAt", order: "desc" } ],tableDataOrderList: [{ text: "报名时间↓", value: [ { column: "createAt", order: "desc" } ] },{ text: "成绩分数↓", value: [ { column: "middleSchoolExamScore", order: "desc" } ] },{ text: "更新时间↓", value: [ { column: "operationAt", order: "desc" } ] },],}}, // 固定变量 model: 'tableDataOrder', items: 'tableDataOrderList'{tag: 'jh-search',searchList: [{ tag: 'v-select', model: "serverSearchWhere.semester", colAttrs: { class: 'pb-0' }, attrs: { prefix: '学期:', color: 'success', ':items': 'constantObj.semester' } },{ tag: 'v-select', model: "serverSearchWhere.segment", colAttrs: { class: 'pb-0' }, attrs: { prefix: '学部:', color: 'success', ':items': 'constantObj.segment' } },{ tag: 'v-text-field', model: "serverSearchWhereLike.name", colAttrs: { class: 'pb-0' }, attrs: { label: '学生名字:', color: 'success' }, quickAttrs: ['clearable'] },],data: {serverSearchWhereLike: { name: '' },serverSearchWhere: { semester: '', segment: '小学' },}},{ tag: 'v-spacer'},{ tag: 'jh-mode', data: { viewMode: 'simple' } },],common: {data: {constantObj: {},}}
内容-数据列表
pageContent: [{tag: 'jh-list',props: {limit: 10, // 服务端搜索limit},attrs: { cols: 12, class: 'p-0 pb-7', ':style': '`height: calc(100vh - 140px); overflow-y: auto;overscroll-behavior: contain`' },headers: [{text: "学生Id", value: "studentId", width: 80, isSimpleMode: true},{text: "姓名", value: "name", width: 90, isTitle: true, slot: [`<div v-if="item.isMonitor" class="ml-1"><v-icon color="warning" small>mdi-shield-star</v-icon><span>干部</span></div>`]},{text: "性别", value: "gender", width: 60, isSimpleMode: true},{text: "学生状态", value: "studentStatus", width: 80},{text: "年级", value: "level", width: 70},{text: "入学-推荐人", value: "recommendBy", width: 100, isDetailMode: true},{text: "入学-跟进人", value: "followUpByUserName", width: 100, isDetailMode: true},{text: "跟进阶段", value: "followUpStage", width: 80},{text: "报名时间", value: "createAt", width: 150},{text: "操作者", value: "operationByUser", width: 90},{text: "操作时间", value: "operationAt", width: 150},{text: '操作', value: 'action'},],rowActionList: []}],common: {async created() {await this.doUiAction('getTableData');},doUiAction: {startDetailItem: ['startDetailItem']},methods: {}}
jh-list
| 属性 | 类型 | 必填 | 描述 |
|---|---|---|---|
| props.limit | string | 否 | 分页每页数量 |
| props.rightArrowText | string | 否 | 右边箭头文本 |
| headers | array | ✅ | 字段内容 |
| headers.isSimpleMode | boolean | 否 | 是否只在简单模式显示,默认false |
| headers.isTitle | boolean | 否 | 是否作为行标题 |
| rowActionList | array | 否 | 详情模式下的点击行 |
内容-数据列表(详情弹框)
pageContent: [{tag: 'jh-list',props: {limit: 10,rightArrowText: '',},attrs: { cols: 12, class: 'p-0 pb-7', ':style': '`height: calc(100vh - 140px); overflow-y: auto;overscroll-behavior: contain`' },headers: [{text: "学生Id", value: "studentId", width: 80, isSimpleMode: true},{text: "姓名", value: "name", width: 90, isTitle: true, slot: [`<div v-if="item.isMonitor" class="ml-1"><v-icon color="warning" small>mdi-shield-star</v-icon><span>干部</span></div>`]},{text: "性别", value: "gender", width: 60, isSimpleMode: true},{text: "学生状态", value: "studentStatus", width: 80},{text: "年级", value: "level", width: 70},{text: "跟进阶段", value: "followUpStage", width: 80},{text: "报名时间", value: "createAt", width: 150},{text: '操作', value: 'action', align: 'center', sortable: false, width: 'window.innerWidth < 500 ? 90: 180', class: 'fixed', cellClass: 'fixed'},],rowActionList: [{ text: "编辑", icon: 'mdi-note-edit-outline', color: 'success', click: 'doUiAction("startUpdateItem", item)' }],}],actionContent: [{tag: 'jh-detail-drawer',key: "detail",attrs: {},title: "详情",headSlot: [],card: {tag: 'div',colAttrs: { class: 'pa-0' },value: `<div class="p-3 border-b" ><div class="flex justify-between mb-2 items-center"><div><span class="font-weight-bold text-base">{{ detailItem.name }}</span></div><span :class="'text-sm '">{{ detailItem.followUpStatus }}</span></div><div class="text-gray-500 flex justify-between">意向就读学部:{{ detailItem.segment }}</div><div class="text-gray-500 flex justify-between">报名日期:{{ detailItem.createAt }}</div></div><div class="pa-0 h-2 bg-gray-100" ></div>`},contentList: [{type: 'preview',md: 12,formItemList: [{ label: "性别", tag: "span", colAttrs: { class: 'border-b pb-2 flex justify-between' }, value: "{{ detailItem.gender }}" },{ label: "身份证件号", tag: "span", colAttrs: { class: 'border-b pb-2 flex justify-between' }, value: "{{ detailItem.icNumber }}" },{ label: "家庭住址", tag: "span", colAttrs: { class: 'border-b pb-2 flex justify-between' }, value: "{{ detailItem.residentialAddress }}" },{ label: "意向就读学部", tag: "span", colAttrs: { class: 'border-b pb-2 flex justify-between' }, value: "{{ detailItem.segment }}" },{ label: "意向就读年级", tag: "span", colAttrs: { class: 'border-b pb-2 flex justify-between' }, value: "{{ detailItem.level }}" },{ label: "意向就读方式", tag: "span", colAttrs: { class: 'border-b pb-2 flex justify-between' }, value: "{{ detailItem.afterSchoolCareType }}" },{ label: "原就读学校", tag: "span", colAttrs: { class: 'border-b pb-2 flex justify-between' }, value: "{{ detailItem.schoolRoll }}" },{ label: "中考分数", tag: "span", colAttrs: { class: 'border-b pb-2 flex justify-between' }, value: "{{ detailItem.middleSchoolExamScore }}" },{ label: "中考报名序号", tag: "span", colAttrs: { class: 'border-b pb-2 flex justify-between' }, value: "{{ detailItem.middleSchoolExamSequence }}" }],action: [{tag: 'v-btn',value: "编辑",attrs: {color: 'primary','@click': "doUiAction('startUpdateItem', detailItem); closeDetailDrawer()"},}]}]}],common: {async created() {await this.doUiAction('getTableData');},}
内容-圆点操作菜单
pageContent: [{tag: 'jh-action',attrs: { class: 'h-16 w-16 p-2 fixed right-4 bottom-32' },actionList: [{ tag: 'v-btn', value: '新增', icon: 'mdi-plus', color: 'success', click: "doUiAction('startCreateItem')" },{ tag: 'v-btn', value: '随机分配跟进人', icon: 'mdi-plus', color: 'success', click: "doUiAction('randomFollowUp')", ':disabled': '!tableSelected.length' },]}]
弹框相关
👉参考PC端弹框相关配置 👈
命令详解
生成样例文件页面
默认生成 example_class 和 example_student 数据表、配置文件和页面,方便参考使用
jianghu-init json --generateType=example
生成页面配置文件
根据数据表生成页面配置文件
jianghu-init json --generateType=json --pageType=page --table=class --pageId=classManagement
配置渲染html
根据配置文件生成页面
jianghu-init json --generateType=page --pageType=page --file=classManagement
开启Dev模式
开启dev模式,修改配置文件将自动更新页面
jianghu-init json dev
参数说明
| 参数 | 描述 |
|---|---|
| generateType | 生成类型,可选 example(生成示例文件)、json(数据表生成配置文件)、page(配置文件生成页面) |
| pageType | 页面类型,可选 page、component |
| table | 数据表名,当generateType为json可用 |
| dev | 启用开发模式,执行后会自动检测当前项目的json文件更新并自动更新html文件 |
其他
字符串代码语法高亮
- 在VSCode中,可以安装以下插件来实现字符串代码的语法高亮,以提高代码的可读性:
安装以上插件之后,在字符串代码前指定语法名称,即可显示语法高亮效果。
pageContent: [/*html*/`<v-btn @click="openTestMultiTabDrawer">打开测试多标签弹框</v-btn>`,],style: /*css*/`.jh-v-input {width: 100%;}`
- 你可以调整 VSCode 的配置来更好地支持模板字符串的 HTML 提示。在 VSCode 的设置中,搜索 "editor.quickSuggestions" 并确保在 "strings" 中启用补全建议:
"editor.quickSuggestions": {"strings": true}
version v2版本升级指南
- 增加服务端搜索 jh-page
{tag: 'jh-table',props: {serverPagination: true, // 需要version: v2},attrs: {},}
- doUiAction.getTableData,尽量不要全部覆盖方法链,如需自定义选择相应方法复写
common.doUiAction: {getTableData: ['prepareTableParamsDefault', // 组合搜索条件赋值到:this.tableParams'prepareTableParams', // 自定义条件方法'getTableData', // 请求'formatTableData' // 格式化 tableData]}
- formatTableData 方法
// 原版formatTableData(rows) {rows.forEach(row => {row.operationAt = row.operationAt ? dayjs(row.operationAt).format('YYYY-MM-DD HH:mm:ss') : '';});return rows;}// v2版本formatTableData() {let tableData = this.tableDataFromBackend.map(row => {row.operationAt = row.operationAt ? dayjs(row.operationAt).format('YYYY-MM-DD HH:mm:ss') : '';return row;});this.tableData = tableData;}
version v3版本升级指南
- 重构 init-json jh组件,把需要设置在 common.data 内的变量放入标签内,方便组件变量管理
- jh-order 移动端排序
{tag: 'jh-order',data: {tableDataOrder: [ { column: "createAt", order: "desc" } ],tableDataOrderList: [{ text: "报名时间↓", value: [ { column: "createAt", order: "desc" } ] },{ text: "成绩分数↓", value: [ { column: "middleSchoolExamScore", order: "desc" } ] },{ text: "更新时间↓", value: [ { column: "operationAt", order: "desc" } ] },],}},
- jh-search 服务端搜索
{tag: 'jh-search',searchList: [{ tag: 'v-select', model: "serverSearchWhere.semester", colAttrs: { class: 'pb-0' }, attrs: { prefix: '学期:', color: 'success', ':items': 'constantObj.semester' } },{ tag: 'v-select', model: "serverSearchWhere.segment", colAttrs: { class: 'pb-0' }, attrs: { prefix: '学部:', color: 'success', ':items': 'constantObj.segment' } },{ tag: 'v-text-field', model: "serverSearchWhereLike.name", colAttrs: { class: 'pb-0' }, attrs: { label: '学生名字:', color: 'success' }, quickAttrs: ['clearable'] },],data: {serverSearchWhereLike: { name: '' },serverSearchWhere: { semester: '', segment: '小学' },}},
- jh-mode 模式切换
{ tag: 'jh-mode', data: { viewMode: 'simple' } },
- jh-scene 场景搜索
{tag: 'jh-scene',attrs: { ':showActionBtn': false, ':mobile': false,// "class": "mr-2"},// v3 版本新增特性data: {sceneCreateForm: {},serverSceneSearchWhere: {},serverSceneSearchWhereIn: {},serverSceneSearchWhereLike: {},serverSceneSearchWhereOptions: [],serverSceneSearchWhereOrOptions: [],currentSceneId: '公开',defaultSceneList: [{ name: "全部", where: {}, whereIn: { "articlePublishStatus": ["public", "draft"] } },{ name: "公开", where: { "articlePublishStatus": "public"}, whereIn: {} },{ name: "草稿", where: { "articlePublishStatus": "draft"}, whereIn: {} },{ name: "回收站", where: { "articlePublishStatus": "deleted"}, whereIn: {} },],maxSceneDisplay: 5,}},