vue2+element 组件封装使用

embedded/2024/10/18 10:26:44/

1.图片上传组件

使用

  <el-descriptions-item label="附件图片" :span="3"><ImageUpload v-model="picUrl" :fileSize="0"  @getImg="getImg"></ImageUpload></el-descriptions-item>
    // 图片getImg(val){console.log(this.imgList,val)this.imgList = val},

 imageUpload组件封装

<template><div class="component-upload-image"><el-uploadmultiple:action="uploadImgUrl"list-type="picture-card":on-success="handleUploadSuccess":before-upload="handleBeforeUpload":limit="limit":on-error="handleUploadError":on-exceed="handleExceed"ref="imageUpload":on-remove="handleDelete":show-file-list="true":headers="headers":file-list="fileList":on-preview="handlePictureCardPreview":class="{hide: this.fileList.length >= this.limit}"><i class="el-icon-plus"></i></el-upload><!-- 上传提示 --><div class="el-upload__tip" slot="tip" v-if="showTip">请上传<template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template><template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>的文件</div><el-dialog:visible.sync="dialogVisible"title="预览"width="800"append-to-body><img:src="dialogImageUrl"style="display: block; max-width: 100%; margin: 0 auto"/></el-dialog></div>
</template><script>
import { getToken } from "@/utils/auth";
import { listByIds, delOss } from "@/api/system/oss";export default {props: {value: [String, Object, Array],// 图片数量限制limit: {type: Number,default: 5,},// 大小限制(MB)fileSize: {type: Number,default: 5,},// 文件类型, 例如['png', 'jpg', 'jpeg']fileType: {type: Array,default: () => ["png", "jpg", "jpeg"],},// 是否显示提示isShowTip: {type: Boolean,default: true}},data() {return {number: 0,uploadList: [],dialogImageUrl: "",dialogVisible: false,hideUpload: false,baseUrl: process.env.VUE_APP_BASE_API,uploadImgUrl: process.env.VUE_APP_BASE_API + "/system/oss/upload", // 上传的图片服务器地址headers: {Authorization: "Bearer " + getToken(),},fileList: []};},watch: {value: {async handler(val) {if (val) {// 首先将值转为数组let list;if (Array.isArray(val)) {list = val;} else {await listByIds(val).then(res => {list = res.data;this.$emit("getImg", list);})}// 然后将数组转为对象数组this.fileList = list.map(item => {// 此处name使用ossId 防止删除出现重名item = { name: item.ossId, url: item.url, ossId: item.ossId };return item;});} else {this.fileList = [];return [];}},deep: true,immediate: true}},computed: {// 是否显示提示showTip() {return this.isShowTip && (this.fileType || this.fileSize);},},methods: {// 上传前loading加载handleBeforeUpload(file) {let isImg = false;if (this.fileType.length) {let fileExtension = "";if (file.name.lastIndexOf(".") > -1) {fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);}isImg = this.fileType.some((type) => {if (file.type.indexOf(type) > -1) return true;if (fileExtension && fileExtension.indexOf(type) > -1) return true;return false;});} else {isImg = file.type.indexOf("image") > -1;}if (!isImg) {this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join("/")}图片格式文件!`);return false;}if (this.fileSize) {const isLt = file.size / 1024 / 1024 < this.fileSize;if (!isLt) {this.$modal.msgError(`上传头像图片大小不能超过 ${this.fileSize} MB!`);return false;}}this.$modal.loading("正在上传图片,请稍候...");this.number++;},// 文件个数超出handleExceed() {this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);},// 上传成功回调handleUploadSuccess(res, file) {if (res.code === 200) {this.uploadList.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId });this.uploadedSuccessfully();} else {this.number--;this.$modal.closeLoading();this.$modal.msgError(res.msg);this.$refs.imageUpload.handleRemove(file);this.uploadedSuccessfully();}},// 删除图片handleDelete(file) {const findex = this.fileList.map(f => f.name).indexOf(file.name);if(findex > -1) {let ossId = this.fileList[findex].ossId;// delOss(ossId);this.fileList.splice(findex, 1);this.$emit("input", this.listToString(this.fileList));}},// 上传失败handleUploadError(res) {this.$modal.msgError("上传图片失败,请重试");this.$modal.closeLoading();},// 上传结束处理uploadedSuccessfully() {if (this.number > 0 && this.uploadList.length === this.number) {this.fileList = this.fileList.concat(this.uploadList);this.uploadList = [];this.number = 0;this.$emit("input", this.listToString(this.fileList));this.$modal.closeLoading();}},// 预览handlePictureCardPreview(file) {this.dialogImageUrl = file.url;this.dialogVisible = true;},// 对象转成指定字符串分隔listToString(list, separator) {let strs = "";separator = separator || ",";for (let i in list) {if (list[i].ossId) {strs += list[i].ossId + separator;}}return strs != "" ? strs.substr(0, strs.length - 1) : "";}}
};
</script>
<style scoped lang="scss">
// .el-upload--picture-card 控制加号部分
::v-deep.hide .el-upload--picture-card {display: none;
}
// 去掉动画效果
::v-deep .el-list-enter-active,
::v-deep .el-list-leave-active {transition: all 0s;
}::v-deep .el-list-enter, .el-list-leave-active {opacity: 0;transform: translateY(0);
}
</style>

2.图片回显组件

使用

 <ImagePreview:src="form.picUrl":width="150":height="150"></ImagePreview>

imagePreview组件封装

<template><div><el-image v-for="(item,index) in realSrcList" :key="index":src="`${item}`"fit="cover":style="`width:${realWidth};height:${realHeight};`":preview-src-list="realSrcList"><div slot="error" class="image-slot"><i class="el-icon-picture-outline"></i></div></el-image></div></template><script>export default {name: "ImagePreview",props: {src: {type: String,default: ""},width: {type: [Number, String],default: ""},height: {type: [Number, String],default: ""}},computed: {realSrc() {if (!this.src) {return;}let real_src = this.src.split(",")[0];return real_src;},realSrcList() {if (!this.src) {return;}let real_src_list = this.src.split(",");let srcList = [];real_src_list.forEach(item => {return srcList.push(item);});return srcList;},realWidth() {return typeof this.width == "string" ? this.width : `${this.width}px`;},realHeight() {return typeof this.height == "string" ? this.height : `${this.height}px`;}},
};
</script><style lang="scss" scoped>
.el-image {border-radius: 5px;background-color: #ebeef5;box-shadow: 0 0 5px 1px #ccc;::v-deep .el-image__inner {transition: all 0.3s;cursor: pointer;&:hover {transform: scale(1.2);}}::v-deep .image-slot {display: flex;justify-content: center;align-items: center;width: 100%;height: 100%;color: #909399;font-size: 30px;}
}
</style>

3.文件上传组件

使用

  <el-descriptions-item label="附件文件" :span="3"><FileUpload v-model="fileIds" :fileSize="0"  @getfile="getfile"></FileUpload></el-descriptions-item>
 // 文件列表getfile(val) {this.fileList = val;},

fileUpload组件的封装

<template><div class="upload-file"><el-uploadv-if="isUpload"multiple:action="uploadFileUrl":before-upload="handleBeforeUpload":file-list="fileList":limit="limit":on-error="handleUploadError":on-exceed="handleExceed":on-success="handleUploadSuccess":show-file-list="false":headers="headers"class="upload-file-uploader"ref="fileUpload"><!-- 上传按钮 --><el-button size="mini" type="primary">选取文件</el-button><!-- 上传提示 --><div class="el-upload__tip" slot="tip" v-if="showTip">请上传<template v-if="fileSize">大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b></template><template v-if="fileType">格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b></template>的文件</div></el-upload><!-- 文件列表 --><transition-groupclass="upload-file-list el-upload-list el-upload-list--text"name="el-fade-in-linear"tag="ul"v-if="isFileList"><li:key="file.url"class="el-upload-list__item ele-upload-list__item-content"style="padding: 0 4px"v-for="(file, index) in fileList"><el-link :href="`${file.url}`" :underline="false" target="_blank"><span class="el-icon-document"> {{ getFileName(file.name) }} </span></el-link><div class="ele-upload-list__item-content-action" v-if="isUpload"><el-link :underline="false" @click="handleDelete(index)" type="danger">删除</el-link></div></li></transition-group></div>
</template><script>
import { getToken } from "@/utils/auth";
import { listByIds, delOss } from "@/api/system/oss";export default {name: "FileUpload",props: {// 值value: [String, Object, Array],// 数量限制limit: {type: Number,default: 5,},// 大小限制(MB)fileSize: {type: Number,default: 5,},// 文件类型, 例如['png', 'jpg', 'jpeg']fileType: {type: Array | Boolean,// default: () => ["doc", "xls", "ppt", "txt", "pdf"],default: () => ["doc", "docx", "xls", "xlsx", "ppt", ".pptx", "pdf"],},// 是否显示提示isShowTip: {type: Boolean,default: true,},// 是否显示文件列表isFileList: {type: Boolean,default: true,},dataIndex: {type: Number | String,default: 0,},// 是否可以上传isUpload: {type: Boolean,default: true,},},data() {return {number: 0,uploadList: [],baseUrl: process.env.VUE_APP_BASE_API,uploadFileUrl: process.env.VUE_APP_BASE_API + "/system/oss/upload", // 上传文件服务器地址headers: {Authorization: "Bearer " + getToken(),},fileList: [],};},watch: {value: {async handler(val) {if (val) {let temp = 1;// 首先将值转为数组let list;if (Array.isArray(val)) {list = val;} else {console.log(val);await listByIds(val).then((res) => {list = res.data.map((oss) => {oss = {name: oss.originalName,url: oss.url,ossId: oss.ossId,};return oss;});this.$emit("getfile", list, this.dataIndex);});}// 然后将数组转为对象数组this.fileList = list.map((item) => {item = { name: item.name, url: item.url, ossId: item.ossId };item.uid = item.uid || new Date().getTime() + temp++;return item;});} else {this.fileList = [];return [];}},deep: true,immediate: true,},},computed: {// 是否显示提示showTip() {return this.isShowTip && (this.fileType || this.fileSize);},},methods: {// 上传前校检格式和大小handleBeforeUpload(file) {// 校检文件类型if (this.fileType) {const fileName = file.name.split(".");const fileExt = fileName[fileName.length - 1];const isTypeOk = this.fileType.indexOf(fileExt) >= 0;if (!isTypeOk) {this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);return false;}}// 校检文件大小if (this.fileSize) {const isLt = file.size / 1024 / 1024 < this.fileSize;if (!isLt) {this.$modal.msgError(`上传文件大小不能超过 ${this.fileSize} MB!`);return false;}}this.$modal.loading("正在上传文件,请稍候...");this.number++;return true;},// 文件个数超出handleExceed() {this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);},// 上传失败handleUploadError(err) {this.$modal.msgError("上传文件失败,请重试");this.$modal.closeLoading();},// 上传成功回调handleUploadSuccess(res, file) {if (res.code === 200) {this.uploadList.push({name: res.data.fileName,url: res.data.url,ossId: res.data.ossId,});this.uploadedSuccessfully();} else {this.number--;this.$modal.closeLoading();this.$modal.msgError(res.msg);this.$refs.fileUpload.handleRemove(file);this.uploadedSuccessfully();}},// 删除文件handleDelete(index) {let ossId = this.fileList[index].ossId;// delOss(ossId);this.fileList.splice(index, 1);this.$emit("input", this.listToString(this.fileList));},// 上传结束处理uploadedSuccessfully() {if (this.number > 0 && this.uploadList.length === this.number) {this.fileList = this.fileList.concat(this.uploadList);this.uploadList = [];this.number = 0;this.$emit("input", this.listToString(this.fileList));this.$modal.closeLoading();}},// 获取文件名称getFileName(name) {// 如果是url那么取最后的名字 如果不是直接返回if (name.lastIndexOf("/") > -1) {return name.slice(name.lastIndexOf("/") + 1);} else {return name;}},// 对象转成指定字符串分隔listToString(list, separator) {let strs = "";separator = separator || ",";for (let i in list) {strs += list[i].ossId + separator;}return strs != "" ? strs.substr(0, strs.length - 1) : "";},},
};
</script><style scoped lang="scss">
.upload-file-uploader {margin-bottom: 5px;
}
.upload-file-list .el-upload-list__item {border: 1px solid #e4e7ed;line-height: 2;margin-bottom: 10px;position: relative;
}
.upload-file-list .ele-upload-list__item-content {display: flex;justify-content: space-between;align-items: center;color: inherit;
}
.ele-upload-list__item-content-action .el-link {margin-right: 10px;
}
</style>

4.树形图组件

使用

 <orginTreev-model="queryParams.deptId"@change="changexx"></orginTree>
    changexx(value) {console.log(value.label);// this.$set(this.queryParams, "deptId", value);// console.log("this.queryParams", this.queryParams);},

树形组件封装

<template><div><a-tree-select v-model="orgId" style="width: 100%" size="large" :dropdown-style="{ maxHeight: '400px', overflow: 'auto',zIndex:3000 }"placeholder="请选择" allow-clear tree-default-expand-all :disabled="disabled" :tree-data="vorganTreeData":replaceFields="replaceFields" @change="onChange"></a-tree-select></div>
</template><script>
//注意!!!!!
//在modal弹窗组件中使用该组件需要在关闭弹窗方法里清空数据否则会报错
import { userdepList } from "@/api/user/user";
export default {name: 'vorganTree',props: {value: {type: [String, Number],default: undefined,},disabled: {type: Boolean,default: false,},deptId: {type: [String, Number],default: '',},replaceFields: {type: Object,default: () => {return {children: 'children',title: 'label',key: 'id',value: 'id',}},},},data () {return {orgId: this.value,vorganTreeData: [],}},watch: {value: {handler (newVal) {console.log(this.orgId)this.orgId = newVal},immediate: true,},deptId:{handler (newVal) {this.userdepList()},immediate: true,}},mounted () {this.userdepList()},methods: {userdepList () {let mData = { ancestors: this.deptId }console.log(mData)userdepList(mData).then(res => {this.vorganTreeData = res.dataconsole.log(this.vorganTreeData)})},selectClear () {this.orgId = undefined},onChange (value,label,node) {this.$emit('input', value)this.$emit('update:value', value)this.$emit('change',value,label,node.triggerNode)},},
}
</script><style scoped lang="less">
</style>

5.多选表格组件

使用

   <selectInput v-model="form.userIds" :selectRow="rowData"></selectInput>
<template><div><el-selectv-model="selectValue"style="width: 100%"readonlyref="modelRef"clearablemultiplefilterable@focus="modelClick()"@click.native="modelClick()"@clear="selectClear"@remove-tag="selectRemoveClear"allow-createplaceholder="请选择"><el-optionv-for="item in selectRow":key="item[userId]":label="item.nickName":value="item[userId]"></el-option></el-select><el-dialog:title="title"width="1000px":visible.sync="dialogFormVisible"append-to-body><el-row :gutter="24"><el-col :span="16"><el-form ref="form" :model="queryParam" label-width="50px"><el-row><el-col :span="8"><el-form-item label="昵称"><el-input v-model="queryParam.nickName"></el-input></el-form-item></el-col><el-col :span="8"><el-form-item label="账号"><el-input v-model="queryParam.userName"></el-input></el-form-item></el-col><el-col :span="8"><el-buttontype="primary"icon="el-icon-search"@click="searchQuery"style="margin-left: 10px">搜索</el-button><el-button icon="el-icon-refresh-right" @click="searchReset">重置</el-button></el-col></el-row></el-form><el-table:data="tableData"v-loading="loading"border@selection-change="handleSelectionChange"@select="handleSelectionChange"@row-click="handleRowSelectionChange"ref="multipleTable":row-key="userId":reserve-selection="true"><el-table-columntype="selection"width="40":reserve-selection="true"></el-table-column><el-table-column:property="item.property":label="item.label"v-for="(item, index) in column":key="index"></el-table-column></el-table><div style="float: right; margin-top: 10px"><el-paginationbackgroundlayout="prev, pager, next":total="total"@current-change="handleCurrentChange":current-page.sync="currentPage":page-size="5"></el-pagination></div></el-col><el-col :span="7" style="margin: 14px"><span style="font-size: 16px" class="select">已选 {{ selectRow.length }}</span><el-table :data="tableData1" border style="margin-top: 20px"><el-table-columnsize="mini":property="item.property":label="item.label"v-for="(item, index) in column1":key="index"></el-table-column><el-table-column prop="action" label="操作" width="50"><template slot-scope="scope"><el-buttontype="text"size="small"@click="deleteRecord(scope.row)">删除</el-button></template></el-table-column></el-table><div style="float: right; margin-top: 10px"><el-paginationbackgroundlayout="prev, pager, next":total="total1"@current-change="handleCurrentChange1":current-page.sync="currentPage1":page-size="5"></el-pagination></div></el-col></el-row><div slot="footer" class="dialog-footer"><el-button @click="dialogFormVisible = false">关闭</el-button></div></el-dialog></div>
</template><script>
import request from "@/utils/request";
export default {props: {title: {type: String,default: "",},value: {type: String,default: "",},// deptId: {//   type: String,//   default: "",// },},data() {return {dialogFormVisible: false,searchText: "",queryParam: {},column: [{property: "nickName",label: "昵称",},{property: "userName",label: "账号",},{property: "orgName",label: "组织",},],column1: [{property: "nickName",label: "昵称",},{property: "userName",label: "账号",},],options: [],loading: false,tableData: [],tableData1: [],currentPage: 1,currentPage1: 1,total: 0,total1: 0,url: "system/user/list", // 一直urlselectRowKey: [],selectRow: [],selectValue: [],userId: "userId", // 唯一键值deptId: "",};},watch: {value: {immediate: true,handler(val) {if (val) {console.log("11111", val);this.selectValue = val.split(",");this.ifValue();} else {this.selectValue = [];this.selectRow = [];}},},// deptId: {//   immediate: true,//   handler(val) {//     console.log("val", val);//     this.selectValue = [];//     this.selectRow = [];//     // if (val) {//     //   this.selectValue = val.split(",");//     //   this.ifValue();//     // } else {//     //   this.selectValue = [];//     //   this.selectRow = [];//     // }//   },// },selectValue: {deep: true,handler(val) {console.log("selectValue", val);let data = val.join(",");this.$emit("input", data);// this.$emit("getuserList", this.tableData1);},},selectRow: {deep: true,handler(val) {this.pageData();},},// tableData1: {//   deep: true,//   handler(val) {//     this.$bus.$emit("tableData1", this.tableData1);//     // this.$emit("getuserList", this.tableData1);//   },// },},created() {},mounted() {this.$bus.$on("deptId", (data) => {console.log("我是selectInput组件,收到了数据", data);this.deptId = data;});},methods: {// handleInput(value) {//   this.queryParam.userName = value;//   this.queryParam.nickName = value;// },selectRemoveClear(val) {let selectIndex = -1;this.selectRow.forEach((item, index) => {if (item[this.userId] == val) {selectIndex = index;}});this.currentPage1 = 1;this.selectRow.splice(selectIndex, 1);this.$refs.multipleTable.selection.splice(selectIndex, 1);},// 清空selectClear() {this.currentPage1 = 1;this.selectRow = [];this.selectValue = [];this.$refs.multipleTable.clearSelection();},deleteSelect(val) {let selectIndex = 0;this.selectValue.forEach((item, index) => {if (item == val[this.userId]) {selectIndex = index;}});this.selectValue.splice(selectIndex, 1);this.selectRow.splice(selectIndex, 1);this.$refs.multipleTable.selection.splice(selectIndex, 1);},// 用于将选择框中的选项添加到已选中的选项中。//在用户选择选项时调用。//将选择框中新选中的选项添加到 selectRow 和 selectValue 中,并更新页面数据。addSelection() {let mRow = JSON.parse(JSON.stringify(this.selectRow));this.$refs.multipleTable.selection.forEach((item, index) => {if (!mRow.some((items) => {return items[this.userId] == item[this.userId];})) {this.selectRow.push(item);this.selectValue.push(item[this.userId]);}});},//     用于从已选中的选项中删除选项。// 在用户取消选中选项时调用。// 从 selectRow 和 selectValue 中删除取消选中的选项,并更新页面数据。deleteSelection() {let selection = JSON.parse(JSON.stringify(this.$refs.multipleTable.selection));this.selectRow = selection;this.selectValue = selection.map((item) => item[this.userId]);},//     用于检查已选中的选项是否与选择框中的选项一致。// 在组件初始化和 value 数据变化时调用。// 如果已选中的选项与选择框中的选项不一致,则调用 getUser 方法。ifValue() {if (this.selectRow.length != this.selectValue.length) {this.getUser();} else if (this.selectRow.length != 0) {this.selectRow.forEach((item) => {if (!this.selectValue.some((items) => {return item[this.userId] == items;})) {this.getUser();}});}},//     用于根据已选中的选项获取用户信息。// 在 ifValue 方法中调用。// 发送网络请求获取已选中的选项对应的用户信息,并更新 selectRow 中的数据。getUser() {// this.getPage("`system/user/list?id=${this.deptId}`").then((res) => {this.getPage("system/user/list/ids", { ids: this.value }).then((res) => {console.log("this.deptId22222", this.deptId);console.log("有id时候res", res);if (res.code == 200) {let records = res.data.map((item) => {let mItem = {email: item.email,nickName: item.nickName,orgName: item.dept ? item.dept.deptName : "",phonenumber: item.phonenumber,userName: item.userName,};mItem[this.userId] = item[this.userId].toString();return mItem;});this.selectRow = records;}});},//     用于删除指定的记录。// 当用户点击已选中的选项的删除按钮时调用。// 调用 deleteSelect 方法删除指定的选项。deleteRecord(record) {this.deleteSelect(record);},toggleSelection(rows) {if (rows) {rows.forEach((row) => {this.$refs.multipleTable.toggleRowSelection(row);});} else {this.$refs.multipleTable.clearSelection();}},ifSelectValue(val) {let selectBoole = false;this.selectValue.forEach((item, index) => {if (item == val[this.userId]) {selectBoole = true;}});if (selectBoole) {this.deleteSelect(val);return false;} else {this.selectValue.push(val[this.userId]);this.selectRow.push(val);return true;}},handleRowSelectionChange(val, row) {if (this.ifSelectValue(val)) {this.$refs.multipleTable.selection.push(val);} else {}},handleSelectionChange(val, row) {this.multipleSelection = val;this.addSelection();if (val.length < this.selectRow.length) {this.deleteSelection();}},handleCurrentChange(val) {this.currentPage = val;this.getList();},handleCurrentChange1(val) {this.currentPage1 = val;this.pageData();},searchReset() {this.queryParam = {};this.currentPage = 1;this.getList();},searchQuery() {this.currentPage = 1;this.getList();},getList() {this.loading = true;// let mData = {//   pageNum: this.currentPage,//   pageSize: 5,// };// console.log("this.queryParam", this.queryParam);// let deptId = this.deptId;this.getPage(this.url, {deptId: this.deptId,pageNum: this.currentPage,pageSize: 5,...this.queryParam,})// this.getPage(this.url, Object.assign(deptId, mData, this.queryParam)).then((res) => {this.loading = false;if (res.code == 200) {// console.log('this.deptId',this.deptId);console.log(11111111, res);this.tableData = res.rows.map((item) => {let mItem = {email: item.email,nickName: item.nickName,orgName: item.dept ? item.dept.deptName : "",phonenumber: item.phonenumber,userName: item.userName,};mItem[this.userId] = item[this.userId].toString();return mItem;});this.total = res.total;}}).catch((err) => {this.loading = false;});},pageData() {let mm = JSON.parse(JSON.stringify(this.selectRow));this.total1 = mm.length;this.tableData1 = mm.slice((this.currentPage1 - 1) * 5,this.currentPage1 * 5);if (this.currentPage1 > 1 && this.tableData1.length == 0) {this.currentPage1 = this.currentPage1 - 1;this.pageData();}console.log("tableData1", this.tableData1);},getPage(url, query) {return request({url: url,method: "get",params: query,});},ifselection() {let mmblo = false;if (this.selectRow.length != this.$refs.multipleTable.selection.length) {mmblo = true;return mmblo;}this.selectRow.forEach((item) => {if (!this.$refs.multipleTable.selection.some((items) => {return item[this.userId] == items[this.userId];})) {mmblo = true;}});return mmblo;},modelClick() {this.dialogFormVisible = true;this.queryParam = {};setTimeout(() => {this.$refs.modelRef.blur();if (this.ifselection()) {let mms = JSON.parse(JSON.stringify(this.$refs.multipleTable.selection));mms.forEach((item) => {this.$refs.multipleTable.selection.pop();});this.selectRow.forEach((item) => {this.$refs.multipleTable.selection.push(item);});this.currentPage = 1;this.getList();}}, 1);this.getList();},},
};
</script>
<style>
/* .select {
} */
.tableData1 {padding-top: 10px;/* background-color: pink; */
}
</style>

6.时间选择器格式

在el中

 value-format="yyyy-MM-dd"
 <el-date-pickerv-model="queryParams.appraisalYear"type="year"placeholder="选择年"value-format="yyyy-MM-dd"></el-date-picker>

在antd中

valueFormat="YYYY-MM-DD"
 <a-form-model-itemlabel="计划时间:"prop="times":labelCol="labelCol":wrapperCol="wrapperCol"><a-range-picker v-model="model.times" valueFormat="YYYY-MM-DD" /></a-form-model-item>

7.自定义校验规则

prop="liaisonUserIds"

  <el-form-item label="联络员" prop="liaisonUserIds" ref="devType"><selectInputv-model="form.liaisonUserIds":selectRow="rowData"></selectInput></el-form-item>

 rules里面liaisonUserIds

 rules: {userId: [{ required: true, message: "请选则", trigger: "change" }],liaisonUserIds: [{required: true,validator: this.validatePass,message: "请选择",trigger: "change",},],},
 // 自定义校验规则validatePass(rule, value, callback) {console.log("rule", rule, "value", value);if (!this.form.liaisonUserIds) {return callback(new Error("联系人为空")); // 校验失败,传入错误信息} else {callback(); // 校验通过,不传入参数或传入 null}},

8.vue2数组不更新,强制更新

  this.$set(this.form, "deptId", selectedUser.deptId);

9.下载

使用

 downExport() {this.download("/epb/dutyPerformItem/export",{dutyPerformId: 1,type: 0,...this.queryParams,},`党支部履责情况列表.xlsx`);},

在mian.js中全局注册

import { download } from '@/utils/request'

在request

import axios from 'axios'
import { Notification, MessageBox, Message, Loading } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
import { tansParams, blobValidate } from "@/utils/ruoyi";
import cache from '@/plugins/cache'
import { saveAs } from 'file-saver'let downloadLoadingInstance;
// 是否显示重新登录
export let isRelogin = { show: false };axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 对应国际化资源文件后缀
axios.defaults.headers['Content-Language'] = 'zh_CN'
// 创建axios实例
const service = axios.create({// axios中请求配置有baseURL选项,表示请求URL公共部分baseURL: process.env.VUE_APP_BASE_API,// 超时timeout: 10000
})// request拦截器
service.interceptors.request.use(config => {// 是否需要设置 tokenconst isToken = (config.headers || {}).isToken === false// 是否需要防止数据重复提交const isRepeatSubmit = (config.headers || {}).repeatSubmit === falseif (getToken() && !isToken) {config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改}// get请求映射params参数if (config.method === 'get' && config.params) {let url = config.url + '?' + tansParams(config.params);url = url.slice(0, -1);config.params = {};config.url = url;}if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {const requestObj = {url: config.url,data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,time: new Date().getTime()}const sessionObj = cache.session.getJSON('sessionObj')if (sessionObj === undefined || sessionObj === null || sessionObj === '') {cache.session.setJSON('sessionObj', requestObj)} else {const s_url = sessionObj.url;                  // 请求地址const s_data = sessionObj.data;                // 请求数据const s_time = sessionObj.time;                // 请求时间const interval = 1000;                         // 间隔时间(ms),小于此时间视为重复提交if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {const message = '数据正在处理,请勿重复提交';console.warn(`[${s_url}]: ` + message)return Promise.reject(new Error(message))} else {cache.session.setJSON('sessionObj', requestObj)}}}return config
}, error => {console.log(error)Promise.reject(error)
})// 响应拦截器
service.interceptors.response.use(res => {// 未设置状态码则默认成功状态const code = res.data.code || 200;// 获取错误信息const msg = errorCode[code] || res.data.msg || errorCode['default']// 二进制数据则直接返回if (res.request.responseType ===  'blob' || res.request.responseType ===  'arraybuffer') {return res.data}if (code === 401) {if (!isRelogin.show) {isRelogin.show = true;MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {isRelogin.show = false;store.dispatch('LogOut').then(() => {location.href = process.env.VUE_APP_CONTEXT_PATH + "index";})}).catch(() => {isRelogin.show = false;});}return Promise.reject('无效的会话,或者会话已过期,请重新登录。')} else if (code === 500) {Message({ message: msg, type: 'error' })return Promise.reject(new Error(msg))} else if (code === 601) {Message({ message: msg, type: 'warning' })return Promise.reject('error')} else if (code !== 200) {Notification.error({ title: msg })return Promise.reject('error')} else {return res.data}},error => {console.log('err' + error)let { message } = error;if (message == "Network Error") {message = "后端接口连接异常";} else if (message.includes("timeout")) {message = "系统接口请求超时";} else if (message.includes("Request failed with status code")) {message = "系统接口" + message.substr(message.length - 3) + "异常";}Message({ message: message, type: 'error', duration: 5 * 1000 })return Promise.reject(error)}
)// 通用下载方法
export function download(url, params, filename, config) {downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })return service.post(url, params, {transformRequest: [(params) => { return tansParams(params) }],headers: { 'Content-Type': 'application/x-www-form-urlencoded' },responseType: 'blob',...config}).then(async (data) => {const isBlob = blobValidate(data);if (isBlob) {const blob = new Blob([data])saveAs(blob, filename)} else {const resText = await data.text();const rspObj = JSON.parse(resText);const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']Message.error(errMsg);}downloadLoadingInstance.close();}).catch((r) => {console.error(r)Message.error('下载文件出现错误,请联系管理员!')downloadLoadingInstance.close();})
}export default service

10.导出

使用

和9是一样的

 handleExport(data) {console.log("data导出", data);this.download("/epb/dutyItem/export",{dutyAppraisalId: data.dutyAppraisalId,},`${data.appraisalYear + "年" + data.deptName + "责任制考核"}.xlsx`);},

11.导入

 <el-uploadclass="upload-demo":action="uploadFileUrl"multiple:show-file-list="false":headers="headers":on-success="handleUploadSuccess"><el-button>导入</el-button></el-upload>
 return {uploadFileUrl: `${process.env.VUE_APP_BASE_API}/epb/workItem/importData${this.form && this.form.id ? "?workId=" + this.form.id : ""}`,// uploadFileUrl: `${process.env.VUE_APP_BASE_API}/epb/workItem/importData?workId=${this.form.id}`, // 上传文件服务器地址// uploadFileUrl: process.env.VUE_APP_BASE_API + "/epb/workItem/importData", // 上传文件服务器地址headers: {Authorization: "Bearer " + getToken(),},};
import { getToken } from "@/utils/auth";
   // 导入文件handleUploadSuccess(res, file) {// console.log("res", res, "file", file);if (res.code == 200) {const tableData = [];let mArr = JSON.parse(JSON.stringify(tableData));// 页面操作  concat() 方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。mArr = mArr.concat(res.data.workItemVos);mArr = mArr.map((item, index) => {return {...item,sort: item.sort + 1, //一开始就遍历加上序号markTime: new Date().getTime(),};});// console.log("mArr", mArr);this.getContentList(mArr);// this.workList = [];this.workList = this.workList.concat(res.data.workLabelVos);console.log("this.workList", this.workList);}},

12.处理分类数据

 // 处理数据handleData(sourceData) {// 分类let classifyWorkContentList = []; //类别数组[...sourceData].forEach((item) => {// .includes()方法返回一个布尔值(true或false)if (classifyWorkContentList.indexOf(item.workContent) === -1) {classifyWorkContentList.push(item.workContent);}});console.log("classifyWorkContentList", classifyWorkContentList);// 按照表格样式修改数据结构// 例如[{workContent: 'xxx', workNormList: [{workItemId: 1111,workId: 11111 ,workContent:'xxx',sort: 1,workNorm:'xxx',No: 1,isDone: 0}]const handleData = classifyWorkContentList.map((item) => {return {workContent: item,workNormList: sourceData.filter((item2) => item2.workContent === item),};});return handleData;},

13.文件回显

两种回显

一种

 <span v-for="(item, index) in form.fileList" :key="index"><a :href="item.fileUrl" target="_blank">{{ item.fileName }}</a>,</span>
 showDetailModal(data) {console.log("data", data);this.title = "详情";this.dialogVisible = true;const fileArr =data?.fileUrl?.split(",")?.map((item, index) => {return {fileUrl: item,fileName: data?.fileName?.split(",")[index],};}) || [];this.form = data;console.log("fileArr", fileArr);this.$set(this.form, "fileList", fileArr);this.getDetail(data.taskId);},

第二种

 <FileUploadv-model="form.fileId":isUpload="false":isShowTip="false":fileType="false"></FileUpload>


http://www.ppmy.cn/embedded/48694.html

相关文章

【数学】什么是马尔可夫链?RNN 与马尔可夫链的联系,马尔可夫链与条件随机场的比较

文章目录 马尔可夫链背景公式示例题目详细讲解Python代码求解实际生活中的例子 RNN 与马尔可夫链的联系对比总结图示解释 马尔可夫链与条件随机场的比较条件随机场 (Conditional Random Field, CRF)马尔可夫链与 CRF 的联系马尔可夫链隐马尔可夫模型 (HMM)条件随机场 (CRF) 举例…

Java课程设计:基于swing的学生信息管理系统

文章目录 一、项目介绍二、项目展示三、源码展示四、源码获取 一、项目介绍 这款Java swing实现的学生信息管理系统和jsp版本的功能很相似&#xff0c;简单的实现了班级信息的增删改查&#xff0c;学生信息的增删改查&#xff0c;数据库采用的是mysql&#xff0c;jdk版本不限&…

关于ReactV18的页面跳转传参和接收

一、使用路由方式进行传参和接收&#xff08;此处需使用 useNavigate 和 useParams 两个hooks&#xff09; 1 首先需要配置好路由形式如下 :id(参数) { path: "/articleDetail/:id", element: lazyElement(<ArticleDetail />), }, 2 传递参数 使用 useNaviga…

python爬虫

{}字典[]列表 请求对象的定制 urllib.request.Request(url,headers) urllib.request.urlopen(请求对象) 因为urlopen方法中不能存储字典 所以headers不能传递进去 注意&#xff1a;因为参数顺序的问题&#xff0c;不能直接写url和headers&#xff0c;中间还有data&#xf…

gitlab下载及安装

目录 1、gitlab下载 2、gitlab安装 3、完全卸载GitLab 1、gitlab下载 首页&#xff1a;https://about.gitlab.com 安装&#xff1a;https://about.gitlab.com/install rpm包&#xff1a;https://packages.gitlab.com/gitlab/gitlab-ce 2、gitlab安装 2.1 CentOS 7 rpm -iv…

LeetCode | 520.检测大写字母

这道题直接分3种情况讨论&#xff1a;1、全部都为大写&#xff1b;2、全部都为小写&#xff1b;3、首字母大写其余小写。这里我借用了一个全是大写字母的串和一个全为小写字母的串进行比较 class Solution(object):def detectCapitalUse(self, word):""":type …

学习笔记——网络管理与运维——概述(网络管理方式)

三、网络管理方式 网络设备管理方式随着技术的发展而演进&#xff0c;以下是按技术发展先后顺序列举的主要网络设备管理方式&#xff1a; 1、控制台管理 最初的网络设备管理方式&#xff0c;通过网络设备的物理控制台端口进行管理&#xff0c;通常使用串行连接。 2、通过CLI…

Android11 后台启动Activity

在 Android 10 (API 29) 及更高版本(包括 Android 11),系统对后台启动 Activity 施加了严格的限制。默认情况下,应用程序在后台无法启动 Activity,以提高用户体验并减少不必要的干扰。以下为解决方法。 From 7d554af386150edec1cd68f6eaf700538af4e373 Mon Sep 17 00:00:0…