在早期的隨筆就介紹過,把常規頁面的內容拆分為幾個不同的元件,如普通的頁面,包括列表查詢、詳細資料檢視、新增資料、編輯資料、匯入資料等頁面場景,這些內容相對比較獨立,而有一定的程式碼量,本篇隨筆介紹基於Vue3+Typescript+Setup語法方式,來拆分頁面模組內容為元件,實現分而治之的處理。
我們先來了解下常規頁面的內容的整體介面佈局,它包含常規的列表介面,新增、編輯、檢視、匯入等介面,除了列表頁面,其他內容以彈出層對話方塊的方式進行處理,如下介面示意圖所示。
我們看到,如果這樣放置頁面的模組內容,如果介面控制元件比較多的話,頁面程式碼會急劇增加,而且由於程式碼太多,管理起來也非常不方便,最好的方式,還是拆分進行元件化的管理比較好 。
我們以一個測試使用者的頁面為例來介紹,測試使用者列表介面如下所示。
其中也包括了檢視、編輯、新增、匯入等介面,我們後面逐一介紹。
我們前面介紹到,整個頁面包含了列表介面,新增、編輯、檢視、匯入等介面,除了列表頁面,其他內容以彈出層對話方塊的方式進行處理。
我們分別建立index.vue代表主列表頁面內容,view代表檢視頁面、edit代表新增或者編輯頁面(兩個頁面類似,因此整合一起更精簡),import代表匯入頁面,一起放在一個testuser頁面目錄中,作為一個模組頁面。
我們先以view.vue檢視頁面為例進行介紹,它是一個檢視明細的介面,因此也是一個彈出對話方塊頁面,我們把它的程式碼處理如下所示。
<template> <el-dialog title="檢視資訊" v-model="isVisible" v-if="isVisible" append-to-body @close="closeDialog(viewRef)"> <el-form ref="viewRef" :model="viewForm" label-width="80px"> <el-tabs type="border-card"> <el-tab-pane label="基本資訊"> <el-row> <el-col :span="12"> <el-form-item label="姓名"> <el-input v-model="viewForm.name" disabled /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="性別"> <el-input v-model="viewForm.sex" disabled /> </el-form-item> </el-col> .................//省略程式碼 </el-tab-pane> </el-tabs> </el-form> <template #footer> <span class="dialog-footer"> <el-button @click="closeDialog(viewRef)">關閉</el-button> </span> </template> </el-dialog> </template>
其他的js程式碼採用tyepscript語法,我們把它放在
<script setup lang="ts"> //邏輯程式碼 </script>
為了把元件的方法公開,我們先定義一個介面型別,便於參照的時候,程式碼進行約束提示。
<script setup lang="ts"> //元件的介面型別 export interface ExposeViewType { show(id?: string | number): Function; } ............ //顯示視窗 const show = (id: string | number) => { //處理程式碼 }; //暴露元件屬性和方法 defineExpose({ show }); </script>
這樣我們在父頁面中使用子模組元件的時候,就可以通過公開的方法進行呼叫了。
//父頁面index.vue <!--檢視詳細元件介面--> <view-data ref="viewRef" /> <!--新增、編輯元件介面--> <edit-data ref="editRef" @submit="saveEdit" /> <!--模板匯入資訊--> <import-data ref="importRef" @finish="finishImport" /> </div> </template> <script setup lang="ts"> ........ import ViewData, { ExposeViewType } from "./view.vue"; import EditData from "./edit.vue"; import ImportData from "./import.vue"; ...... // 顯示檢視對話方塊處理 const viewRef = ref<ExposeViewType | null>(); //檢視表單參照 //const viewRef = ref<InstanceType<typeof ViewData>>(); function showView(id) { if (isEmpty(id)) { warnMessage("請選擇編輯的記錄!"); return; } viewRef.value.show(id); }
我們通過const viewRef = ref<ExposeViewType | null>(); 就可以獲得元件型別的參照,然後呼叫元件的介面方法即可。
viewRef.value.show(id);
在檢視頁面的元件定義模板中,我們大致程式碼如下所示。
宣告了對應的參照,以及表單物件,以及提供相應的方法進行處理,這些內容對父頁面封裝了細節。
<script setup lang="ts"> //元件的介面型別 export interface ExposeViewType { show(id?: string | number): Function; } import { reactive, ref, onMounted, watch, computed, nextTick } from "vue"; import { FormInstance} from "element-plus"; defineOptions({ name: "ViewData" }); //定義元件名稱 //宣告Props的介面型別 interface Props { visible?: boolean; // 是否顯示 id?: string | number; // 接受外部v-model傳入的id值 } //使用預設值定義Props const props = withDefaults(defineProps<Props>(), { visible: false, value: null }); //宣告元件事件 interface Emits { (e: "update:id", id: string | number): void; (e: "update:visible", visible: boolean): void; (e: "close"): void; //(e: "submit"): void; } //定義元件事件 const emit = defineEmits<Emits>();
我們定義了元件名稱、元件的Props屬性、以及Emit事件,Emit事件如果想簡單化一點,也可以直接使用名稱即可。
例如,有時候我們會直接宣告名稱進行定義Emit,如下所示。
//定義觸發事件 const emit = defineEmits(["error", "success", "remove", "change"]);
顯示頁面的方法,是公開給父頁面進行呼叫的,因此接收一個id引數,並根據id值,利用axios存取遠端API介面獲取資料,進行賦值顯示即可。
//顯示視窗 const show = (id: string | number) => { if (!isNullOrUnDef(id)) { testuser.Get(id).then(data => { // console.log(data); Object.assign(viewForm, data); isVisible.value = true; //顯示對話方塊 }); } };
關於axios存取遠端API介面的類實現,可以參考隨筆《基於SqlSugar的開發框架循序漸進介紹(10)-- 利用axios元件的封裝,實現對後端API資料的存取和基礎類別的統一封裝處理》進行了解。
這裡的TestUser的APi類,繼承自基礎類別BaseApi,因此擁有常規的處理方法。
最後,檢視明細的視窗關閉後,需要設定一下視窗的相關標記。
let isVisible = ref(false); //是否顯示檢視對話方塊 function closeDialog(formEl: FormInstance | undefined) { // 關閉常規 新增、編輯、檢視、匯入等視窗處理 isVisible.value = false; if (!formEl) { formEl.resetFields(); } emit("close"); //關閉 }
由於視窗內部的顯示標記和Prop屬性的關係,我們需要處理一下,對他們進行Watch監控,並處理值的變化。
//監控某些值的變化,進行處理 watch( () => props.visible, newValue => { isVisible.value = newValue; emit("update:visible", newValue); } ); watch( () => isVisible, newValue => { // console.log(newValue); emit("update:visible", newValue.value); } );
表單的form物件,我們根據後端資料結構進行生成即可。
const viewRef = ref<FormInstance>(); //表單參照 // 表單屬性定義 let viewForm = reactive({ id: "", name: "", sex: "", birthDate: "", nationality: "", education: "", marriage: "", star: "", height: "", weight: "", ................. createTime: "", extensionData: "" // 擴充套件資料 });
有了這些處理,我們檢視詳細的頁面彈出和關閉就正常了。頁面效果如下所示。
新建、編輯頁面也是類似,只是在儲存資料後觸發相關的事件,讓父頁面進行更新顯示即可。
<!--檢視詳細元件介面--> <view-data ref="viewRef" /> <!--新增、編輯元件介面--> <edit-data ref="editRef" @submit="saveEdit" /> <!--模板匯入資訊--> <import-data ref="importRef" @finish="finishImport" />
如編輯、新增頁面的父元件頁面,也是隻需關注他的開啟和完成處理即可。
//新增、編輯表單參照 const editRef = ref<ExposeViewType | null>(); //顯示新增對話方塊 function showAdd() { editRef.value.show(); } // 顯示編輯對話方塊 function showEdit(id) { if (isEmpty(id)) { warnMessage("請選擇編輯的記錄!"); return; } editRef.value.show(id); } //新增/更新後重新整理 function saveEdit() { getlist(); }
而在編輯資訊的元件頁面內部,就需要判斷是更新還是插入記錄的處理,完成後再丟擲事件即可。
// 儲存資料處理 async function submitData() { var formEl = editRef.value; if (!formEl) return; // console.log(editForm); await formEl.validate(async valid => { if (valid) { //驗證成功,執行下面方法 var result = false; if (isAdd.value) { result = await testuser.Create(editForm); //新增儲存 } else { result = await testuser.Update(editForm); //編輯儲存 } if (result) { successMessage("操作成功!"); // 提示資訊 emit("submit"); // 提示重新整理資料 closeDialog(formEl); // 重置視窗狀態 } else { errorMessage("操作失敗"); } } })
匯入資料頁面,大體也是類似,不過由於涉及到更多的是對匯入處理的規則處理,需要封裝一下相關的元件功能,因此後面再獨立介紹細節實現。
系列文章:
《基於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語法糖編寫頁面和元件的總結》