vue3.x

vue+jsPlumb实现业务流程图

2020-09-01  本文已影响0人  WebGiser

先上效果图

image.png

1、vue引入jsPlumb

import jsPlumb from 'jsplumb'
window.jsplumb = jsPlumb.jsPlumb;

2、使用jsPlumb动态绘制流程图

<template>
    <div id="stageListId">

    </div>
</template>

<script>
    import Vue from 'vue'

    export default {
        name: 'stageList',
        data() {
            return {
                jsPlumbInstance:'',
                setting: {
                    anchors: ["Right", "Left"],
                    endpoint: ["Dot", { radius: 3}],
                    dragOptions: { cursor: 'pointer'},
                    connector: ["Flowchart"],      //Bezier
                    paintStyle: { stroke: "green", strokeWidth: 5 },
                    endpointStyle: {
                        fill: "#ff0000",
                        outlineStroke: "#ff0000",
                        outlineWidth: 1,
                        width: 5,
                        length: 5
                    },
                    overlays: [["Arrow", { width: 15, length: 15, location: 1 }]],
                    isSource: true,
                    isTarget: true,
                    maxConnections: -1,
                    connectorStyle: {
                        gradient: {
                            stops: [[3, "#00ff00"]]
                        },
                        strokeWidth: 2,
                        stroke: "#00ffff"
                    },
                    connectorOverlays: [
                        //["Label", { label: "", id: "label", cssClass: "labelStyle" }],
                        ["Arrow", { width: 15, length: 15, location: 1 }]
                    ]
                },

                menuAction: '',
                menuSelectedId: '',
            }
        },
        mounted() {
            let _this = this;
            this.jsPlumbInstance = jsPlumb.getInstance({
                Container:"stageListId"
            });

            Bus.$on('addOneStage',(params)=>{
                let stageAddForm = params.stageAddForm;
                let divId = _this.addOneNewStageDiv(stageAddForm);
                _this.$nextTick(()=>{
                    _this.jsPlumbInstance.addEndpoint(divId,{anchor: "Left", uuid:divId+"_l"}, _this.setting);
                    _this.jsPlumbInstance.addEndpoint(divId,{anchor: "Right", uuid:divId+"_r"}, _this.setting);
                    _this.jsPlumbInstance.draggable(divId,{
                        containment: true
                    });
                    if(_this.menuAction != '' && _this.menuSelectedId != ''){
                        switch(_this.menuAction){
                            case 'addBefore':
                                _this.jsPlumbInstance.connect({
                                    uuids:[divId+"_r", _this.menuSelectedId+"_l"]
                                }, _this.setting);
                                break;
                            case 'addAfter':
                                _this.jsPlumbInstance.connect({
                                    uuids:[_this.menuSelectedId+"_r", divId+"_l"]
                                }, _this.setting);
                                break;
                        }
                    }
                });
            });
        },
        methods: {
            addOneNewStageDiv(data){
                let _this = this;
                let id = data.id;
                const stageVue = Vue.extend({
                    template: `
                                <div :style="stageDivClass" id="${id}" @click="stageDivClick">
                                    <div :style="headClass" class="commonStageClass">
                                        <span>{{stageData.name}}</span>
                                        <span :style="menuImgClass" @click="menuClick"><img src="image/menu.png"></span>
                                    </div>
                                    <div :style="descClass">
                                        <span>阶段目标</span>
                                        <span>{{stageData.target}}</span>
                                    </div>
                                    <div :style="descClass">
                                        <span>任务描述</span>
                                        <span>{{stageData.desc}}</span>
                                    </div>
                                    <div :style="menuClass"" v-show="menuShow">
                                        <div @click="addBefore" :style="menuItemClass">在前面新增</div>
                                        <div @click="addAfter" :style="menuItemClass">在后面新增</div>
                                        <div @click="stageInfo" :style="menuItemClass">详情</div>
                                        <div @click="stageUpdate" :style="menuItemClass">修改</div>
                                        <div @click="stageDelete" :style="menuItemClass">删除</div>
                                    </div>
                                </div>`,
                    data() {
                        return {
                            menuShow: false,
                            stageData: data,
                            stageDivClass:{
                                position: 'absolute',
                                left: '200px',
                                top: '200px',
                                width: '180px',
                                height: '180px',
                                border: '1px solid #000000',
                                backgroundColor: '#ccc',
                                cursor: 'move'
                            },
                            menuImgClass:{
                                float: 'right',
                                cursor: 'pointer'
                            },
                            headClass:{
                                padding: '5px 0px',
                                backgroundColor: 'rgb(65 200 214)',
                                color: '#ffffff'
                            },
                            descClass: {
                                color: '#000000'
                            },
                            menuClass:{
                                position: 'absolute',
                                right: '3px',
                                top: '33px',
                                zIndex: '100',
                                padding: '8px',
                                backgroundColor: '#ffffff'
                            },
                            menuItemClass:{
                                cursor: 'pointer'
                            }
                        }
                    },
                    mounted() {

                    },
                    methods: {
                        stageDivClick(){
                            _this.menuSelectedId = id;
                            _this.$store.commit('changeStageId', id);
                            let elemArr = document.getElementsByClassName('commonStageClass');
                            for(let i=0,len=elemArr.length; i<len; i++){
                                if(elemArr[i].parentNode.id == _this.menuSelectedId){
                                    elemArr[i].style.backgroundColor = '#ff0000';
                                    elemArr[i].parentNode.style.border = '1px solid #ff0000';
                                }else{
                                    elemArr[i].style.backgroundColor = 'rgb(65 200 214)';
                                    elemArr[i].parentNode.style.border = '1px solid #000000';
                                }
                            }
                        },
                        menuClick(){
                            _this.menuSelectedId = id;
                            this.menuShow = !this.menuShow;
                        },
                        addBefore(){
                            this.menuShow = false;
                            _this.menuAction = 'addBefore';
                            Bus.$emit("openStageAddForm");
                        },
                        addAfter(){
                            this.menuShow = false;
                            _this.menuAction = 'addAfter';
                            Bus.$emit("openStageAddForm");
                        },
                        stageInfo(){
                            this.menuShow = false;
                            Bus.$emit('openStageDetail');
                        },
                        stageUpdate(){
                            this.menuShow = false;

                        },
                        stageDelete(){
                            this.menuShow = false;
                        }
                    }
                });
                let divElem = document.createElement("div");
                document.getElementById("stageListId").appendChild(divElem);
                new stageVue().$mount(divElem);
                return id;
            }
        }
    }
</script>

<style scoped>
    #stageListId{
        position: absolute;
        top: 1%;
        left: 1%;
        width: 98%;
        height: 98%;
        z-index: 100;
        background-color: #ffffff;
    }
</style>
上一篇 下一篇

猜你喜欢

热点阅读