基于SqlSugar的开发框架循序渐进介绍(15)-- 整合代码生成工具进行前端界面的生成

简介: 基于SqlSugar的开发框架循序渐进介绍(15)-- 整合代码生成工具进行前端界面的生成

在前面随笔《基于SqlSugar的开发框架循序渐进介绍(12)-- 拆分页面模块内容为组件,实现分而治之的处理》中我们已经介绍过,对于相关的业务表的界面代码,我们已经尽可能把不同的业务逻辑封装在不同的页面组件中,隔离变化的差异,因此界面组件化后,就可以利用代码生成工具进行统一的界面代码的生成了,而且由于变化的隔离处理,我们实际上维护的代码变得更加方便维护了。本篇随笔介绍在整合代码生成工具进行前端界面的生成的一些思路和实际的界面代码的生成。

1、页面的模块化处理

在前面随笔《基于SqlSugar的开发框架循序渐进介绍(12)-- 拆分页面模块内容为组件,实现分而治之的处理》中我们已经介绍过,常规页面包含有列表界面,新增、编辑、查看、导入等界面,除了列表页面,其他内容以弹出层对话框的方式进行处理,如下界面示意图所示。

根据以上的页面划分,我们把一个页面分为search.vue、edit.vue、import.vue、view.vue、index.vue,其中index.vue为整合各个组件的主页面,在视图中如下所示。我们每个业务模块都是如此统一划分,因此比较统一,同时也是为后续的代码生成工具批量生成做好准备。

因此在index.vue页面中,我们整合了几个组件页面即可,如下所示。

<template>
  <div class="main">
    <!--条件及列表展示-->
    <Search ref="searchRef" @show-import="showImport" @show-add="showAdd" @show-view="showView" @show-edit="showEdit" />
    <!--查看详细组件界面-->
    <view-data ref="viewRef" />
    <!--新增、编辑组件界面-->
    <edit-data ref="editRef" @submit="refreshData" />
    <!--模板导入信息-->
    <import-data ref="importRef" @finish="finishImport" />
  </div>
</template>
<script setup lang="ts">
import { reactive, ref, onMounted } from 'vue';
import Search from './search.vue';
import ViewData from './view.vue';
import EditData from './edit.vue';
import ImportData from './import.vue';

 

1)查看视图页面

 我们先以view.vue查看页面为例进行介绍,它是一个查看明细的界面,因此也是一个弹出对话框页面,我们把它的代码处理如下所示。

<template>
  <el-dialog v-if="isVisible" v-model="isVisible" title="查看信息" append-to-body @close="closeDialog">
    <el-form ref="viewRef" :model="viewForm" label-width="100px">
      <el-tabs type="border-card">
        <el-tab-pane label="基本信息">
          <el-descriptions title="" :column="2" border>
            <el-descriptions-item label="显示名称">
              {{ viewForm.name }}
            </el-descriptions-item>
            <el-descriptions-item label="Web地址">
              {{ viewForm.url }}
            </el-descriptions-item>
            <el-descriptions-item label="Web图标">
              <!-- {{ viewForm.webIcon }} -->
              <icon :icon="viewForm.webIcon" />
            </el-descriptions-item>
            <el-descriptions-item label="排序">
              {{ viewForm.seq }}
            </el-descriptions-item>
            <el-descriptions-item label="可见">
              <el-tag v-if="viewForm.visible" type="success" effect="dark">可见</el-tag>
              <el-tag v-else type="danger" effect="dark">隐藏</el-tag>
            </el-descriptions-item>
            <el-descriptions-item label="展开">
              <el-tag v-if="viewForm.expand" type="success" effect="dark">展开</el-tag>
              <el-tag v-else type="" effect="dark">收缩</el-tag>
            </el-descriptions-item>
            <el-descriptions-item label="创建时间">
              <el-date-picker v-model="viewForm.createTime" align="right" type="datetime" placeholder="选择日期"
                value-format="YYYY-MM-DD HH:mm" disabled />
            </el-descriptions-item>
            <el-descriptions-item label="特殊标签">
              {{ viewForm.tag }}
            </el-descriptions-item>
          </el-descriptions>
        </el-tab-pane>
      </el-tabs>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="closeDialog">关闭</el-button>
      </span>
    </template>
  </el-dialog>
</template>
其他的js代码采用tyepscript语法,我们把它放在
<script setup lang="ts">
//逻辑代码
</script>

然后我们在js代码中抛出show的方法,便于父组件的调用。

//显示窗口
const show = (id: string | number) => {
  if (!$u.test.isNullOrUnDef(id)) {
    menu.Get(id).then((data) => {
      Object.assign(viewForm, data);
      isVisible.value = true; //显示对话框
    });
  }
};
//暴露组件属性和方法
defineExpose({
  show,
});

同时在页面里面,也定义一个表单的对象引用,便于上面模板组件的显示。

const viewRef = ref<FormInstance>(); //表单引用
// 表单属性定义
let viewForm = reactive({
  iD: '',
  pid: '',
  name: '',
  icon: '',
  seq: '',
  functionId: '',
  visible: 0,
  expand: 0,
  winformType: '',
  url: '',
  webIcon: '',
  creator: '',
  createTime: '',
  tag: '',
});

如果是查看详细的视图中有树形列表,我们还可以在onMounted的处理中,添加获取树列表的数据即可,如下代码所示。

//挂载的时候初始化数据
onMounted(() => {
  // 设置默认值
  getTree();
});
// 初始化树列表
let treedata = ref([]);
const getTree = () => {
  // 树列表数据获取
  menu.GetAll().then((data) => {
    treedata.value = []; // 树列表清空
    var list = data?.items;
    if (list) {
      var newTreedata = $u.util.getJsonTree(list, {
        id: 'id',
        pid: 'pid',
        label: 'name',
        children: 'children',
      });
      treedata.value = newTreedata;
    }
  });
};

而查看视图的触发,往往在列表的操作按钮中,或者双击表格行进行触发,界面如下所示。

界面如下代码所示。

而调用查看详细页面的事件,传递对应的id并调用组件实例抛出的方法即可。如下代码所示。

// 显示查看对话框处理
const viewRef = ref<InstanceType<typeof ViewData>>();
function showView(id) {
  viewRef.value.show(id);
}

至此,一个独立的视图页面组件,以及如何触发调用就完成了,视图页面单独维护,便于代码的管理,同时也隔离了复杂的页面逻辑。

视图页面效果如下所示。

 

2)新增编辑视图页面

在常规的处理中,往往编辑和新增的界面是差不多的,差异不同的地方,我们可以通过条件 if 的方式进行处理即可。因此可以把两者放在一个组件中实现对话框内容和逻辑处理。

刚才我们提到了Index.vue页面,是对几个组件的统筹处理,如下代码所示。

<template>
  <div class="main">
    <!--条件及列表展示-->
    <Search ref="searchRef" @show-import="showImport" @show-add="showAdd" @show-view="showView" @show-edit="showEdit" />
    <!--查看详细组件界面-->
    <view-data ref="viewRef" />
    <!--新增、编辑组件界面-->
    <edit-data ref="editRef" @submit="refreshData" />
    <!--模板导入信息-->
    <import-data ref="importRef" @finish="finishImport" />
  </div>
</template>

从上面代码我们看到,在HTML代码中,我们引入对应的组件,并在主查询页面中触发事件即可,如下所示。

其中showAdd和ShowEdit类似,都是调用编辑/新增的对话框,不同的是,通过传递id来辨别是否为新增,如果需要传入pid的父节点信息,那么我们也可以创建一个showAdd的方法。

//新增、编辑表单引用
const editRef = ref<InstanceType<typeof EditData>>();
//显示新增对话框
function showAdd(pid?: string | number) {
 editRef.value.showAdd(pid);
}
// 显示编辑对话框
function showEdit(id) {
  editRef.value.show(id);
}
//新增/更新后刷新
function refreshData() {
  searchRef.value.getlist();
}

编辑业务数据的对话框和查看详细的类似,不过这里是需要使用输入控件进行内容编辑修改处理的。

对于一些复杂控件,我们可以自定义组件来简化在界面上的使用,尽可能的快捷、简单。

我们在组件中定义showAdd和show的方法,便于父组件的调用即可,如果传递了id值,我们根据业务对象的get方法获取详细的数据,赋值到表单对象上就可以正常显示了。

//默认标题为[编辑信息],当show传入id为空的时候,为[新建信息]
let title = ref('编辑信息');
let isAdd = ref(false); //是否新增状态
//显示窗口(编辑/新建)
const showAdd = async (pid?: string | number) => {
  title.value = '新建信息';
  isAdd.value = true;
  resetFields(); //清空表单
  editForm.pid = pid + '';
  isVisible.value = true; //显示对话框
};
const show = async (id?: string | number) => {
  if (!$u.test.isNullOrUnDef(id)) {
    title.value = '编辑信息';
    isAdd.value = false;
    await menu.Get(id).then((data) => {
      Object.assign(editForm, data);
    });
  } else {
    title.value = '新建信息';
    isAdd.value = true;
    resetFields(); //清空表单
  }
  isVisible.value = true; //显示对话框
};

抛出这两个实例的方法,供外面调用。

//暴露组件属性和方法
defineExpose({
  show,
  showAdd,
});

为了承载表单的数据模型,我们创建相关的业务对象

const editRef = ref<FormInstance>(); //表单引用
// 表单属性定义(初始化)
let editForm = reactive({
  id: '',
  pid: '',
  name: '',
  icon: '',
  functionId: '',
  winformType: '',
  url: '',
  seq: '001',
  isTop: false,
  expand: 1,
  visible: 1,
  webIcon: '',
  tag: 'web', // Web专用
});

保存数据的时候,我们判断表单的rules规则,如果符合通过,那么提交数据并提示用户即可。

// 保存数据处理
async function submitData() {
  var formEl = editRef.value;
  if (!formEl) return;
  await formEl.validate(async (valid) => {
    if (valid) {
      //验证成功,执行下面方法
      var result = false;
      if (isAdd.value) {
        result = await menu.Create(editForm); //新增保存
      } else {
        result = await menu.Update(editForm); //编辑保存
      }
      if (result) {
        $u.success('操作成功!'); // 提示信息
        emit('submit'); // 提示刷新数据
        closeDialog(); // 重置窗口状态
      } else {
        $u.error('操作失败');
      }
    }
  });
}

编辑界面的效果如下所示。

 

3)导入界面的处理

导入界面,一般我们分为几个步骤,一个是提供导入模板下载,然后上传文件并显示数据,然后确认提交即可。

由于导入数据的逻辑上大致类似,不同的是他们的业务数据和验证规则,因此我们通过自定义组件的方式,来简化相关的处理。

我通过改造ele-import 的第三方组件,让它支持Vue3+Typescript语法,实现对业务数据的上传操作。

<template>
  <div class="main">
    <!--条件及列表展示-->
    <Search ref="searchRef" @show-import="showImport" @show-add="showAdd" @show-view="showView" @show-edit="showEdit" />
    <import-data ref="importRef" @finish="finishImport" />
  </div>
</template>

而在import.vue页面里面,我们的代码是使用ele-import来处理即可。

<template>
  <div>
    <!-- 模板导入信息 -->
    <ele-import :fields="importForm.fields" :filepath="importForm.filepath" :append="importForm.append"
      :formatter="importForm.formatter" :rules="importForm.rules" :tips="importForm.tips" :title="importForm.title"
      :visible="isVisible" :request-fn="saveImport" @close="close" @finish="finishImport" />
  </div>
</template>

通过传入对应的数据,如导入字段,以及规则,以及下载文件等相关参数,就可以实现了文件的上传处理了。

// 请求服务端处理上传数据,返回一个Promise对象
const saveImport = async (data) => {
  // console.log(data);
  const result = await menu.SaveImport(data);
  // console.log(result);
  if (result) {
    return Promise.resolve();
  } else {
    return Promise.reject();
  }
};

同时,这也是一个弹出窗口,因此也需要暴露show方法给外部调用。

//显示窗口
const show = () => {
  isVisible.value = true; //显示对话框
};
//暴露组件属性和方法
defineExpose({
  show,
});

而这个组件的相关数据信息,定义在importForm中,我们来看看对应的数据格式。

const importForm = reactive({
  // Excel 模板导入数据
  // 弹出层标题
  title: '功能菜单导入',
  // 提示信息
  tips: [], // ['商品编号 必填', '产品类型 必填', '商品名称 必填'],
  // 字段名称参照表
  fields: {
    // 字段根据需要裁剪
    pid: '父ID',
    name: '显示名称',
    icon: '图标',
    seq: '排序',
    url: 'Url地址',
    webIcon: '菜单图标',
    systemType_ID: '系统编号',
    tag: '特殊标签',
  },// 附加数据, 在每条记录上都会加这两个字段和值
  append: {
    // company: '广州爱奇迪',
    // leader: '伍华聪'
  },
  // 参数校检, 和 element-ui 中 form表单中传递的rules一样, 都是使用的 async-validator 库
  // https://element.eleme.cn/#/zh-CN/component/form#biao-dan-yan-zheng
  rules: {
    pid: { type: 'string', required: true, message: '父ID必填' },
    name: { type: 'string', required: true, message: '显示名称必填' },
    url: { type: 'string', required: true, message: 'Url地址必填' },
    webIcon: { type: 'string', required: true, message: '菜单图标必填' },
    systemType_ID: { type: 'string', required: true, message: '系统编号必填' },
    tag: { type: 'string', required: true, message: '特殊标签必填' },
  },
  // Excel模板下载地址。注意, 只能是.xlsx的文件, .xls或者.cvs都会报错
  filepath: 'http://localhost:5043/UploadFiles/template/功能菜单.xlsx',
});

整个导入模块,会通过这个对象的数据格式,进行不同的显示和校验处理等操作。界面效果如下所示。

其中第一步提示信息,并提供模板文件下载

第二步提供文件上传处理。

 第三步确认数据并完成处理。

这种统一的操作,我们通过封装,隔离了逻辑步骤的协调处理,只需要在业务组件中生成相关的数据即可,便于使用。

 

2、利用代码生成工具快速生成

通过上面的介绍,我们了解到整个页面的组件代码结构,因此可以利用它们和数据表之间的关系,生成对应的页面组件,利用代码生成工具Database2Sharp强大的数据库元数据和模板引擎,我们构建了对应的框架代码生成规则,因此统一生成即可,提高了代码开发的效能,同时也统一了代码的结构,便于大项目的维护。

对于SQLSugar的项目框架,我们为了方便,分别单独提供后端代码和Web API代码的生成、Winform界面代码的生成,以及前面介绍到的Vue3+TypeScript+ElementPlus的代码生成操作。

代码生成工具的界面效果如下所示,通过入口菜单,可以实现不同部分的代码快速生成。

通过隔离页面组件的内容变化,实现变化不同通过数据库表关系生成,固定部分采用规定模板预置内容,实现了代码的快速生成操作。

 

系列文章:

基于SqlSugar的开发框架的循序渐进介绍(1)--框架基础类的设计和使用

基于SqlSugar的开发框架循序渐进介绍(2)-- 基于中间表的查询处理

基于SqlSugar的开发框架循序渐进介绍(3)-- 实现代码生成工具Database2Sharp的整合开发

基于SqlSugar的开发框架循序渐进介绍(4)-- 在数据访问基类中对GUID主键进行自动赋值处理

基于SqlSugar的开发框架循序渐进介绍(5)-- 在服务层使用接口注入方式实现IOC控制反转

基于SqlSugar的开发框架循序渐进介绍(6)-- 在基类接口中注入用户身份信息接口

基于SqlSugar的开发框架循序渐进介绍(7)-- 在文件上传模块中采用选项模式【Options】处理常规上传和FTP文件上传

基于SqlSugar的开发框架循序渐进介绍(8)-- 在基类函数封装实现用户操作日志记录

基于SqlSugar的开发框架循序渐进介绍(9)-- 结合Winform控件实现字段的权限控制

基于SqlSugar的开发框架循序渐进介绍(10)-- 利用axios组件的封装,实现对后端API数据的访问和基类的统一封装处理

基于SqlSugar的开发框架循序渐进介绍(11)-- 使用TypeScript和Vue3的Setup语法糖编写页面和组件的总结

基于SqlSugar的开发框架循序渐进介绍(12)-- 拆分页面模块内容为组件,实现分而治之的处理

基于SqlSugar的开发框架循序渐进介绍(13)-- 基于ElementPlus的上传组件进行封装,便于项目使用

基于SqlSugar的开发框架循序渐进介绍(14)-- 基于Vue3+TypeScript的全局对象的注入和使用

基于SqlSugar的开发框架循序渐进介绍(15)-- 整合代码生成工具进行前端界面的生成

基于SqlSugar的开发框架循序渐进介绍(16)-- 工作流模块的功能介绍

基于SqlSugar的开发框架循序渐进介绍(17)-- 基于CSRedis实现缓存的处理

基于SqlSugar的开发框架循序渐进介绍(18)-- 基于代码生成工具Database2Sharp,快速生成Vue3+TypeScript的前端界面和Winform端界面

专注于代码生成工具、.Net/.NetCore 框架架构及软件开发,以及各种Vue.js的前端技术应用。著有Winform开发框架/混合式开发框架、微信开发框架、Bootstrap开发框架、ABP开发框架、SqlSugar开发框架等框架产品。
 转载请注明出处:撰写人:伍华聪  http://www.iqidi.com

相关文章
|
12天前
|
前端开发 JavaScript API
(前端3D模型开发)网页三维CAD中加载和保存STEP模型
本文介绍了如何使用`mxcad3d`库在网页上实现STEP格式三维模型的导入与导出。首先,通过官方教程搭建基本项目环境,了解核心对象如MxCAD3DObject、Mx3dDbDocument等的使用方法。接着,编写了加载和保存STEP模型的具体代码,包括HTML界面设计和TypeScript逻辑实现。最后,通过运行项目验证功能,展示了从模型加载到保存的全过程。此外,`mxcad3d`还支持多种其他格式的三维模型文件操作。
|
1月前
|
前端开发 JavaScript 开发者
颠覆传统:React框架如何引领前端开发的革命性变革
【10月更文挑战第32天】本文以问答形式探讨了React框架的特性和应用。React是一款由Facebook推出的JavaScript库,以其虚拟DOM机制和组件化设计,成为构建高性能单页面应用的理想选择。文章介绍了如何开始一个React项目、组件化思想的体现、性能优化方法、表单处理及路由实现等内容,帮助开发者更好地理解和使用React。
77 9
|
4天前
|
前端开发 JavaScript 开发者
前端项目代码规范工具 (ESLint. Prettier. Stylelint. TypeScript)
前端项目代码规范工具 (ESLint. Prettier. Stylelint. TypeScript)
|
5天前
|
机器学习/深度学习 前端开发 算法
婚恋交友系统平台 相亲交友平台系统 婚恋交友系统APP 婚恋系统源码 婚恋交友平台开发流程 婚恋交友系统架构设计 婚恋交友系统前端/后端开发 婚恋交友系统匹配推荐算法优化
婚恋交友系统平台通过线上互动帮助单身男女找到合适伴侣,提供用户注册、个人资料填写、匹配推荐、实时聊天、社区互动等功能。开发流程包括需求分析、技术选型、系统架构设计、功能实现、测试优化和上线运维。匹配推荐算法优化是核心,通过用户行为数据分析和机器学习提高匹配准确性。
26 3
|
1月前
|
前端开发 数据处理 Android开发
Flutter前端开发中的调试技巧与工具使用方法,涵盖调试的重要性、基本技巧如打印日志与断点调试、常用调试工具如Android Studio/VS Code调试器和Flutter Inspector的介绍
本文深入探讨了Flutter前端开发中的调试技巧与工具使用方法,涵盖调试的重要性、基本技巧如打印日志与断点调试、常用调试工具如Android Studio/VS Code调试器和Flutter Inspector的介绍,以及具体操作步骤、常见问题解决、高级调试技巧、团队协作中的调试应用和未来发展趋势,旨在帮助开发者提高调试效率,提升应用质量。
48 8
|
3天前
|
前端开发 搜索推荐 安全
陪玩系统架构设计陪玩系统前后端开发,陪玩前端设计是如何让人眼前一亮的?
陪玩系统的架构设计、前后端开发及前端设计是构建吸引用户、功能完善的平台关键。架构需考虑用户需求、技术选型、安全性等,确保稳定性和扩展性。前端可选用React、Vue或Uniapp,后端用Spring Boot或Django,数据库结合MySQL和MongoDB。功能涵盖用户管理、陪玩者管理、订单处理、智能匹配与通讯。安全性方面采用SSL加密和定期漏洞扫描。前端设计注重美观、易用及个性化推荐,提升用户体验和平台粘性。
16 0
|
1月前
|
前端开发 JavaScript API
前端界的秘密武器:掌握这些框架,让你轻松秒杀99%的同行!
前端开发日新月异,掌握几个明星框架如React、Vue.js和Angular,不仅能让工作更得心应手,还能轻松超越同行。React以高效的虚拟DOM和组件化著称;Vue.js简洁易懂,灵活性高;Angular提供全面的解决方案,适合大型应用。此外,轻量级的Svelte也值得关注,其编译时处理设计提升了应用性能。掌握这些框架,结合深刻理解和灵活运用,助你在前端领域脱颖而出。
31 9
|
1月前
|
监控 前端开发 JavaScript
前端稳定性工具-Sentry
【11月更文挑战第9天】Sentry 是一个开源的错误和性能监控平台,支持多种编程语言和框架。它能够捕获前端应用中的各种错误和性能问题,提供详细的错误信息和用户行为关联,帮助开发团队快速定位和解决问题,优化应用性能。但需注意隐私保护、数据准确性和成本控制。
|
1月前
|
Web App开发 前端开发 JavaScript
前端开发的秘密武器:这些工具让你轻松应对各种复杂布局!
【10月更文挑战第31天】前端开发充满挑战,尤其是在处理复杂布局时。本文介绍了几种关键工具和技术,如HTML和CSS基础、Firefox开发者工具、Visual Studio Code以及Vue、React和Angular等前端框架,帮助开发者高效应对复杂布局,提升代码质量和用户体验。
35 2
|
2月前
|
存储 人工智能 前端开发
前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
185 2