vue3.0 通用管理页面封装

bmTable使用方法

<BmTable url="/project/list":columns="columns":formItem="formItem":formConfig="formConfig":isPagination="true"@postData="postData"@preData="preData"ref="bmTable"><template #bmSuffix><div><el-button type="success">新增</el-button></div></template></BmTable>
export default {mixins: [IndexMixin],setup() {const bmTable = ref()const postData = (data)=> { return data; }const preData = (data)=> { return data; }return {postData,preData,bmTable}}
}

export default {data() {return {columns: [{prop: 'creatTime',label: '创建时间',},{prop: 'datas',label: '操作',labelWidth: 180,render: (item)=> {return <><el-button link type="success" onClick={()=> { this.deletes(item); }}>删除</el-button></>}}],formItem: [{prop: 'created',label: '创建时间',el: 'el-input',placeholder: '123',defaultValue: 'test'},{prop: 'crea',label: '创建',el: 'el-select',data: [{label: '123', value: '1'}, {label: '3', value: '2'}],elOpt: 'el-option',placeholder: '123',defaultValue: '1'},],formConfig: { }}},
}

参数

  1. columns 表格列参数
  2. formItem 页面搜索条件参数
  3. formConfig 页面搜索内容配置参数
  4. isPagination 是否前端分页
  5. bmSuffix 插槽 页面操作按钮位置,如新增、批量下载、批量删除等操作

事件

  1. postData 请求完成后对返回的数据处理事件
  2. preData 请求前对请求参数处理事件

实现方案
原理:当我们存在多个组件中的数据或者功能很相近时,我们就可以利用 mixins 将公共部分提取出来,通过 mixins 封装函数,组件调用他们是不会改变函数作用域外部的。

注意事项

  • 接口返回数据
    接口返回参数若后端分页时数据放入data.data.result, 前端分页时数据放入data.data
if (!isPagination) {tableData.list = onPostData ? onPostData(data.data) : data.data;tableData.data = tableData.list.slice((tableData.pagination.page - 1) * tableData.pagination.pageSize,tableData.pagination.page * tableData.pagination.pageSize);tableData.pagination.total = tableData.list.length;return;}tableData.data = onPostData? onPostData(data.data.result): data.data.result;tableData.pagination.total = data.data.total;});

组件封装源码

index.vue

<template><div class="bm-content"><BmForm:formConfig="formConfig":initData="searchData":formItem="formItem":inline="true"@search="search"v-if="formItem?.length"></BmForm><slot name="bmSuffix"></slot><el-table:data="tableData.data"style="width: 100%"stripev-bind="$attrs"header-row-class-name="bm-table-header"row-class-name="bm-table-body"><el-table-columnv-for="(item, index) in columns":key="item.label":width="item.labelWidth"v-bind="item"><template #default="scope"><span v-if="!item.render">{{ scope.row[item.prop] }}</span><render v-else :render="item.render" :data="scope.row" /></template></el-table-column></el-table><div class="bm-pagination"><el-paginationv-model:current-page="tableData.pagination.page"v-model:page-size="tableData.pagination.pageSize"@current-change="currentChange":page-sizes="[10, 20, 50]"smalllayout="total, sizes, prev, pager, next, jumper":total="tableData.pagination.total"background/></div></div>
</template><script lang="ts" setup>
import render from "./render.jsx";
interface propsType {method?: string; // 方法url?: string; // 地址columns?: {label?: string;props?: string;labelWidth?: number;render?: any;};isPagination?: boolean; // 是否前端分页onPostData?: Function; // 后置数据处理formConfig?: Object; // 表单配置formItem?: any[]; // 表单item配置onPreData?: Function; // 参数前置处理
}
import { getCurrentInstance, onMounted, reactive, useAttrs, ref } from "vue";const Instance = getCurrentInstance();
const http = Instance?.appContext.config.globalProperties.$http;
const attrs = useAttrs();const {method = "get",url,columns,isPagination = true,onPostData,formConfig,formItem,onPreData,
}: propsType = attrs;
const searchData = reactive({});const tableData: any = reactive({data: [],list: [],pagination: {total: 0,pageSize: 10,page: 1,},
});const getList = () => {// 请求参数 queryconst query: any = { ...searchData };if (isPagination) {query.page = tableData.pagination.page;query.pageSize = tableData.pagination.pageSize;}// 前置调用onPreData && onPreData(query);http({method: method,url: url,data: query,}).then((data: any) => {// 后置调用// result.dataif (!isPagination) {tableData.list = onPostData ? onPostData(data.data) : data.data;tableData.data = tableData.list.slice((tableData.pagination.page - 1) * tableData.pagination.pageSize,tableData.pagination.page * tableData.pagination.pageSize);tableData.pagination.total = tableData.list.length;return;}tableData.data = onPostData? onPostData(data.data.result): data.data.result;tableData.pagination.total = data.data.total;});
};const currentChange = (e: any) => {if (!isPagination) {tableData.data = tableData.list.slice((e - 1) * tableData.pagination.pageSize,e * tableData.pagination.pageSize);return;}getList();
};const search = (data, formData) => {data.validate((valid) => {if (valid) {Object.keys(searchData).map((item) => {searchData[item] = formData[item];});getList();} else {return false;}});
};onMounted(() => {formItem?.map((item) => {searchData[item.prop] = item.defaultValue ? item.defaultValue : "";});getList();
});defineExpose({getList,
});
</script>
<style lang="less" scoped>
:deep(.bm-table-header) {height: 60px;
}
:deep(.bm-table-body) {height: 50px;.cell {font-size: 13px;}
}
.bm-pagination {display: flex;justify-content: flex-end;height: 50px;background-color: #ffff;
}
.bm-content {border-radius: 3px;overflow: hidden;// height: calc(100vh - 100px);// background-color: white;
}
</style>

render.jsx

export default {render(context) {return (<>{context.$attrs.render(context.$attrs.data)}</>);}
}

bmform.vue


<template><el-form v-bind="$attrs" :model="formData" ref="formRef"><el-form-item v-for="(item, ind) in formItem" :key="ind" v-bind="item"><component :is="item.el" v-bind="item" v-model="formData[item.prop]" v-if="!item.types"><component :is="item.elOpt"v-for="(option, index) in item.data":key="index"v-bind="option"v-if="item.data"></component></component><el-buttontype="primary"v-elsev-for="(opt, key) in item.options":key="key"v-bind="opt"@click="opt.click(formRef)">{{ opt.value }}</el-button></el-form-item><el-form-item v-if="$attrs.inline"><el-button type="primary" :icon="Search" @click="submitForm(formRef)" style="width: 0px;">搜索</el-button></el-form-item></el-form>
</template>
<script setup lang="ts">
import { useAttrs, reactive, ref } from "vue";
import { Search } from '@element-plus/icons-vue';const emit = defineEmits(['search'])
const attr = useAttrs();
const formRef = ref()const { formConfig, formItem, initData }: any = attr;
const formData = reactive(initData);// 数据向外暴露
const submitForm = (data)=> {emit('search', data, formData)
}</script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/240391.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[SQL]实验 视图和索引的应用

实验目的&#xff1a; [实验目的和要求] 1、掌握视图的创建、修改和重命名的方法 2、掌握视图中数据的操作 3、了解索引的作用 4、掌握索引的创建方法 实验步骤&#xff1a; 1、在销售管理数据库中&#xff0c;创建一个女职工视图&#xff0c;包括员工的编号、姓名、性别、雇佣…

JavaScript 数组去重 ES6 方法总结

JavaScript 数组去重 ES6 方法 方法一 new Set()生成出来的数据是Set数据结构&#xff0c;需要自行转换成对应结构 let array [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 3, 3, 9, 8, 9, s, o, o]; Array.from(new Set(array));方法二 let array [0, 1, 2, 3, 4, 5, 6, 7, 8,…

网站怎么才能做好SEO?网站SEO指引!!

在当今互联网的激烈竞争中&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;已成为提升网站流量和吸引更多用户的关键手段。为了帮助您更好地掌握SEO网站优化技巧&#xff0c;本文将深入探讨以下几个方面&#xff1a; 一、关键词策略 关键词策略是SEO优化的基石。正确选择…

【WPF.NET开发】创建样式

本文内容 创建样式隐式应用样式显式应用样式以编程方式应用样式扩展样式TargetType 属性与 x:Key 属性之间的关系 使用 Windows Presentation Foundation (WPF)&#xff0c;可以使用自己的可重用样式自定义现有控件的外观。 可以对应用、窗口和页面全局应用样式&#xff0c;也…

linux同步文件到百度云盘

背景 由于个人项目预算有限&#xff0c;把mysql和应用程序都跑在同一台阿里云ECS机器上面&#xff0c;就在昨天(2023年12月21日) &#xff0c;服务器突然出现问题 进程全部挂掉了&#xff0c;服务器也无法重启&#xff0c;找工程师排查后发现是系统磁盘挂载出现了问题&#xf…

Ansible的脚本---Playbook剧本编写

playbook的组成部分 1、 tasks&#xff1a;任务 在目标主机上需要执行的操作。使用模块定义这些操作。每个任务都是一个模块的调用。 2、 variables&#xff1a;变量 用于存储和传递数据。类似于shell脚本中的变量。变量可以自定义。可以在playbook当中定义为全局变量&…

基于Vite+Vue3 给项目引入Axios

基于ViteVue3 给项目引入Axios,方便与后端进行通信。 系列文章指路&#x1f449; 系列文章-基于Vue3创建前端项目并引入、配置常用的库和工具类 文章目录 安装依赖新建src/config/config.js 用于存放常用配置进行简单封装解决跨域问题调用尝试 安装依赖 npm install axios …

VisualVM监控远程服务SpringBoot

1.启动参数 java -jar \ -Djava.rmi.server.hostname192.168.14.11 \ -Dcom.sun.management.jmxremote \ -Dcom.sun.management.jmxremote.port2622 \ -Dcom.sun.management.jmxremote.sslfalse \ -Dcom.sun.management.jmxremote.access.file/usr/jmxremote.access \ -Dcom.s…

PIL/Pillow

Abstract PIL(Python Imaging Library)是一个用于图像处理的 Python 库。它提供了广泛的功能&#xff0c;包括图像加载、保存、调整大小、裁剪、旋转、滤镜应用等。 由于 PIL 的开发停止在 2009 年&#xff0c;因此推荐使用其后续的维护版本 Pillow。Pillow 是一个兼容 PIL 接…

Springboot启动异常 OgnlException: sqlSelect [java.lang.NoSuchMethodError

完整的日志如下&#xff1a; Invocation of init method failed; nested exception is org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.BuilderException: Error evaluating expression ew ! null and ew.sqlSelect ! null. Cause…

不忍学弟学妹受苦受难!!!逐一讲解发动机原理实验报告(1)

固体火箭发动机侵蚀燃烧测试实验 经过了愉快迷糊——哦不瑟瑟发抖——哦不痛不欲生的两天&#xff0c;终于和小伙伴们协力完成了西北工业大学航天学院发动机原理实验报告。具体的实验指导书均可在本人博客资源站下载。 固体火箭发动机侵蚀燃烧测试实验&#xff0c;嗯哼—— 实…

MySQL 事务的ACID特性

MySQL事务是什么&#xff0c;它就是一组数据库的操作&#xff0c;是访问数据库的程序单元&#xff0c;事务中可能包含一个或者多个 SQL 语句。这些SQL 语句要么都执行、要么都不执行。我们知道&#xff0c;在MySQL 中&#xff0c;有不同的存储引擎&#xff0c;有的存储引擎比如…

c++学习笔记-提高篇-STL标准模板库3(stack容器、queue容器以及list容器)

目录 Stack容器 一、Stack容器介绍 二、stack常用接口 三、栈的示例 queue&#xff08;队列&#xff09;容器 一、queue容器介绍 二、queue常用接口 三、queue示例 list容器 一、list容器介绍 二、list常用接口及示例 &#xff08;一&#xff09;list构造函数 &am…

使用Swift Package Manager (SPM)实现xcframework分发

Swift Package Manager (SPM) 是苹果官方提供的用于管理 Swift 项目的依赖关系和构建过程的工具。它是一个集成在 Swift 编程语言中的包管理器&#xff0c;用于解决在开发过程中管理和构建包依赖项的需求。 1、上传xcframework.zip到服务端 压缩xcframeworks成一个zip包&…

【flink】状态清理策略(TTL)

flink的keyed state是有有效期(TTL)的&#xff0c;使用和说明在官网描述的篇幅也比较多&#xff0c;对于三种清理策略没有进行横向对比得很清晰。 全量快照清理(FULL_STATE_SCAN_SNAPSHOT)增量清理(INCREMENTAL_CLEANUP)rocksdb压缩清理(ROCKSDB_COMPACTION_FILTER) 注意&…

MySQL数据管理————外键

方式一&#xff1a;在创建表的时候&#xff0c;增加约束&#xff08;麻烦&#xff0c;比较复杂&#xff09; CREATE TABLE grade( gradeid INT(10) NOT NULL AUTO_INCREMENT COMMENT 年级id, gradename VARCHAR(50) NOT NULL COMMENT 年级名称, PRIMARY KEY(gradeid) )ENGINEI…

国图公考:公考常识题如何复习更高效?

公务员考试是许多人求职的首选之一&#xff0c;而公考常识题作为公务员考试的重要组成部分&#xff0c;对于考生来说具有很高的分值。在这一模块的复习中&#xff0c;有以下几点可以帮助考生提高学习效率&#xff0c;一起来看一下吧! 一、明确复习目标 了解自己在各个知识点上…

gitee版本回退本地和仓库的执行步骤(后悔药,无副作用,按说明书使用)

目录 1.本地回退 1.打开项目文件夹 3.回退到指定版本 4.选择回退模式并确认 5.本地回退成功 2.回退仓库版本 1.在git上面找到项目的提交记录 2.找到提交错误的版本​编辑 3.双击新页面这个版本进去 点击操作再点击revert​编辑 4.确认回退 ​5.仓库回退成功 在使用…

融资项目——代码生成器

public void GenCode(){// 1、创建代码生成器AutoGenerator mpg new AutoGenerator();// 2、全局配置GlobalConfig gc new GlobalConfig();String projectPath System.getProperty("user.dir");gc.setOutputDir(projectPath "/src/main/java");gc.setA…

The Cherno C++笔记02

目录 Part 06 How the C Compiler Works 1.编译过程 2.C并不关心文件 3.翻译单元&#xff08;Translation Unit&#xff09; 4. 实际用代码感受一下编译过程 4.1 预处理 4.1.1 预处理的本质 4.1.2 预处理后的.i文件 4.1.3 骚操作 4.2 .asm文件&#xff08;汇编语言源文…