vue elementUI Plus實現(xiàn)拖拽流程圖的詳細代碼(不引入插件)
vue elementUI Plus實現(xiàn)拖拽流程圖,不引入插件,純手寫實現(xiàn)。
1.設計思路:
左側button列表是要拖拽的組件。中間是拖拽后的流程圖。右側是拖拽后的數(shù)據(jù)列表。
我們拖動左側組件放入中間的流程圖中,并把button攜帶的數(shù)據(jù)信息帶過來。
2.設計細節(jié)
左側button組件列表可拖動并攜帶信息,當拖動到中間流程圖上方時,流程圖網(wǎng)格變色。當鼠標釋放后,數(shù)據(jù)傳遞,流程圖變化。
拖拽事件流程和參數(shù)
dragstart:當元素開始被拖拽時觸發(fā)。
drag:元素正在被拖拽時持續(xù)觸發(fā)(某些瀏覽器支持)。
dragend:當拖拽結束時觸發(fā)。
dragenter:當拖拽的元素進入目標元素時觸發(fā)。
dragover:當拖拽的元素在目標元素上移動時持續(xù)觸發(fā)。
dragleave:當拖拽的元素離開目標元素時觸發(fā)。
drop:當拖拽的元素在目標元素上釋放時觸發(fā)。
3.詳細代碼實現(xiàn)
<template> <div class="scriptDraweAdd"> <drawer-Box :drawerVisible="drawer.visible" :drawerFooter="drawer.drawerFooter" :direction="drawer.direction" :drawerSize="drawer.drawerSize" :drawerTitle="drawer.drawerTitle" @handleDrawerOpened="handleDrawerOpened" @handleDrawerClose="handleDrawerClose" @handleDrawerSubmit="handleDrawerSubmit" > <div class="main h100"> <el-form ref="addFormRef" :model="editFrom" size="small" status-icon class="h100" label-width="auto"> <el-row :gutter="0"> <el-col> <el-row :gutter="10"> <el-col :span="4" class="mb20 setting-title"><span>General settings</span></el-col> <el-col :span="10" class="mb20"> <el-form-item prop="projectName" :rules="rules.projectName"> <template v-slot:label ><span>Project Name </span> <el-tooltip effect="dark" content="Project Name" placement="top"> <i> <svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" /> </i> </el-tooltip> </template> <el-input v-model="editFrom.projectName" placeholder="Project Name" clearable></el-input> </el-form-item> </el-col> <el-col :span="10" class="mb20"> <el-form-item prop="version" :rules="rules.version"> <template v-slot:label ><span>Version </span> <el-tooltip effect="dark" content="Software Version" placement="top"> <i> <svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" /> </i> </el-tooltip> </template> <el-input v-model="editFrom.version" placeholder="Software Version" clearable></el-input> </el-form-item> </el-col> </el-row> </el-col> <el-col> <el-row :gutter="10"> <el-col :span="4" class="mb20"><span></span></el-col> <!-- <el-col :span="10" class="mb20"> <el-form-item prop="softwareName" :rules="rules.softwareName"> <template v-slot:label ><span>Software Name </span> <el-tooltip effect="dark" content="Software Name" placement="top"> <i> <svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" /> </i> </el-tooltip> </template> <el-input v-model="editFrom.softwareName" placeholder="Software Name" clearable></el-input> </el-form-item> </el-col> --> <el-col :span="10" class="mb20"> <el-form-item prop="function" :rules="rules.function"> <template v-slot:label ><span>Function </span> <el-tooltip effect="dark" content="Function of the script" placement="top"> <i> <svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" /> </i> </el-tooltip> </template> <el-select v-model="editFrom.function" placeholder="Function"> <el-option v-for="item in functionOptions" :key="item.value" :label="item.label" :value="item.value" /> </el-select> </el-form-item> </el-col> </el-row> </el-col> <el-col> <el-row :gutter="10"> <el-col :span="4" class="mb20 setting-title"><span>Advanced settings</span></el-col> <el-col :span="10" class="mb20"> <el-form-item label="" prop="maxRunTime" :rules="rules.maxRunTime"> <template v-slot:label ><span>Max Run Time </span> <el-tooltip effect="dark" content="The max run time of the script" placement="top"> <i> <svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" /> </i> </el-tooltip> </template> <el-input-number type="number" v-model="editFrom.maxRunTime" :min="0" :max="1000" placeholder="Max Run Time" style="width: 100%" /> </el-form-item> </el-col> <el-col :span="10" class="mb20"> <el-form-item prop="startStopService" :rules="rules.startStopService"> <template v-slot:label ><span>Start Stop Service </span> <el-tooltip effect="dark" content="Service(s) needed to be pause during software installation, separate with commas." placement="top"> <i> <svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" /> </i> </el-tooltip> </template> <el-input v-model="editFrom.startStopService" placeholder="Start Stop Service" clearable></el-input> </el-form-item> </el-col> </el-row> </el-col> <el-col> <el-row :gutter="10"> <el-col :span="4" class="mb20"><span></span></el-col> <el-col :span="10" class="mb20"> <el-form-item prop="debugEnable" :rules="rules.debugEnable"> <template v-slot:label ><span>Debug Enable </span> <el-tooltip effect="dark" content="Used to enable logging." placement="top"> <i> <svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" /> </i> </el-tooltip> </template> <el-switch v-model="editFrom.debugEnable" :active-value="true" :inactive-value="false" /> </el-form-item> </el-col> <el-col :span="10" class="mb20"> <el-form-item prop="defaultMsicLine" :rules="rules.defaultMsicLine"> <template v-slot:label ><span>Default MSIC Line </span> <el-tooltip effect="dark" content="Default MSI commands, used for each MSI installer." placement="top"> <i> <svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" /> </i> </el-tooltip> </template> <el-input v-model="editFrom.defaultMsicLine" placeholder="Default MSIC Line" clearable></el-input> </el-form-item> </el-col> </el-row> </el-col> <el-col> <el-row :gutter="10"> <el-col :span="4" class="mb20"><span></span></el-col> <el-col :span="10" class="mb20"> <el-form-item prop="uDriveMap" :rules="rules.uDriveMap"> <template v-slot:label ><span>U-Drive Map </span> <el-tooltip effect="dark" content="If the software stored on U-Drive." placement="top"> <i> <svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" /> </i> </el-tooltip> </template> <el-switch v-model="editFrom.uDriveMap" :active-value="true" :inactive-value="false" /> </el-form-item> </el-col> <el-col :span="10" class="mb20"> <el-form-item label="IFS Script" prop="ifsScript" :rules="rules.ifsScript"> <template v-slot:label ><span>IFS Script </span> <el-tooltip effect="dark" content="If you need to run the script on your local computer." placement="top"> <i> <svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" /> </i> </el-tooltip> </template> <el-switch v-model="editFrom.ifsScript" :active-value="true" :inactive-value="false" /> </el-form-item> </el-col> </el-row> </el-col> <el-col> <el-row :gutter="10"> <el-col :span="4" class="mb20"><span></span></el-col> <!-- <el-col :span="10" class="mb20"> <el-form-item prop="patchCommands"> <template v-slot:label ><span>Patch Commands </span> <el-tooltip effect="dark" content="Used if need to install software to alternate folder." placement="top"> <i> <svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" /> </i> </el-tooltip> </template> <el-input v-model="editFrom.patchCommands" placeholder="Patch Commands" disabled></el-input> </el-form-item> </el-col> --> <el-col :span="10" class="mb20"> <el-form-item label="Remarks" prop="remarks" :rules="rules.remarks"> <el-input v-model="editFrom.remarks" clearable placeholder="Remarks" :rows="2" type="textarea" /> </el-form-item> </el-col> </el-row> </el-col> <el-col> <el-row :gutter="10" class="custom-row-height"> <el-col :span="8" class="mb20"> <div class="searchdiv"> <div style="display: flex"> <el-input style="margin-right: 10px" v-model="searchScriptName" placeholder="Script Name" @keyup.enter="getScriptList()" clearable></el-input> <el-button @click="getScriptList()" type="primary"> <i> <svg-icon icon-class="icon_screen" class-name="iconfont font14" /> </i ></el-button> </div> <div class="paramslabel"> <el-tooltip v-for="(item, index) in scriptList" :key="index" placement="top" raw-content :content="remarkHTML(item.remarks)"> <el-button draggable="true" @dragstart="dragstart($event, item)" @dragend="dragend($event, item)" class="buttondiv" :title="item.scriptName" type="primary">{{ item.scriptName }}</el-button> </el-tooltip> </div> </div> </el-col> <el-col :span="9" class="mb20"> <div class="flowdiv"> <div class="flowlabel"> <div> <el-button class="buttondiv" type="primary">Start</el-button> <div :class="['add-contain-div', overFlag.over0 ? 'add-contain-div-active' : '']" @dragover="dragOver($event, 'over0')" @drop="drop($event, 0)"> <svg-icon icon-class="downward_vertical_line" class="addline" /> <svg-icon icon-class="icon_add" class="addicon" /> </div> </div> <div v-for="(item, index) in editFrom.scriptList" :key="index" style="padding-left: 60px"> <!-- <el-button v-show="true" class="buttondiv2" type="primary">{{ item.gClientScriptId }}</el-button> --> <el-input style="width: 180px" v-show="false" v-model="item.gClientScriptId" placeholder="gClientScriptId" readonly></el-input> <el-tooltip placement="top" raw-content :content="remarkHTML(item.remarks)"> <el-button class="buttondiv" type="primary">{{ item.scriptName }}</el-button> </el-tooltip> <el-button type="text" @click="deleteMethod(index)" class="deletebutton"> <svg-icon icon-class="icon_delete2" class="deleteline" /> </el-button> <div style="padding-right: 60px" @dragover="dragOver($event, 'over' + (index + 1))" @drop="drop($event, index + 1)"> <div :class="['add-contain-div', overFlag['over' + (index + 1)] ? 'add-contain-div-active' : '']"> <svg-icon icon-class="downward_vertical_line" class="addline" /> <svg-icon icon-class="icon_add" class="addicon" /> </div> </div> </div> <el-button class="buttondiv" type="primary">End</el-button> </div> </div> </el-col> <el-col :span="7" class="mb20" style="min-width:350px"> <div v-for="(item2, index2) in editFrom.scriptList" :key="index2 + 'params'"> <div class="paramsdiv"> <div class="params-title-parent"> <el-form-item ><span style="margin-left: 10px; font-weight: bold">{{ item2.scriptName }}</span></el-form-item > </div> <div class="paramsdiv-content"> <el-form-item label-width="auto" label="Order No."> <el-input style="width: 100%" v-model="item2.orderNum" placeholder="Order No." readonly></el-input></el-form-item> <el-form-item label="CmdRCOpt" label-width="auto" :prop="`scriptList[${index2}].cmdRcopt`" :rules="[{ required: true, message: `Please input CmdRCOpt`, trigger: 'change' }]"> <el-select v-model="item2.cmdRcopt" placeholder="CmdRCOpt" disabled style="width: 100%"> <el-option v-for="item3 in cmdRCOptOptions" :key="item3.value" :label="item3.label" :value="item3.value" /> </el-select> </el-form-item> <div v-for="(item, index) in item2.paramslist" :key="index2 + '_' + index"> <el-form-item v-show="false" label="Order No." label-width="140px"> <el-input style="width: 100%" v-model="item.index" placeholder="Order No." readonly></el-input> </el-form-item> <div v-if="item.dataType === 'String'" class="paramsdiv-params"> <el-form-item :prop="`scriptList[${index2}].paramslist[${index}].value`" :rules="[{ required: true, message: `Please input ${item.name}`, trigger: 'blur' }]" label-width="auto" > <template v-slot:label ><span>{{ item.name }}</span> <el-tooltip effect="dark" :content="item.remarks" placement="top"> <i> <svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" /> </i> </el-tooltip> <el-tag style="margin-right: 0px !important; margin-top: 3px !important" type="primary" class="mr12" effect="light" round>{{ item.dataType }}</el-tag> </template> <el-input style="width: 100%" v-model="item.value" :placeholder="item.name"></el-input> </el-form-item> </div> <div v-if="item.dataType === 'Int'" class="paramsdiv-params"> <el-form-item :prop="`scriptList[${index2}].paramslist[${index}].value`" :rules="[{ required: true, message: `Please input ${item.name}`, trigger: 'change' }]" label-width="auto" > <template v-slot:label ><span>{{ item.name }}</span> <el-tooltip effect="dark" :content="item.remarks" placement="top"> <i> <svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" /> </i> </el-tooltip> <el-tag style="margin-right: 0px !important; margin-top: 3px !important" type="primary" class="mr12" effect="light" round>{{ item.dataType }}</el-tag> </template> <!-- <el-input style="width: 100%" v-model="item.value" :placeholder="item.name"></el-input> --> <el-input-number type="number" v-model="item.value" :placeholder="item.name" style="width: 100%" /> </el-form-item> </div> <div v-if="item.dataType === 'Boolean'" class="paramsdiv-params"> <el-form-item :prop="`scriptList[${index2}].paramslist[${index}].value`" :rules="[{ required: true, message: `Please input ${item.name}`, trigger: 'change' }]" label-width="auto" > <template v-slot:label ><span>{{ item.name }}</span> <el-tooltip effect="dark" :content="item.remarks" placement="top"> <i> <svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" /> </i> </el-tooltip> <el-tag style="margin-right: 0px !important; margin-top: 3px !important" type="primary" class="mr12" effect="light" round>{{ item.dataType }}</el-tag> </template> <el-switch v-model="item.value" :active-value="true" :inactive-value="false" :value="false" :disabled="index === 0" /> </el-form-item> </div> <div v-if="item.dataType === 'File'" class="paramsdiv-params"> <el-form-item :label="item.name" :placeholder="item.name" :prop="`scriptList[${index2}].paramslist[${index}].fileList`" :rules="[{ required: true, message: `Please upload file`, validator: validator, trigger: 'change' }]" label-width="auto" > <template v-slot:label ><span>{{ item.name }}</span> <el-tooltip effect="dark" :content="item.remarks" placement="top"> <i> <svg-icon icon-class="icon_ notes_info" class-name="iconfont font14" /> </i> </el-tooltip> <el-tag style="margin-right: 0px !important; margin-top: 3px !important" type="primary" class="mr12" effect="light" round>{{ item.dataType }}</el-tag> </template> <el-upload :disabled="item.isOriginalFile === 1" :action="upload.action" :headers="upload.headers" :limit="upload.limit" multiple v-model:file-list="item.fileList" :on-success="(res) => handleUploadSuccess(res, item, index)" :on-remove="(uploadFile, uploadFiles) => handleRemove(uploadFile, uploadFiles, item, index)" :before-upload="(file) => beforeAvatarUpload(file, item, index)" :on-exceed="(uploadFile, uploadFiles) => handleExceed(uploadFile, uploadFiles, item, index)" :on-preview="(uploadFile) => handlePreview(uploadFile, item, index)" > <el-button :disabled="item.fileList && item.fileList.length > 0" type="primary">Click to upload</el-button> <template #tip> <div class="el-upload__tip">.ps1, .txt files with a size less than 2M</div> </template> </el-upload> </el-form-item> <el-form-item v-show="false" label="File Name" label-width="140px"> <el-input style="width: 80%" v-model="item.fileName" placeholder="File Name" readonly></el-input> </el-form-item> <el-form-item :prop="`scriptList[${index2}].paramslist[${index}].fileContent`" label-width="140px" style="margin-top: -20px"> <el-input v-show="false" type="textarea" readonly style="width: 100%" v-model="item.fileContent" placeholder="File Content" :autosize="{ minRows: 3, maxRows: 10000 }" ></el-input> </el-form-item> </div> </div> </div> </div> </div> </el-col> </el-row> </el-col> </el-row> </el-form> </div> </drawer-Box> </div> </template> <script> import { toRefs, reactive, onMounted, ref } from 'vue' import { ElMessage } from 'element-plus' import DrawerBox from '../drawer/index' import gClientApi from '@/api/gClientApi' import gClientManagementApi from '@/api/gClientManagementApi' import { removeProperty } from '@/utils/validate' import { Session } from '@/utils/storage' export default { name: 'GclientScriptMenagement', emits: ['handleSearch', 'handleClose', 'downScriptFile'], components: { DrawerBox // vxeTable }, props: { drawer: { type: Object, default: () => { return {} } }, GclientScriptMenagement: { type: Object, default: () => { return {} } } }, setup(props, ctx) { // 列表數(shù)組 接口返回的數(shù)據(jù) const vxeData = reactive({ tableList: [] }) const addFormRef = ref(null) // 復選框數(shù)組 const vxeList = reactive({ checkList: [] }) const useTableHeader = reactive({}) const state = reactive({ upload: { action: process.env.VUE_APP_API_URL + '/portal/v1/GClientScript/scriptUpload', headers: { Authorization: Session.get('token') }, accept: '.ps1, .txt', fileSize: 2, limit: 1 }, functionOptions: [ { lable: 'Install', value: 'Install' }, { lable: 'Uninstall', value: 'Uninstall' } ], typeOptions: [ { label: 'String', value: 'String' }, { label: 'Int', value: 'Int' }, { label: 'Boolean', value: 'Boolean' }, { label: 'File', value: 'File' } ], cmdRCOptOptions: [ { label: 'Continue running', value: 0 }, { label: 'Command failed,stop running', value: 1 }, { label: 'Command failed,continue running', value: 2 } ], editFrom: { softwareName: '', version: '', projectName: '', // applicationName: '', patchCommands: '', maxRunTime: 90, startStopService: '', debugEnable: true, defaultMsicLine: '', uDriveMap: false, function: 'Install', ifsScript: false, remarks: '', scriptList: [] }, editFrom2: { softwareName: '', version: '', projectName: '', // applicationName: '', patchCommands: '', maxRunTime: 90, startStopService: '', debugEnable: true, defaultMsicLine: '', uDriveMap: false, function: 'Install', ifsScript: false, remarks: '', scriptList: [] }, scriptList: [], rules: { softwareName: [{ required: true, message: 'Please input Software Name', trigger: 'blur' }], version: [{ required: true, message: 'Please input Version', trigger: 'blur' }], projectName: [{ required: true, message: 'Please input Project Name', trigger: 'blur' }], // applicationName: [{ required: true, message: 'Please input Application Name', trigger: 'blur' }], patchCommands: [{ required: true, message: 'Please input Patch Commands', trigger: 'blur' }], maxRunTime: [{ required: true, message: 'Please input Max Run Time', trigger: 'blur' }], startStopService: [{ required: true, message: 'Please input Start Stop Service', trigger: 'blur' }], debugEnable: [{ required: true, message: 'Please input Debug Enable', trigger: 'blur' }], defaultMsicLine: [{ required: true, message: 'Please input Default MSIC Line', trigger: 'blur' }], uDriveMap: [{ required: true, message: 'Please input U-Drive Map', trigger: 'blur' }], function: [{ required: true, message: 'Please input Function', trigger: 'blur' }], ifsScript: [{ required: true, message: 'Please input IFS Script', trigger: 'blur' }] }, paramsIndex: 1, searchScriptName: '', overFlag: {} }) const getParamsName = (index) => { return `Param Name ${index + 1}` } const getParamsRules = (name) => { let msg = `Please input ${name}` let tips = [{ required: true, message: msg, trigger: 'blur' }] return tips } const validator = (rule, value, callback) => { if (value && value.length > 0) { callback() // 表示驗證通過 } else { callback(new Error('length>0')) } } const deleteMethod = (index) => { const newArray = state.editFrom.scriptList.filter((element, index2) => index2 !== index) state.editFrom.scriptList = newArray state.editFrom.scriptList.forEach((val, index) => { val.orderNum = index + 1 }) } const SubmitList = (checkData) => { vxeList.checkList = checkData } // 數(shù)據(jù)提交 const handleDrawerSubmit = async () => { addFormRef.value.validate(async (valid) => { if (valid) { const data = { ...state.editFrom } console.log(data) const res = await gClientManagementApi.add(data) if (res.code === 200) { resetForm(addFormRef.value) handleDrawerClose() ctx.emit('handleSearch') ElMessage({ showClose: true, message: res.message, type: 'success' }) } else { ElMessage({ showClose: true, message: res.message, type: 'error' }) } } else { console.log('error submit!') return false } }) } // Drawer 打開時觸發(fā) const handleDrawerOpened = () => { getScriptList() } // Drawer 關閉 const handleDrawerClose = () => { state.editFrom = JSON.parse(JSON.stringify(state.editFrom2)) ctx.emit('handleClose', 'Add') } const dragstart = (event, item) => { // console.log(event, item) // 使用 dataTransfer 對象傳遞JSON數(shù)據(jù)作為文本 event.dataTransfer.setData('text/plain', JSON.stringify(item)) } const dragend = (event, item) => { state.overFlag = {} } const dragOver = (event, name) => { // 阻止瀏覽器默認操作,允許drop事件發(fā)生 event.preventDefault() state.overFlag = {} state.overFlag[name] = true // console.log(state.overFlag) } const drop = (event, index) => { // 阻止瀏覽器默認操作 event.preventDefault() // 獲取傳遞的JSON數(shù)據(jù) const jsonData = event.dataTransfer.getData('text/plain') // 解析JSON數(shù)據(jù) const data = JSON.parse(jsonData) state.overFlag = {} state.editFrom.scriptList.splice(index, 0, data) state.editFrom.scriptList = JSON.parse(JSON.stringify(state.editFrom.scriptList)) state.editFrom.scriptList.forEach((val, index) => { val.orderNum = index + 1 }) console.log('get', state.editFrom.scriptList) } // 表單 Reset const resetForm = (formEl) => { if (!formEl) return formEl.resetFields() state.editFrom = JSON.parse(JSON.stringify(state.editFrom2)) } const handleBlur = () => { // console.log('1111', state.editFrom.scriptList) } const getScriptList = async () => { // console.log(columns.value) // console.log(exportColumns.value) // 條件檢索 const query = removeProperty(JSON.parse(JSON.stringify({ scriptName: state.searchScriptName }))) console.log(query) const res = await gClientApi.getDownLoadData({ ...query }) if (res.code === 200) { const _arr = res.data.map((item) => { let paramslist = [] if (item.paramsNameList && item.paramsNameList.length > 0) { item.paramsNameList.map((element) => { if (null !== element.value && undefined !== element.value && '' !== element.value) { paramslist.push({ ...element }) } else { paramslist.push({ ...element, value: '', fileList: [], fileName: '', fileContent: '' }) } }) } item.paramslist = paramslist item.gClientScriptId = item.id let _item = { ...item } return _item }) state.scriptList = JSON.parse(JSON.stringify(_arr)) // ElMessage({ // message: res.message, // type: 'success' // }) } else { ElMessage({ message: res.message, type: 'error' }) } } // 上傳圖片驗證 const beforeAvatarUpload = (file, item, index) => { // 校檢文件類型 if (state.upload.accept) { // 文件后綴名 let fileExtension = '' if (file.name.lastIndexOf('.') > -1) { fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1) } const isTypeOk = state.upload.accept.indexOf(fileExtension) > -1 if (!isTypeOk) { ElMessage({ showClose: true, message: `The file format is incorrect. Please upload the file in ${state.upload.accept} format!`, type: 'error' }) return false } } // 校檢文件大小 if (state.upload.fileSize) { const isLt = file.size / 1024 / 1024 < state.upload.fileSize if (!isLt) { ElMessage({ showClose: true, message: `The uploaded file size cannot exceed ${state.upload.fileSize} MB!`, type: 'error' }) return false } } return true } // 文件個數(shù)超出 const handleExceed = (files, uploadFiles, item, index) => { ElMessage({ showClose: true, message: `The number of uploaded files cannot exceed ${state.upload.limit} !`, type: 'error' }) } // 文件上傳成功時的鉤子 const handleUploadSuccess = (res, item, index) => { switch (res.code) { case 200: item.fileContent = res.data.fileContent item.fileName = res.data.fileName item.value = res.data.fileName // ruleForm.systemScreenshot = res.data.filePath ElMessage({ showClose: true, message: res.message, type: 'success' }) break case 401: Session.clear() window.location.reload() break case 403: Session.clear() window.location.reload() break default: ElMessage({ showClose: true, message: res.message, type: 'error' }) } } // 文件列表移除文件時的鉤子 const handleRemove = (uploadFile, uploadFiles, item, index) => { item.fileList = [] item.fileContent = '' item.fileName = '' item.value = '' } // 點擊文件列表中已上傳的文件時的鉤子 const handlePreview = (uploadFile, item, index) => { // ctx.emit('downScriptFile', item) } const handleChange = (value, item) => { console.log(value, item) } const fileChange = (name, item) => { addFormRef.value.validateField(name, (val) => { if (!val) { return true } else { return false } }) } const remarkHTML = (remark) => { // return remark.replace(/\r\n/g, ' ').replace(/\n/g, ' ').replace(/\s/g, ' '); if (remark) { return remark.replace(/\n|\r\n/g, ' ').replace(/ /g, ' ') } return '' } onMounted(() => {}) return { ...toRefs(state), ...toRefs(vxeData), ...toRefs(vxeList), ...toRefs(useTableHeader), addFormRef, handleDrawerOpened, handleDrawerClose, handleDrawerSubmit, SubmitList, getParamsName, getParamsRules, deleteMethod, resetForm, getScriptList, dragstart, dragOver, drop, dragend, handleBlur, validator, beforeAvatarUpload, handleExceed, handleUploadSuccess, handleRemove, handleChange, handlePreview, fileChange, remarkHTML } } } </script> <style lang="scss"> .scriptDraweAdd { // .setting-title { // font-size: var(--el-form-label-font-size); // color: var(--el-text-color-regular); // height: 32px; // line-height: 32px; // padding: 0 12px 0 0; // box-sizing: border-box; // font-weight: bold; // } .drawer_title { font-weight: bold; margin-bottom: 16px; } .name-parent { display: flex; .title { font-weight: bold; width: 5px; height: 30px; margin-right: 5px; background-color: var(--color-primary) !important; } .blank { font-weight: bold; width: 5px; height: 30px; margin-right: 5px; } .label { flex: 1; } } .title { font-weight: bold; width: 5px; height: 30px; margin-right: 5px; background-color: var(--color-primary) !important; } .no-label .el-form-item__label { display: none; } .custom-row-height { /* 使用calc()函數(shù)從100vh中減去100px */ // height: calc(100vh - 600px); min-height: 400px; .searchdiv { flex: 1; height: 100%; padding: 5px; border-radius: 4px; border: 1px solid #cccccc; box-sizing: border-box; .paramslabel { margin-top: 10px; display: flex; /* 啟用Flexbox布局 */ flex-direction: column; /* 子元素縱向排列 */ justify-content: center; /* 子元素在父容器內(nèi)水平居中(縱向上的居中) */ align-items: center; /* 子元素在父容器內(nèi)水平居中(橫向上的居中) */ .buttondiv { width: 60%; // min-width: 290px; max-width: 300px; height: 30px; margin: 7px; color: var(--color-primary) !important; background-color: #fff; border: 2px solid var(--color-primary); } } } .flowdiv { min-width: 500px; flex: 1; height: 100%; padding: 5px; border-radius: 4px; border: 1px solid #cccccc; box-sizing: border-box; .deletebutton { width: 48px; height: 32px; color: #606266 !important; .deleteline { width: 40px; height: 32px; color: #606266 !important; } } .flowlabel { margin-top: 10px; display: flex; /* 啟用Flexbox布局 */ flex-direction: column; /* 子元素縱向排列 */ justify-content: center; /* 子元素在父容器內(nèi)水平居中(縱向上的居中) */ align-items: center; /* 子元素在父容器內(nèi)水平居中(橫向上的居中) */ .add-contain-div { margin: -5px 5px -5px 5px; height: 60px; // background-color: var(--color-primary) !important; position: relative; .addline { position: absolute; width: 100%; height: 100%; color: #606266; } .addicon { position: absolute; width: 40%; height: 40%; color: #606266; margin-left: 130px; margin-top: 17px; } } .add-contain-div-active { border: 1px dashed var(--color-primary); } .buttondiv { width: 300px; height: 30px; margin: 5px; color: var(--color-primary) !important; background-color: #fff; border: 2px solid var(--color-primary); } .buttondiv2 { width: 250px; height: 30px; margin: 5px; color: var(--color-primary) !important; background-color: #fff; border: 2px solid var(--color-primary); &:hover { border: 2px solid var(--el-color-primary); background-color: var(--el-color-primary) !important; color: #fff !important; } &:active, &:focus { background-color: var(--color-primary) !important; color: #fff !important; } } // .deletediv{ // float:right; // right:0px; // width:auto; // } } } } .paramsdiv { min-width: 500px; flex: 1 1 0%; height: 100%; border-radius: 2px; border: 1px solid #cccccc; box-sizing: border-box; margin-left: 0px; padding-bottom: 25px; margin-bottom: 20px; margin-right: 0px; .paramsdiv-content { padding: 5px; .paramsdiv-params { margin-bottom: 30px; } } .params-title-parent { padding: 5px 5px 5px 5px; display: flex; justify-content: space-between; /* 如果需要,可以添加以下樣式以確保父 div 占據(jù)整個寬度 */ width: 100%; border-bottom: 1px solid rgb(230, 230, 230); background-color: #fbfbfb; margin-bottom: 20px; .child { /* 你可以根據(jù)需要添加子 div 的樣式 */ } .left { /* 你可以在這里添加左邊子 div 的特定樣式 */ } .right { /* 你可以在這里添加右邊子 div 的特定樣式 */ } } } } </style>
到此這篇關于vue elementUI Plus實現(xiàn)拖拽流程圖,不引入插件,純手寫實現(xiàn)。的文章就介紹到這了,更多相關vue elementUI Plus拖拽流程圖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vue中v-for和v-if不能在同一個標簽使用的最新解決方案
這篇文章主要介紹了vue中v-for和v-if不能在同一個標簽的最新解決方案,這里描述了兩種解決方案,結合實例代碼給大家介紹的非常詳細,需要的朋友可以參考下2023-07-07vue?props使用typescript自定義類型的方法實例
這篇文章主要給大家介紹了關于vue?props使用typescript自定義類型的相關資料,文中通過實例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2023-01-01vue3實現(xiàn)模擬地圖站點名稱按需顯示的功能(車輛模擬地圖)
最近在做車輛模擬地圖,在實現(xiàn)控制站點名稱按需顯示,下面通過本文給大家分享vue3實現(xiàn)模擬地圖站點名稱按需顯示的功能,感興趣的朋友跟隨小編一起看看吧2024-06-06實例分析vue循環(huán)列表動態(tài)數(shù)據(jù)的處理方法
本篇文章給大家詳細分享了關于vue循環(huán)列表動態(tài)數(shù)據(jù)的處理方法以及相關知識點內(nèi)容,有需要的朋友們參考下。2018-09-09