vue3+vue-flow实现拖拽矩形框,端点连线,自定义宽高
vue3+vue-flow实现拖拽矩形框,端点连线,自定义宽高
- 前言
- 一、下载插件
- 二、直接上代码
- 1.taskDetail.vue
- 2.读入数据
- 总结
前言
vue3+vue-flow实现拖拽矩形框,端点连线,自定义宽高
一、下载插件
"@vue-flow/background": "^1.3.2",
"@vue-flow/controls": "^1.1.2",
"@vue-flow/core": "^1.42.4",
"@vue-flow/minimap": "^1.5.2",
"@vue-flow/node-resizer": "^1.4.0",
二、直接上代码
1.taskDetail.vue
代码如下(示例):
<template><div class="app-container" style="height: calc(100vh - 100px)"><div class="taskcard-box"><el-card class="left-box" shadow="never"><!-- <TaskFlow ref="taskFlowRef" v-bind="taskFlowParams" /> --><TaskFlow ref="taskFlowRef" :detailInfo="taskFlowParams" :key="1" v-model:unusedPort="unusedPort" /></el-card><el-card class="right-box custom_right_box" shadow="never"><el-tabs type="border-card" class="demo-tabs"><el-tab-pane label="设置"><el-space direction="vertical"><el-form ref="formRef" :model="form" :rules="rules" label-width="auto"><el-form-item label="所属项目:"><!-- <SpProjectSelect v-model="project.id" url="/project/listPage" method="post" disabled /> --></el-form-item><el-form-item label="任务名称:" prop="taskName"><el-input v-model="form.taskName" placeholder="请输入任务名称" /></el-form-item><el-form-item label="宽度:"><el-input-number v-model="taskFlowParams.width" :min="800" :max="100000" /></el-form-item><el-form-item label="高度:"><el-input-number v-model="taskFlowParams.height" :min="800" :max="100000" /></el-form-item><el-form-item label="时间间隔(ms):" prop="taskInterval"><el-input-number v-model="form.taskInterval" :min="1" :max="10000000" /></el-form-item><el-form-item label="任务周期:" prop="taskType"><sp-select-dict v-model="form.taskType" dictType="task-type" /></el-form-item><el-form-item label="状态:" prop="taskStatus"><el-switch size="large" v-model="form.taskStatus" active-value="0" inactive-value="1" inline-prompt active-text="启用" inactive-text="禁用" /></el-form-item></el-form></el-space></el-tab-pane><el-tab-pane label="组件"><ComponentTree /></el-tab-pane></el-tabs><div class="btn-box"><el-button @click="back">返回</el-button><el-button type="primary" @click="save">保存</el-button></div></el-card></div></div>
</template><script setup>
import TaskFlow from "@/views/comChunk/leftContent.vue";
import ComponentTree from "@/components/componentTree/ComponentTree.vue";
import { addTaskApi, taskUpdateByIdApi, getTaskDetailByIdApi } from "@/api/flow";
import { ElMessage ,ElLoading} from "element-plus";
const route = useRoute();
const router = useRouter();
const taskFlowRef = ref();
const formRef= ref()
onMounted(() => {if (route.query.id) {form.value.id = route.query.id;getDetail();}
});
const data = reactive({form: {id: null,configJson: {height: 600,width: 1200,},taskStatus: "0",taskType: "",taskJson: {},taskName: "",taskInterval: null,},taskFlowParams: {data: {},width: 1200,height: 600,background: {color: "#fffbe6", // 设置画布背景颜色},grid: {size: 10, // 网格大小 10pxvisible: true, // 渲染网格背景},},rules: {taskName: [{ required: true, message: "任务名称不能为空", trigger: "blur" }],taskType: [{ required: true, message: "任务类型不能为空", trigger: "blur" }],taskInterval: [{required: true,type: "number",message: "时间间隔不能为空",trigger: "blur",},],},unusedPort: [],
});const { form, taskFlowParams, rules, unusedPort } = toRefs(data);const getDetail = async () => {const res = await getTaskDetailByIdApi({ id: form.value.id });if (res.code == 200 && res.data) {form.value = {...form.value ,...res.data };const edgesData = res.data?.taskJson?.cells.filter((item) => item.shape === "edge");const nodesData = res.data?.taskJson?.cells.filter((item) => item.shape !== "edge");await nextTick(() => {nodesData.forEach((item) => taskFlowRef.value?.addNodesToFlow(item));taskFlowRef.value?.addEdgesToFlow(edgesData);});// 确保 taskFlowParams 变化不会导致递归taskFlowParams.value = { ...taskFlowParams.value, width: res.data.configJson.width, height: res.data.configJson.height };}
}; /* 保存 */
let loading = ref(null);
const save = async () => {formRef.value?.validate(async (valid) => {if (!valid) return;loading.value = ElLoading.service({text: "Loading",background: "rgba(0, 0, 0, 0.7)",});try {let data = {...form.value,id: form.value?.id ? form.value.id : undefined,};let nodesData = taskFlowRef.value?.nodes;let edgesData = taskFlowRef.value?.edges;data.taskJson = await processModuleJson(nodesData, edgesData);data.configJson = {height: taskFlowParams.height || 600,width: taskFlowParams.width || 1200,};// data.imageUrl = "";console.log("form.value", form.value);console.log("data", data);console.log("data", data.id);const res = !data.id ? await addTaskApi({ ...data }) : await taskUpdateByIdApi({ ...data });console.log(res);if (res.code == 200) {ElMessage({type: "success",message: data.id ? "修改成功" : "添加成功",});router.back()}} finally {loading.value.close();}});
};/* 处理moduleJson数据 */
const processModuleJson = (nodesData, edgesData) => {let nodeArr = nodesData.map((item) => {// console.log(item);let ports = {};if (item.data.ports?.items && item.data.ports?.items.length > 0) {ports = item.data.ports;} else {ports = {groups: {in: {position: { name: "left" },}, // 你可以自定义 `in` 端口组的属性out: {lable: { position: { name: "right" } },position: { name: "right" },}, // 你可以自定义 `out` 端口组的属性},items: item.data.ports || [], // 这里存放原来的 ports 数组};}let tools = {};if (item.data.tools?.items && item.data.tools?.items.length > 0) {tools = item.data.tools;} else {tools = {items: item.data.tools,};}return {// ...item,portMarkup: [],router: {},size: {},...item.data,shape: "rect",componentId: item.data.componentId,id: item.id,ports: ports,tools: tools,position: item.position,width: item.dimensions.width,height: item.dimensions.height,};});let edgeArr = edgesData.map((item) => {return {...item,shape: "edge",source: {cell: item.source,port: item.sourceHandle,},target: {cell: item.target,port: item.targetHandle,},};});// form.value.moduleJson = {// cells: [...nodesData, ...edgesData],// };return { cells: [...nodeArr, ...edgeArr] };
};const back = ()=>{router.back()
}
</script><style lang="scss" scoped>
.taskcard-box {display: flex;justify-content: space-between;align-items: flex-start;width: 100%;height: 100%;
}
.right-box {width: 350px;height: 100%;
}
.left-box {flex: 1;max-height: calc(100vh - 100px);overflow: auto;margin-right: 10px;
}
.btn-box {display: flex;justify-content: flex-end;align-items: center;margin-top: 10px;
}
.demo-tabs {max-height: calc(100vh - 180px);overflow: scroll;
}
</style>
2.读入数据
代码如下(示例):
data = pd.read_csv('https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv')
print(data.head())
该处使用的url网络请求的数据。
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。