基於SqlSugar的開發框架循序漸進介紹(15)-- 整合代碼生成工具進行前端界面的生成

来源:https://www.cnblogs.com/wuhuacong/archive/2022/10/13/16788557.html
-Advertisement-
Play Games

在前面隨筆《基於SqlSugar的開發框架循序漸進介紹(12)-- 拆分頁面模塊內容為組件,實現分而治之的處理》中我們已經介紹過,對於相關的業務表的界面代碼,我們已經儘可能把不同的業務邏輯封裝在不同的頁面組件中,隔離變化的差異,因此界面組件化後,就可以利用代碼生成工具進行統一的界面代碼的生成了,而且... ...


在前面隨筆《基於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的全局對象的註入和使用

 

專註於代碼生成工具、.Net/.NetCore 框架架構及軟體開發,以及各種Vue.js的前端技術應用。著有Winform開發框架/混合式開發框架、微信開發框架、Bootstrap開發框架、ABP開發框架、SqlSugar開發框架等框架產品。
  轉載請註明出處:撰寫人:伍華聰  http://www.iqidi.com 
    

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本人水平有限,如有疏漏或者不正確部分,請大佬指正。 一.Vuex概述 1.1組件之間共用數據的方式 父向子傳值:v-bind 屬性綁定子向父傳值:v-on 事件綁定兄弟組件之間共用數據:eventBUs* $on 接收數據的那個組件* $emit 發送數據的那個組件 特點:適合小範圍使用 1.2Vu ...
  • mounted() { document.body.onresize = function() { // ctrl+滑鼠中鍵滾輪 禁止伸縮頁面 document.body.style.zoom = 1 / window.devicePixelRatio // document.documentEle ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 最近接了個項目,採用uniapp的nvue開發安卓和ios端+小程式端,第一次開發nvue,對於css佈局這塊,還是踩了很多坑。以及一些uniapp的Api在nvue中也無法使用。文章中也收錄了一些我在項目中使用的一些方法,比如富文本解析 ...
  • :::tip 最近在著手騰訊文檔的輸入體驗優化,在其中有一個不起眼的小需求引起了我的註意,並順便研究了一些事件監聽機制相結合的特點,特此記錄一下填坑過程。 ::: 模擬游標跟隨 大部分的主流輸入法都有這樣一個特性,在輸入中文時,可以通過左右方向鍵控制游標,移動至輸入區中任意兩個字元之間的位置,用戶接 ...
  • qiankun angular12 single-spa-angular子應用的改造 參考資料: https://qiankun.umijs.org/zh/guide/tutorial#angular-%E5%BE%AE%E5%BA%94%E7%94%A8 (乾坤官網); https://jueji ...
  • 一、HTTPS協議概念 超文本傳輸安全協議(Hypertext Transfer Protocol Secure,簡稱:HTTPS)是一種通過電腦網路進行安全通信的傳輸協議。HTTPS經由HTTP進行通信,利用SSL/TLS來加密數據包。HTTPS的主要目的是提供對網站伺服器的身份認證,保護交換數 ...
  • Vue組件 數據源 //這裡是HTML內容 這裡通過下麵的引入框架結構把數據源傳到框架中 還有匹配項 <Mytable :configList="configList" :configData="configData"></Mytable> // 引入結構組件 import myCard from ...
  • 概念 performance.now():返回值表示為從time origin之後到當前調用時經過的時間, time origin: 時間源, 時間源是一個可以被認定為當前文檔生命周期的開始節點的標準時間,計算方法如下: 如果腳本的 global object 是 Window, 則時間源的確定方式 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...