当前位置: 首页 > news >正文

若依vue3.0表格的增删改查文件封装

一、因若依生成的文件没进行封装,维护起来比较麻烦。所以自己简单的进行封装了一下

        gitee代码(文件)地址:https://gitee.com/liu_yu_ting09/ruo_yi.git

二、封装的方法(下面绿色按钮进行全局封装一个JeecgListMixin.js文件)

三、文件目录

四、具体文件内容

  1、JeecgListMixin.js(按照自己的目录进行创建,我的文件目录在src/mixins/JeecgListMixin.js)

   JeecgListMixin.js文件代码如下:

import { ref } from "vue";
export const useCommonMixin = (additionalParams) => {///公共参数const { list, queryParams, registerModal,deleteOne,proxy,id,queryRef } = additionalParams; //传递过来的公共参数const loading = ref(false);//是否加载中const selectionRows = ref([]); //选中的数组,用于多选const selectedRowKeys = ref([]);//选中的key数组const dataSource = ref([]);//数据源const total = ref(0);//总条数function loadData(index){//加载数据loading.value = true;list(queryParams.value).then((res) => {loading.value = false;dataSource.value = res.rows;total.value = res.total;if(index ==1)proxy.$modal.msgSuccess("查询成功!");if(index ==2)proxy.$modal.msgSuccess("重置成功!");});}/** 新增按钮操作 */function handleAdd() {registerModal.value.add();}/** 修改按钮操作 */function handleUpdate(row) {registerModal.value.edit(row);}/** 搜索按钮操作 */function handleQuery(index) {queryParams.value.pageNum = 1;if(index ==1) return loadData(2);loadData(1);}// /** 一项删除按钮操作 */function handleDeleteOne(id) {proxy.$modal.confirm('是否确认删除这一项吗?').then(function () {return deleteOne(id);}).then(() => {loadData();proxy.$modal.msgSuccess("删除成功");}).catch(() => {});}// 选中事件触发function handleSelectionChange(selection) {selectionRows.value = selection;selectedRowKeys.value = selection.map((item) => item[id]);;}function handleDeleteBatch(index) {if (selectedRowKeys.value.length == 0) return  proxy.$modal.msgWarning("请选择需要删除的数据");;let ids = selectedRowKeysif(index ==1) ids = selectedRowKeys.value.join(','); //批量删除转化字符串转化proxy.$modal.confirm(`是否确认批量删除   ${selectedRowKeys.value.length}   条数据?`).then(function () {return deleteOne(ids.value);}).then(() => {loadData();proxy.$modal.msgSuccess("删除成功");}).catch(() => {});}function searchReset(){ //搜索重置proxy.resetForm(queryRef);handleQuery(1);}function handleExport(url,queryParams,name) { //导出 --参数 url 请求地址  queryParams 参数名  name 文件名称proxy.download(url,queryParams,name);}return {loading,dataSource,total,loadData,handleAdd,handleUpdate,selectionRows,selectedRowKeys,handleQuery,handleDeleteOne,handleSelectionChange,handleDeleteBatch,searchReset,handleExport};
};

  2、主页面文件(index文件下图:)

         

        index代码:

<template><div class="app-container"><el-row :gutter="20"><!--部门数据--><el-col :span="4" :xs="24"><div class="head-container"><el-inputv-model="deptName"placeholder="请输入部门名称"clearableprefix-icon="Search"style="margin-bottom: 20px"/></div><div class="head-container"><el-tree:data="deptOptions":props="{ label: 'label', children: 'children' }":expand-on-click-node="false":filter-node-method="filterNode"ref="deptTreeRef"node-key="id"highlight-currentdefault-expand-all@node-click="handleNodeClick"/></div></el-col><!--用户数据--><el-col :span="20" :xs="24"><el-form:model="queryParams"ref="queryRef":inline="true"v-show="showSearch"label-width="68px"><el-form-item label="用户名称" prop="userName"><el-inputv-model="queryParams.userName"placeholder="请输入用户名称"clearablestyle="width: 240px"@keyup.enter="handleQuery"/></el-form-item><el-form-item label="手机号码" prop="phonenumber"><el-inputv-model="queryParams.phonenumber"placeholder="请输入手机号码"clearablestyle="width: 240px"@keyup.enter="handleQuery"/></el-form-item><el-form-item label="状态" prop="status"><el-selectv-model="queryParams.status"placeholder="用户状态"clearablestyle="width: 240px"><el-optionv-for="dict in sys_normal_disable":key="dict.value":label="dict.label":value="dict.value"/></el-select></el-form-item><el-form-item><el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button><el-button icon="Refresh" @click="resetQuery">重置</el-button></el-form-item></el-form><el-row :gutter="10" class="mb8"><el-col :span="1.5"><el-buttontype="primary"plainicon="Plus"@click="handleAdd"v-hasPermi="['system:user:add']">新增</el-button></el-col><el-col :span="1.5"><el-buttontype="danger"plainicon="Delete":disabled="selectedRowKeys.length ==0"@click="handleDeleteBatch()"v-hasPermi="['system:user:remove']">批量删除</el-button></el-col><el-col :span="1.5"><el-buttontype="info"plainicon="Upload"@click="handleImport"v-hasPermi="['system:user:import']">导入</el-button></el-col><el-col :span="1.5"><el-buttontype="warning"plainicon="Download"@click="handleExport('system/user/export', queryParams,`user_${new Date().getTime()}.xlsx`)"v-hasPermi="['system:user:export']">导出</el-button></el-col><right-toolbarv-model:showSearch="showSearch"@queryTable="loadData":columns="columns"></right-toolbar></el-row><el-tablev-loading="loading":data="dataSource"@selection-change="handleSelectionChange"><el-table-column type="selection" width="50" align="center" /><el-table-columnlabel="用户编号"align="center"key="userId"prop="userId"v-if="columns[0].visible"/><el-table-columnlabel="用户名称"align="center"key="userName"prop="userName"v-if="columns[1].visible":show-overflow-tooltip="true"/><el-table-columnlabel="用户昵称"align="center"key="nickName"prop="nickName"v-if="columns[2].visible":show-overflow-tooltip="true"/><el-table-columnlabel="部门"align="center"key="deptName"prop="dept.deptName"v-if="columns[3].visible":show-overflow-tooltip="true"/><el-table-columnlabel="手机号码"align="center"key="phonenumber"prop="phonenumber"v-if="columns[4].visible"width="120"/><el-table-columnlabel="状态"align="center"key="status"v-if="columns[5].visible"><template #default="scope"><el-switchv-model="scope.row.status"active-value="0"inactive-value="1"@change="handleStatusChange(scope.row)"></el-switch></template></el-table-column><el-table-columnlabel="创建时间"align="center"prop="createTime"v-if="columns[6].visible"width="160"><template #default="scope"><span>{{ parseTime(scope.row.createTime) }}</span></template></el-table-column><el-table-columnlabel="操作"align="center"width="150"class-name="small-padding fixed-width"><template #default="scope"><el-tooltipcontent="修改"placement="top"v-if="scope.row.userId !== 1"><el-buttonlinktype="primary"icon="Edit"@click="handleUpdate(scope.row)"v-hasPermi="['system:user:edit']"></el-button></el-tooltip><el-tooltipcontent="删除"placement="top"v-if="scope.row.userId !== 1"><el-buttonlinktype="primary"icon="Delete"@click="handleDeleteOne(scope.row.userId)"v-hasPermi="['system:user:remove']"></el-button></el-tooltip><el-tooltipcontent="重置密码"placement="top"v-if="scope.row.userId !== 1"><el-buttonlinktype="primary"icon="Key"@click="handleResetPwd(scope.row)"v-hasPermi="['system:user:resetPwd']"></el-button></el-tooltip><el-tooltipcontent="分配角色"placement="top"v-if="scope.row.userId !== 1"><el-buttonlinktype="primary"icon="CircleCheck"@click="handleAuthRole(scope.row)"v-hasPermi="['system:user:edit']"></el-button></el-tooltip></template></el-table-column></el-table><paginationv-show="total > 0":total="total"v-model:page="queryParams.pageNum"v-model:limit="queryParams.pageSize"@pagination="loadData"/></el-col></el-row><!-- 添加或修改用户配置对话框 --><!-- 用户导入对话框 --><el-dialog:title="upload.title"v-model="upload.open"width="400px"append-to-body><el-uploadref="uploadRef":limit="1"accept=".xlsx, .xls":headers="upload.headers":action="upload.url + '?updateSupport=' + upload.updateSupport":disabled="upload.isUploading":on-progress="handleFileUploadProgress":on-success="handleFileSuccess":auto-upload="false"drag><el-icon class="el-icon--upload"><upload-filled /></el-icon><div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div><template #tip><div class="el-upload__tip text-center"><div class="el-upload__tip"><el-checkboxv-model="upload.updateSupport"/>是否更新已经存在的用户数据</div><span>仅允许导入xls、xlsx格式文件。</span><el-linktype="primary":underline="false"style="font-size: 12px; vertical-align: baseline"@click="importTemplate">下载模板</el-link></div></template></el-upload><template #footer><div class="dialog-footer"><el-button type="primary" @click="submitFileForm">确 定</el-button><el-button @click="upload.open = false">取 消</el-button></div></template></el-dialog><userModal ref="registerModal" @success="loadData" /><!-- 用户注册编辑对话框 --></div>
</template>
<script setup name="User">
import { getToken } from "@/utils/auth";
import {changeUserStatus,listUser,resetUserPwd,delUser,deptTreeSelect,
} from "./api/userApi";
const router = useRouter();
const { proxy } = getCurrentInstance();
const { sys_normal_disable, sys_user_sex } = proxy.useDict("sys_normal_disable","sys_user_sex"
);
import { useCommonMixin } from "@/mixins/JeecgListMixin.js"; //公共方法
import userModal from "./components/userModal.vue"; //公共方法
const registerModal = ref();
const showSearch = ref(true);
const deptName = ref("");
const deptOptions = ref(undefined);
/*** 用户导入参数 */
const upload = reactive({// 是否显示弹出层(用户导入)open: false,// 弹出层标题(用户导入)title: "",// 是否禁用上传isUploading: false,// 是否更新已经存在的用户数据updateSupport: 0,// 设置上传的请求头部headers: { Authorization: "Bearer " + getToken() },// 上传的地址url: import.meta.env.VITE_APP_BASE_API + "/system/user/importData",
});
// 列显隐信息
const columns = ref([{ key: 0, label: `用户编号`, visible: true },{ key: 1, label: `用户名称`, visible: true },{ key: 2, label: `用户昵称`, visible: true },{ key: 3, label: `部门`, visible: true },{ key: 4, label: `手机号码`, visible: true },{ key: 5, label: `状态`, visible: true },{ key: 6, label: `创建时间`, visible: true },
]);const data = reactive({queryParams: {pageNum: 1,pageSize: 10,userName: undefined,phonenumber: undefined,status: undefined,deptId: undefined,},
});
const { queryParams } = toRefs(data);
// 根据需要传入额外参数(传递给JeecgListMixin页面的文件)
const additionalParams = {list: listUser,//查询用户列表queryParams: queryParams,//查询参数registerModal:registerModal,//用户注册编辑对话框deleteOne:delUser,//删除用户接口proxy:proxy,//公共方法id: "userId",//主键idqueryRef:'queryRef',//查询框ref
}
const { loading, dataSource, total, loadData, handleAdd,handleUpdate,handleQuery,handleDeleteOne,handleDeleteBatch,handleSelectionChange,searchReset,handleExport,selectionRows,selectedRowKeys} =useCommonMixin(additionalParams);
/** 通过条件过滤节点  */
const filterNode = (value, data) => {if (!value) return true;return data.label.indexOf(value) !== -1;
};
/** 根据名称筛选部门树 */
watch(deptName, (val) => {proxy.$refs["deptTreeRef"].filter(val);
});
/** 查询部门下拉树结构 */
function getDeptTree() {deptTreeSelect().then((response) => {deptOptions.value = response.data;});
}
/** 节点单击事件 */
function handleNodeClick(data) {queryParams.value.deptId = data.id;handleQuery();
}
/** 重置按钮操作 */
function resetQuery() {queryParams.value.deptId = undefined;proxy.$refs.deptTreeRef.setCurrentKey(null);searchReset();
}
/** 用户状态修改  */
function handleStatusChange(row) {let text = row.status === "0" ? "启用" : "停用";proxy.$modal.confirm('确认要"' + text + '""' + row.userName + '"用户吗?').then(function () {return changeUserStatus(row.userId, row.status);}).then(() => {proxy.$modal.msgSuccess(text + "成功");}).catch(function () {row.status = row.status === "0" ? "1" : "0";});
}
/** 更多操作 */
// function handleCommand(command, row) {
//   switch (command) {
//     case "handleResetPwd":
//       handleResetPwd(row);
//       break;
//     case "handleAuthRole":
//       handleAuthRole(row);
//       break;
//     default:
//       break;
//   }
// }/** 跳转角色分配 */
function handleAuthRole(row) {const userId = row.userId;router.push("/system/user-auth/role/" + userId);
}/** 重置密码按钮操作 */
function handleResetPwd(row) {proxy.$prompt('请输入"' + row.userName + '"的新密码', "提示", {confirmButtonText: "确定",cancelButtonText: "取消",closeOnClickModal: false,inputPattern: /^.{5,20}$/,inputErrorMessage: "用户密码长度必须介于 5 和 20 之间",inputValidator: (value) => {if (/<|>|"|'|\||\\/.test(value)) {return "不能包含非法字符:< > \" ' \\\ |";}},}).then(({ value }) => {resetUserPwd(row.userId, value).then((response) => {proxy.$modal.msgSuccess("修改成功,新密码是:" + value);});}).catch(() => {});
}
/** 导入按钮操作 */
function handleImport() {upload.title = "用户导入";upload.open = true;
}
/** 下载模板操作 */
function importTemplate() {proxy.download("system/user/importTemplate",{},`user_template_${new Date().getTime()}.xlsx`);
}
/**文件上传中处理 */
const handleFileUploadProgress = (event, file, fileList) => {upload.isUploading = true;
};/** 文件上传成功处理 */
const handleFileSuccess = (response, file, fileList) => {upload.open = false;upload.isUploading = false;proxy.$refs["uploadRef"].handleRemove(file);proxy.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +response.msg +"</div>","导入结果",{ dangerouslyUseHTMLString: true });loadData();
};
/** 提交上传文件 */
function submitFileForm() {proxy.$refs["uploadRef"].submit();
}
getDeptTree();
loadData();
</script>

3、api(接口文件)

具体代码:

        

import request from '@/utils/request'
import { parseStrEmpty } from "@/utils/ruoyi";// 查询用户列表
export function listUser(query) {return request({url: '/system/user/list',method: 'get',params: query})
}// 查询用户详细
export function getUser(userId) {return request({url: '/system/user/' + parseStrEmpty(userId),method: 'get'})
}// 新增用户
export function addUser(data) {return request({url: '/system/user',method: 'post',data: data})
}// 修改用户
export function updateUser(data) {return request({url: '/system/user',method: 'put',data: data})
}
export function saveOrUpdate(data,isUpdate) { // 新增-编辑const method = isUpdate ? 'put' : 'post';return request({url: '/system/user',method: method,data: data})
}
// 删除用户
export function delUser(userId) {return request({url: '/system/user/' + userId,method: 'delete'})
}// 用户密码重置
export function resetUserPwd(userId, password) {const data = {userId,password}return request({url: '/system/user/resetPwd',method: 'put',data: data})
}// 用户状态修改
export function changeUserStatus(userId, status) {const data = {userId,status}return request({url: '/system/user/changeStatus',method: 'put',data: data})
}// 查询用户个人信息
export function getUserProfile() {return request({url: '/system/user/profile',method: 'get'})
}// 修改用户个人信息
export function updateUserProfile(data) {return request({url: '/system/user/profile',method: 'put',data: data})
}// 用户密码重置
export function updateUserPwd(oldPassword, newPassword) {const data = {oldPassword,newPassword}return request({url: '/system/user/profile/updatePwd',method: 'put',params: data})
}// 用户头像上传
export function uploadAvatar(data) {return request({url: '/system/user/profile/avatar',method: 'post',headers: { 'Content-Type': 'application/x-www-form-urlencoded' },data: data})
}// 查询授权角色
export function getAuthRole(userId) {return request({url: '/system/user/authRole/' + userId,method: 'get'})
}// 保存授权角色
export function updateAuthRole(data) {return request({url: '/system/user/authRole',method: 'put',params: data})
}// 查询部门下拉树结构
export function deptTreeSelect() {return request({url: '/system/user/deptTree',method: 'get'})
}

4、新增编辑弹窗文件

具体代码

1、userModal.vue文件

<template><el-dialog v-model="visible"  :title="title" :width="width"><div  v-if="visible"><userForm  ref="registerForm" @ok="submitCallback" @onLose="onLose"  /></div><template #footer>  <!-- 按钮 --><div class="dialog-footer"><el-button type="primary" @click="handleOk" :disabled="disabled">确 定</el-button><el-button @click="handleCancel">取 消</el-button></div></template></el-dialog>
</template>
<script setup >
import { ref, nextTick } from "vue";
import userForm from "./userForm.vue";
const title = ref("");
const width = ref('800');
const visible = ref(false);
const disabled = ref(false);
const registerForm = ref();
const emit = defineEmits(["register", "success"]);
/*** 新增*/
function add() {title.value = "新增";visible.value = true;nextTick(() => {registerForm.value.add();});
}
/*** 编辑**/
function edit(record) {title.value = "编辑";visible.value = true;nextTick(() => {registerForm.value.edit(record);});}
/*** 确定按钮点击事件*/
function handleOk() {disabled.value = true;registerForm.value.submitForm();
}
function onLose() {disabled.value = false;
}
/*** form保存回调事件*/
function submitCallback() {handleCancel();onLose();emit("success");
}
/*** 取消按钮回调事件*/
function handleCancel() {visible.value = false;
}
defineExpose({add,edit,
});
</script>

2、userForm.vue文件

<template><el-form :model="formData" :rules="rules" :disabled="disabled" ref="formRef" label-width="80px"><el-row><el-col :span="12"><el-form-item label="用户昵称" prop="nickName"><el-inputv-model="formData.nickName"placeholder="请输入用户昵称"maxlength="30"/></el-form-item></el-col><el-col :span="12"><el-form-item label="归属部门" prop="deptId"><el-tree-selectv-model="formData.deptId":data="deptOptions":props="{ value: 'id', label: 'label', children: 'children' }"value-key="id"placeholder="请选择归属部门"check-strictly/></el-form-item></el-col></el-row><el-row><el-col :span="12"><el-form-item label="手机号码" prop="phonenumber"><el-inputv-model="formData.phonenumber"placeholder="请输入手机号码"maxlength="11"/></el-form-item></el-col><el-col :span="12"><el-form-item label="邮箱" prop="email"><el-inputv-model="formData.email"placeholder="请输入邮箱"maxlength="50"/></el-form-item></el-col></el-row><el-row><el-col :span="12"><el-form-itemv-if="formData.userId == undefined"label="用户名称"prop="userName"><el-inputv-model="formData.userName"placeholder="请输入用户名称"maxlength="30"/></el-form-item></el-col><el-col :span="12"><el-form-itemv-if="formData.userId == undefined"label="用户密码"prop="password"><el-inputv-model="formData.password"placeholder="请输入用户密码"type="password"maxlength="20"show-password/></el-form-item></el-col></el-row><el-row><el-col :span="12"><el-form-item label="用户性别"><el-select v-model="formData.sex" placeholder="请选择"><el-optionv-for="dict in sys_user_sex":key="dict.value":label="dict.label":value="dict.value"></el-option></el-select></el-form-item></el-col><el-col :span="12"><el-form-item label="状态"><el-radio-group v-model="formData.status"><el-radiov-for="dict in sys_normal_disable":key="dict.value":value="dict.value">{{ dict.label }}</el-radio></el-radio-group></el-form-item></el-col></el-row><el-row><el-col :span="12"><el-form-item label="岗位"><el-select v-model="formData.postIds" multiple placeholder="请选择"><el-optionv-for="item in postOptions":key="item.postId":label="item.postName":value="item.postId":disabled="item.status == 1"></el-option></el-select></el-form-item></el-col><el-col :span="12"><el-form-item label="角色"><el-select v-model="formData.roleIds" multiple placeholder="请选择"><el-optionv-for="item in roleOptions":key="item.roleId":label="item.roleName":value="item.roleId":disabled="item.status == 1"></el-option></el-select></el-form-item></el-col></el-row><el-row><el-col :span="24"><el-form-item label="备注"><el-inputv-model="formData.remark"type="textarea"placeholder="请输入内容"></el-input></el-form-item></el-col></el-row></el-form>
</template>
<script setup>
import { ref, reactive, nextTick } from "vue";
const { proxy } = getCurrentInstance();
import {saveOrUpdate,deptTreeSelect,getUser
} from "../api/userApi";
const { sys_normal_disable, sys_user_sex } = proxy.useDict("sys_normal_disable","sys_user_sex"
);
const emit = defineEmits(["register", "ok"]);
const formRef = ref();
const deptOptions = ref(undefined);
const postOptions = ref([]);
const disabled = ref(false);
const roleOptions = ref([]);
const formData = reactive({userId: undefined,deptId: undefined,userName: undefined,nickName: undefined,password: undefined,phonenumber: undefined,email: undefined,sex: undefined,status: "0",remark: undefined,postIds: [],roleIds: [],
});
//表单验证
const rules = {userName: [{ required: true, message: "用户名称不能为空", trigger: "blur" },{min: 2,max: 20,message: "用户名称长度必须介于 2 和 20 之间",trigger: "blur",},],nickName: [{ required: true, message: "用户昵称不能为空", trigger: "blur" }],password: [{ required: true, message: "用户密码不能为空", trigger: "blur" },{min: 5,max: 20,message: "用户密码长度必须介于 5 和 20 之间",trigger: "blur",},{pattern: /^[^<>"'|\\]+$/,message: "不能包含非法字符:< > \" ' \\\ |",trigger: "blur",},],email: [{type: "email",message: "请输入正确的邮箱地址",trigger: ["blur", "change"],},],phonenumber: [{pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,message: "请输入正确的手机号码",trigger: "blur",},],
};/*** 新增*/
function add() {edit({});
}
/*** 编辑*/
function edit(record) {nextTick(() => {//赋值表单数据Object.assign(formData, record);});console.log(formData);proxy.resetForm("formRef");
}
/*** 提交数据*/
async function submitForm() {disabled.value = true;proxy.$refs["formRef"].validate((valid) => {if (valid) {let model = { ...formData };const isUpdate = formData.createTime;saveOrUpdate(model,isUpdate).then((res) => {disabled.value = false;if (res.code ==200) {proxy.$modal.msgSuccess(res.msg);emit("ok");} else {emit("onLose");proxy.$modal.msgError(res.msg);}});}else{disabled.value = false;emit("onLose");} });
}
/** 查询部门下拉树结构 */
function getDeptTree() {deptTreeSelect().then((response) => { //部门下拉树deptOptions.value = response.data;});getUser().then(response => { //岗位角色postOptions.value = response.posts;roleOptions.value = response.roles;});
} getDeptTree();
defineExpose({add,edit,submitForm,
});
</script>

文档:使用 useCommonMixin 进行用户管理

概述

useCommonMixin 是一个 Vue 组合式 API,用于简化用户管理界面的操作,包括数据加载、用户添加、修改、删除和导出功能。该混合器接受一组公共参数,提供了一些基本的方法和状态管理。

参数

useCommonMixin 接受以下参数:

  • list: 查询用户列表的方法。
  • queryParams: 查询参数的响应式对象。
  • registerModal: 用户注册/编辑对话框的引用。
  • deleteOne: 删除用户的 API 接口。
  • proxy: 公共方法的引用。
  • id: 主键 ID 字段名。
  • queryRef: 查询框的引用。

返回值

该混合器返回一个对象,包含以下属性和方法:

状态管理

  • loading: 布尔值,表示数据是否在加载中。
  • dataSource: 用户数据源,响应式数组。
  • total: 用户总数,响应式数值。
  • selectionRows: 当前选中的用户数组。
  • selectedRowKeys: 当前选中的用户 ID 数组。

方法

  • loadData(index): 加载用户数据,并根据 index 显示成功消息。
  • handleAdd(): 打开用户添加对话框。
  • handleUpdate(row): 打开用户编辑对话框,传入待编辑的行数据。
  • handleQuery(index): 执行查询操作,重置页码并调用 loadData
  • handleDeleteOne(id): 确认并删除单个用户。
  • handleSelectionChange(selection): 更新选中的用户数组和 ID。
  • handleDeleteBatch(index): 确认并删除选中的多个用户。
  • searchReset(): 重置搜索表单并重新加载数据。
  • handleExport(url, queryParams, name): 导出用户数据。

使用示例

在 Vue 组件中引入并使用该混合器:

 

javascriptCopy Code

import { useCommonMixin } from './jeecglistMixin'; const additionalParams = { list: listUser, queryParams: queryParams, registerModal: registerModal, deleteOne: delUser, proxy: proxy, id: 'userId', queryRef: 'queryRef', }; const { loading, dataSource, total, loadData, handleAdd, handleUpdate, handleQuery, handleDeleteOne, handleDeleteBatch, handleSelectionChange, searchReset, handleExport, selectionRows, selectedRowKeys, } = useCommonMixin(additionalParams);

注意事项

确保传入的 queryParamsregisterModal 是响应式对象,且 listdeleteOne 是可用的 API 方法。

总结

useCommonMixin 提供了一套完整的用户管理功能,帮助开发者轻松实现常见的 CRUD 操作。通过合理传递参数,可以快速构建出高效、用户友好的管理界面。

相关文章:

若依vue3.0表格的增删改查文件封装

一、因若依生成的文件没进行封装&#xff0c;维护起来比较麻烦。所以自己简单的进行封装了一下 gitee代码&#xff08;文件&#xff09;地址&#xff1a;https://gitee.com/liu_yu_ting09/ruo_yi.git 二、封装的方法&#xff08;下面绿色按钮进行全局封装一个JeecgListMixin.js…...

【已解决】如何使用JAVA 语言实现二分查找-二分搜索折半查找【算法】手把手学会二分查找【数据结构与算法】

文章目录 前言任务描述编程要求 输出样例:未查找到11元素&#xff01; 二、代码实现总结理解不了考试的时候直接背下来就好了。 前言 [TOC]二分搜索 任务描述 折半查找&#xff08;二分搜索&#xff09; 设a[low..high]是当前的查找区间&#xff0c;首先确定该区间的中点位置…...

ERROR 1524 (HY000): Plugin ‘mysql_native_password‘ is not loaded

你遇到的错误是由于 MySQL 版本不再默认支持 mysql_native_password 认证插件导致的。从 MySQL 8.0 开始&#xff0c;默认的认证插件是 caching_sha2_password&#xff0c;而不是 mysql_native_password。 解释&#xff1a; 错误 ERROR 1524 (HY000): Plugin mysql_native_pa…...

.NET 6.0 WebAPI 使用JWT生成Token的验证授权

1.引入相关程序包JwtBearer注意版本: 2.配置文件appsettings.json写相关配置参数(也可不写&#xff0c;写在程序里面&#xff0c;数据库读取也是一样的) , //JWT加密"JWTToken": {"SecretKey": "jsaduwqe6asdjewejdue7dfmsdfu0sdfmwmsd8wfsd6",…...

M9410A VXT PXI 矢量收发信机,300/600/1200MHz带宽

M9410A PXI 矢量收发信机 -300/600/1200MHz带宽- M9410A VXT PXI 矢量收发信机&#xff0c;300/600/1200MHz带宽支持 5G 的 PXI 矢量收发信机&#xff08;VXT&#xff09;是一个 2 插槽模块&#xff0c;具有 1.2 GHz 的瞬时带宽 主要特点 Keysight M9410A VXT PXIe 矢量收发…...

用工厂模式演示springboot三种注入方式 | @Autowired

背景&#xff1a;看了个demo工厂模式&#xff0c;示例代码的工厂类是new出来的&#xff0c;但是实际项目中都是用springboot框架、bean都是会给容器管理的&#xff0c;所以在思考这个工厂类要交给springboot托管要怎么改。以下是总结笔记 依赖注入 1.工厂类用new实现2.工厂类用…...

es查询语法

查询关键词的含义&#xff1a; match: 用于进行全文搜索&#xff0c;分析查询文本并与倒排索引中的词项进行匹配。 term: 精确匹配&#xff0c;适用于非分析字段&#xff0c;如 keyword 类型。用于查找字段值完全相等的文档。 bool: 组合多个查询条件。可以使用 must&#xf…...

LabVIEW提高开发效率技巧----合理使用数据流与内存管理

理使用数据流和内存管理是LabVIEW开发中提高性能和稳定性的关键&#xff0c;特别是在处理大数据或高频率信号时&#xff0c;优化可以避免内存消耗过大、程序卡顿甚至崩溃。 1. 使用 Shift Register 进行内存管理 Shift Register&#xff08;移位寄存器&#xff09; 是 LabVIE…...

如何在 ECharts 中设置轴标签

在 ECharts 中&#xff0c;轴标签&#xff08;Axis Label&#xff09;是指 X 轴或 Y 轴上的刻度标签&#xff0c;用于显示轴上的数据值或分类名称。你可以通过配置 xAxis&#xff08;X 轴&#xff09;或 yAxis&#xff08;Y 轴&#xff09;的 axisLabel 属性来设置轴标签的样式…...

怎么用gitee做一个图片仓库,在md文档中用这个图片网络地址,然后显示图片

痛因&#xff1a;我为什么要这样做&#xff0c;呃&#xff0c;我一开始图片都是存本地地址的&#xff0c;放在和这个md文档同级的assets文件夹下面&#xff0c;这样子确实当时很方便&#xff0c;复制粘贴什么也不用管&#xff0c;但是想把这个文档分享给别的人的时候&#xff0…...

Thinkphp(TP)

1.远程命令执行 /index.php?sindex/think\app/invokefunction&functioncall_user_func_array&vars[0]system&vars[1][]whoami 2.远程代码执行 /index.php?sindex/think\app/invokefunction&functioncall_user_func_array&vars[0]phpinfo&vars[1][]…...

【艾思科蓝】前端框架巅峰对决:React、Vue与Angular的全面解析与实战指南

【JPCS独立出版】​第三届能源与动力工程国际学术会议&#xff08;EPE 2024&#xff09;_艾思科蓝_学术一站式服务平台 更多学术会议请看&#xff1a;https://ais.cn/u/nuyAF3 引言 在快速发展的前端技术领域&#xff0c;选择合适的框架或库对于项目的成功至关重要。React、Vu…...

IT行业的未来:技术变革与创新的持续推动

IT行业的未来&#xff1a;技术变革与创新的持续推动 随着数字化进程的不断加速&#xff0c;信息技术&#xff08;IT&#xff09;行业正迈入一个快速变革的时代。新兴技术如人工智能&#xff08;AI&#xff09;、5G、物联网&#xff08;IoT&#xff09;和区块链&#xff0c;正在…...

Python PDF转图片自定义输出

PDF转图片自定义输出 一、引入必要库 1 2import fitz import os也可以检查一下版本就是了&#xff1a;print(fitz.__doc__) 上一篇文章已经介绍过要使用的库&#xff0c;和写代码要用到的思路了。我们直接开始&#xff1a; 二、找到文件 首先是我们要获取用户的输入&#x…...

Git 常用操作命令说明

Git 常用操作命令 1. 初始化和克隆仓库 1.1 初始化仓库 git init在当前目录初始化一个新的 Git 仓库。 1.2 克隆仓库 git clone <repository-url>从远程仓库克隆项目到本地。 示例&#xff1a; git clone https://github.com/user/repo.git2. 查看状态和日志 2.1…...

自学前端的正确姿势是...

师傅带进门&#xff0c;修行在个人。 在前端自学成才的道路上&#xff0c;有些人走的很快&#xff0c;有些人却举步维艰。 为什么会这样子呢&#xff1f;因为他们没有掌握自学前端的正确姿势。 在介绍应该要怎样自学前端之前&#xff0c;首先来看下&#xff0c;自学前端容易…...

C/C++语言基础--C++构造函数、析构函数、深拷贝与浅拷贝等等相关知识讲解

本专栏目的 更新C/C的基础语法&#xff0c;包括C的一些新特性 前言 周末休息了&#xff0c;没有更新&#xff0c;请大家见谅哈&#xff1b;构造函数、析构函数可以说便随着C每一个程序&#xff0c;故学构造函数、析构函数是必要的&#xff1b;C语言后面也会继续更新知识点&am…...

json格式互相转换

您提供的字符串已经是一个JSON格式的字符串&#xff0c;但是JSON标准要求键名必须用双引号括起来&#xff0c;而不是单引号。因此&#xff0c;您需要将字符串中的单引号替换为双引号。以下是转换后的JSON字符串&#xff1a; {"图片描述": "高速公路上发生了严重…...

Linux下共享内存详解

共享内存是Linux中一种高效的进程间通信&#xff08;IPC&#xff09;方式&#xff0c;它允许多个进程共享同一段内存&#xff0c;从而实现数据的快速传递。共享内存通常比其他IPC机制&#xff08;如管道或消息队列&#xff09;更快&#xff0c;因为数据直接存储在内存中&#x…...

MySQL篇(管理工具)

目录 一、系统数据库 二、常用工具 1. mysql 2. mysqladmin 3. mysqlbinlog 4. mysqlshow 5. mysqldump 6. mysqlimport/source 6.1 mysqlimport 6.2 source 一、系统数据库 MySQL数据库安装完成后&#xff0c;自带了一下四个数据库&#xff0c;具体作用如下&#xf…...

redis学习笔记(六)

redis每种数据结构的应用场景 1. 字符串 (String) 应用场景 &#xff1a; 缓存&#xff1a;存储频繁访问的数据&#xff0c;如网页缓存、会话信息等。计数器&#xff1a;实现统计和计数功能&#xff0c;如访问计数、统计数据等。键值存储&#xff1a;简单的键值对存储&#xf…...

spring与springmvc整合

文章目录 spring与springmvc整合重复创建bean容器关系获取spring容器上下文 spring与springmvc整合 在项目中使用springmvc的时候&#xff0c;由于spring和springmvc是同源的&#xff0c;有时候大家会把所有的配置都扔到springmvc的配置文件中&#xff0c;而不去区分spring和s…...

如何使用Optuna在PyTorch中进行超参数优化

所有神经网络在训练过程中都需要选择超参数,而这些超参数对收敛速度和最终性能有着非常显著的影响。 这些超参数需要特别调整,以充分发挥模型的潜力。超参数调优过程是神经网络训练中不可或缺的一部分,某种程度上,它是一个主要基于梯度优化问题中的“无梯度”部分。 在这…...

2.Spring-容器-注入

注册&#xff1a;将组件放入容器中&#xff1b; 注入&#xff1a;让容器按需进行操作&#xff1b; 一、Autowired&#xff1a;自动注入组件 原理&#xff1a;Spring调用容器的getBean 二、Qualifier 精确指定 精确指定&#xff1a;如果容器中组件存在多个&#xff0c;则使用…...

在uboot中添加自定义命令

有时候为了方便测试&#xff0c;我们需要在Uboot中添加自己的命令&#xff0c;这时可以通过下面的步骤实现&#xff1a; 1、在common目录下添加自己的命令文件“cmd_命令名.c”&#xff0c;如cmd_test.c&#xff0c;内容如下&#xff08;参考模版&#xff09;&#xff1a; …...

AngularJS 模块

AngularJS 模块 AngularJS,作为一个强大且灵活的前端框架,其核心特性之一就是模块化。模块在AngularJS中扮演着至关重要的角色,它们是组织代码的主要方式,使得开发者能够创建可复用、可维护且易于测试的代码结构。本文将深入探讨AngularJS模块的概念、用途、创建方式以及最…...

[yotroy.cool] MGT 388 - Finance for Engineers - notes 笔记

个人博客https://www.yotroy.cool/,感谢关注~ 图片资源可能显示不全,请前往博客查看哦! ============================================================ Lecture 1 What is Accounting? The process of identifying, measuring and communicating economic informati…...

2024年9月python二级易错题和难题大全(附详细解析)(三)

2024年9月python二级易错题和难题大全(附详细解析)(三) 第1题第2题第3题第4题第5题第6题第7题第8题第9题第10题第11题第12题第13题第14题第15题第16题第17题第18题第19题第20题第1题 1、以下程序的输出结果是() L1 = [4, 5, 6, 8].reverse() print(L1)A、[8, 6, 5, 4]&…...

【LLM多模态】Animatediff文生视频大模型

note AnimateDiff框架&#xff1a;核心是一个可插拔的运动模块&#xff0c;它可以从真实世界视频中学习通用的运动先验&#xff0c;并与任何基于相同基础T2I的个性化模型集成&#xff0c;以生成动画。训练策略&#xff1a;AnimateDiff的训练包括三个阶段&#xff1a; 领域适配…...

PDB数据库中蛋白质结构文件数据格式

在PDB(Protein Data Bank)数据库中,蛋白质结构文件通常以两种主要格式存储:.pdb(PDB格式)和 .cif(CIF格式,Crystallographic Information File)。这两种文件格式记录了蛋白质的三维结构坐标信息以及实验数据,但它们的表达方式和用途有所不同。 1. PDB数据库中的结构…...