在早期的随笔就介绍过,把常规页面的内容拆分为几个不同的组件,如普通的页面,包括列表查询、详细资料查看、新增资料、编辑资料、导入资料等页面场景,这些内容相对比较独立,而有一定的代码量,本篇随笔介绍基于Vue3+Typescript+Setup语法方式,来拆分页面模块内容为组件,实现分而治之的处理。

1、页面模块组件的划分

我们先来了解下常规页面的内容的整体界面布局,它包含常规的列表界面,新增、编辑、查看、导入等界面,除了列表页面,其他内容以弹出层对话框的方式进行处理,如下界面示意图所示。

这些页面也可以放在一个大页面里面进行处理,逻辑代码也可以整合一起进行管理,大致的页面布局如下所示。

我们看到,如果这样放置页面的模块内容,如果界面控件比较多的话,页面代码会急剧增加,而且由于代码太多,管理起来也非常不方便,最好的方式,还是拆分进行组件化的管理比较好 。

我们以一个测试用户的页面为例来介绍,测试用户列表界面如下所示。

其中也包括了查看、编辑、新增、导入等界面,我们后面逐一介绍。

2、页面组件的开发

我们前面介绍到,整个页面包含了列表界面,新增、编辑、查看、导入等界面,除了列表页面,其他内容以弹出层对话框的方式进行处理。

我们分别创建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语法糖编写页面和组件的总结

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

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

    在我们实际项目开发过程中,往往需要根据实际情况,对组件进行封装,以更简便的在界面代码中使用,在实际的前端应用中,适当的组件封装,可以减少很多重复的界面代码,并且能够非常简便的使用,本篇随笔介绍基于El ...

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

    刚完成一些前端项目的开发,腾出精力来总结一些前端开发的技术点,以及继续完善基于SqlSugar的开发框架循序渐进介绍的系列文章,本篇随笔主要介绍一下基于Vue3+TypeScript的全局对象的注入和 ...

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

    在前面随笔<基于SqlSugar的开发框架循序渐进介绍(12)-- 拆分页面模块内容为组件,实现分而治之的处理>中我们已经介绍过,对于相关的业务表的界面代码,我们已经尽可能把不同的业务逻辑 ...

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

    在一个应用系统的开发框架中,往往很多地方需要用到缓存的处理,有些地方是为了便于记录用户的数据,有些地方是为了提高系统的响应速度,如有时候我们在发送一个短信验证码的时候,可以在缓存中设置几分钟的过期时间 ...

  5. 基于SqlSugar的开发框架循序渐进介绍(20)-- 在基于UniApp+Vue的移动端实现多条件查询的处理

    在做一些常规应用的时候,我们往往需要确定条件的内容,以便在后台进行区分的进行精确查询,在移动端,由于受限于屏幕界面的情况,一般会对多个指定的条件进行模糊的搜索,而这个搜索的处理,也是和前者强类型的条件 ...

  6. 基于SqlSugar的开发框架循序渐进介绍(21)-- 在工作流列表页面中增加一些转义信息的输出,在后端进行内容转换

    有时候,为了给前端页面输出内容,有时候我们需要准备和数据库不一样的实体信息,因为数据库可能记录的是一些引用的ID或者特殊字符,那么我们为了避免前端单独的进行转义处理,我们可以在后端进行统一的格式化后再 ...

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

    我喜欢在一个项目开发模式成熟的时候,使用代码生成工具Database2Sharp来配套相关的代码生成,对于我介绍的基于SqlSugar的开发框架,从整体架构确定下来后,我就着手为它们量身定做相关的代码 ...

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

    我们在设计数据库表的时候,往往为了方便,主键ID一般采用字符串类型或者GUID类型,这样对于数据库表记录的迁移非常方便,而且有时候可以在处理关联记录的时候,提前对应的ID值.但有时候进行数据记录插入的 ...

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

    在前面随笔,我们介绍过这个基于SqlSugar的开发框架,我们区分Interface.Modal.Service三个目录来放置不同的内容,其中Modal是SqlSugar的映射实体,Interface ...

随机推荐

  1. 移动应用开发迎来哪些新技术?5月24日相约HDD·线上沙龙·创新开发专场

    HUAWEI Developer Day(简称HDD),是华为开发者联盟与广大开发者深度交流的平台.围绕移动终端的最新技术和产品形态,持续向广大开发者传递华为终端的最新产品和开放服务能力,结合最新的行 ...

  2. SpringBoot实现基于token的登录验证

    一.SpringBoot实现基于token的登录验证 基于token的登录验证实现原理:客户端通过用户名和密码调用登录接口,当验证数据库中存在该用户后,将用户的信息按照token的生成规则,生成一个字 ...

  3. 『忘了再学』Shell基础 — 22、主要的环境变量配置文件说明

    目录 1.source命令 2.Linux系统中环境变量配置文件 (1)登录时生效的环境变量配置文件 (2)/etc/profile环境变量配置文件 (3)/etc/profile.d/*.sh环境变 ...

  4. MIT 6.824(Spring 2020) Lab1: MapReduce 文档翻译

    首发于公众号:努力学习的阿新 前言 大家好,这里是阿新. MIT 6.824 是麻省理工大学开设的一门关于分布式系统的明星课程,共包含四个配套实验,实验的含金量很高,十分适合作为校招生的项目经历,在文 ...

  5. Date类的常见用法——JavaSE基础

    Date类的常见用法 Date类属于java.util包 因此需要导入Date类 Date() 分配一个Date对象,并初始化此对象为系统当前的日期和时间,可以精确到毫秒). Date(long da ...

  6. 【ASP.NET Core】配置应用程序地址的N多种方法

    下面又到了老周误人子弟的时间,今天要误大伙的话题是:找找有多少种方法可以设置 ASP.NET Core 应用的地址,即 URL. 精彩马上开始! 1.UseUrls 方法 这是一个扩展方法,参数是可变 ...

  7. 在CabloyJS中将Webpack生成的文件自动上传到阿里云OSS

    背景 阿里云OSS提供了一个Webpack插件,可在Webpack打包结束后将webpack生成的文件自动上传到阿里云OSS中 下面看看在CabloyJS中如何使用该插件 新建项目,并配置MySQL连 ...

  8. python和numpy中sum()函数的异同

    转载:https://blog.csdn.net/amuchena/article/details/89060798和https://www.runoob.com/python/python-func ...

  9. NOI Online 2022 一游

    NOI Online 2022 一游 TG 啊,上午比提高,根据去年的经验,题目配置估计那至少一黑 所以直接做 1 题即可.(确信) 总体:估分 140,炸了但没完全炸 奇怪的过程 开题:3 2 1 ...

  10. 【C++ 字符串题目】 输入三个人名,按字母顺序排序输出

    题目来源:https://acm.ujn.edu.cn Problem A: [C++ 字符串] 输入三个人名,按字母顺序排序输出 Time Limit: 1 Sec  Memory Limit: 1 ...