gooflow 自定义流程图-程序员宅基地

技术标签: js  

demo链接:https://pan.baidu.com/s/1mJ46mlh8v2Q1XnZ8i5DceQ 密码:0lra

注意:本地直接打开会报错。

不支持 file地址: Uncaught DOMException: Blocked a frame with origin "null" from accessing a cross-origin frame.at init (file:///C:/Users/24950/Desktop/gooflow/gooflow.html?size=big&edit=true:122:31)

在webstrom中打开即可。http://localhost:63342/Desktop/gooflow/index.html

 

流程图原理:

①gooflow相关页面,功能倒入项目。初始化流程图,页面封装流程图展示,数据获取,保存,复制等功能

②页面创建2个iframe窗口分别指向gooflow.html

    1、小窗口展示流程图缩略图不可编辑,可放大

    2、大窗口全屏观看,可编辑,可缩小

    3、放大功能即打开big iframe,  缩小即关闭big iframe。 可否编辑功能控制流程图上面的遮罩层 show/hide

③公共js封装流程图相关方法

    1、流程图后台数据获取,保存等

    2、iframe跨页面操作

// 父 --> 子   loadData:子页面方法
document.getElementById("iframe").contentWindow.loadData(data.json, data.currentNodes);
document.getElementById("bigiframe").contentWindow.loadData(data.json, data.currentNodes);

// 子 --> 父  
var _iframe = window.parent;
var _iframe_big_div =_iframe.document.getElementById('parDiv');
_iframe_big_div.style.display = 'none';

window.parent.document.getElementById("bigiframe").contentWindow.jsondata=data.json;

 

代码示例仅展示一部分,详细请下载代码查看!

gooflow.html: 流程图页面

<!DOCTYPE html>
<html xmlns:v="urn:schemas-microsoft-com:vml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>jQuery网页在线流程图</title>
    <meta name="keywords" content="在线流程图,GooFlow流程图">
    <META HTTP-EQUIV="pragma" CONTENT="no-cache">
    <META HTTP-EQUIV="Cache-Control" CONTENT="no-cache, must-revalidate">
    <META HTTP-EQUIV="expires" CONTENT="0">
    <link rel="stylesheet" type="text/css" href="gooflow/common.css">
    <!--[if lt IE 9]>    <?import namespace="v" implementation="#default#VML" ?><![endif]-->
    <link rel="stylesheet" type="text/css" href="gooflow/GooFlow2.css">
    <link rel="stylesheet" type="text/css" href="gooflow/default.css">
</head>

<body>

    <div id="demo"></div>
    <textarea id="result" row="6" style="display: none;"></textarea>
    <div class="role_info">
        <input id="role_info_name"/>
        <input id="role_info_role"/>
        <input id="role_info_limit"/>
        <input id="role_info_role_val"/>
        <input id="role_info_limit_val"/>
    </div>

    <!-- 节点编辑 -->
    <div class="shade_edit_disabled"></div>
    <div class="shade"></div>
    <div class="pop pop_node">
        <div class="pop_h"><span class="pop_h_title"><span class="line"></span>节点编辑</span><span class="close" onclick="nodeClose()"></span></div>
        <div class="pop_cont">
            <div class="pop_cont_box">
                <p class="title"><span class="line"></span>基本信息</p>
                <div class="pop_one pop450_span4"><span class="xing">*</span><div class="ipt_box"><i>节点名称:</i><input type="text" id="node_name"></div></div>
                <div class="pop_one pop450_span4"><span class="xing">*</span><div class="ipt_box"><i>节点角色:</i>
                    <select id="node_role" class="poprole">
                        <!--<option value="0">团队成员</option>-->
                        <!--<option value="1">团队负责人</option>-->
                        <!--<option value="2">质控负责人</option>-->
                    </select>
                </div></div>
                <p class="title mar_top20"><span class="line"></span>选择节点权限</p>
                <div class="pop_one  select_mb">
                    <span class="xing">*</span>
                    <div class="ipt_box">
                        <ul class="select_com_ul" id="node_limit">
                            <li><input class="ipt1" value="1" name="node_limit" type="radio"><span class="sel_name">立项管理</span></li>
                            <li><input class="ipt1" value="5" name="node_limit" type="radio"><span class="sel_name">立项申请</span></li>
                            <li><input class="ipt1" value="9" name="node_limit" type="radio"><span class="sel_name">质评管理</span></li>
                            <li><input class="ipt1" value="16" name="node_limit" type="radio"><span class="sel_name">投票</span></li>
                            <li><input class="ipt1" value="17" name="node_limit" type="radio"><span class="sel_name">内核委员</span></li>
                            <li><input class="ipt1" value="18" name="node_limit" type="radio"><span class="sel_name">内核主任</span></li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
        <div class="btn_box">
            <span class="btn btn_cancle" onclick="nodeClose()">取消</span>
            <span class="btn btn_sure" id="node_save">确定</span>
        </div>
    </div>

    <!-- 编辑流程图页面 遮罩层 -->
    <div class="shade_big_disabled"></div>

<!--<script type="text/javascript" src="gooflow/jquery.js"></script>-->
<script type="text/javascript" src="../js/jquery-1.8.2.min.js"></script>
<script type="text/javascript" src="gooflow/data2.js"></script>
<script type="text/javascript" src="gooflow/GooFunc.js"></script>
<script type="text/javascript" src="gooflow/json2.js"></script>
<script type="text/javascript" src="gooflow/GooFlow.js"></script>
<script type="text/javascript" src="../js/layer/layer.js"></script>
<script>
    var demo, out, width, height, GooFlow_work_auto = false, scale = 1,headBtns, popRole, roles,
            node_name, node_role , node_limit, node_role_val, node_limit_val;
    $(document).ready(function(){
        init();
        listAuthority();
    });

    //  页面初始化
    function init(){
        var url = window.location.href;
        if(url.indexOf("small") > 0){   // 小窗口流程图展示
            scale = 1;
            width= 735;
            height= 345;
            GooFlow_work_auto = true;
            headBtns = ["save", "undo", "redo","copy","enlarge"];
            $(".shade_edit_disabled").show();
        }
        if(url.indexOf("big") > 0){ // 大窗口流程图展示
            scale = 2;
            var _iframe = window.parent;
            var _div =_iframe.document.getElementById('parDiv');
            var width = $(_div).width();
            var height = $(_div).height();
            headBtns = ["save", "undo", "redo","copy","narrow"];
            $(".shade_edit_disabled").hide();
        };

        // 系统管理-流程管理页面  遮罩层隐藏流程图可编辑,其他页面遮罩层默认显示流程图不可编辑
        if(url.indexOf("edit") > 0){ $(".shade_big_disabled").hide(); }

        var property = {
            width: width,
            height: height,
            scale: scale,
            toolBtns: ["start round", "end round", "task"],
            haveHead: true,
            headBtns: headBtns,
            //如果haveHead=true,则定义HEAD区的按钮
            haveTool: true,
            haveGroup: true,
            useOperStack: true
        };
        var remark = {
            cursor: "选择指针",
            direct: "结点连线",
            start: "开始结点",
            "end": "结束结点",
            state: "状态结点",
            node: "自动结点",
            chat: "决策结点",
            plug: "附加插件",
            fork: "分支结点",
            "join": "联合结点",
            "task": "任务结点",
            "complex mix": "复合结点",
            group: "组织划分框编辑开关"
        };
        demo = $.createGooFlow($("#demo"), property);
        demo.setNodeRemarks(remark);
//        demo.clearData();
        demo.loadData(jsondata);



        // 小弹窗 流程图禁止滚轮
        if(GooFlow_work_auto){ $(".GooFlow_work").css("overflow","hidden"); }

        roles = getRoles();
        for(var i=0;i<roles.length;i++){
            popRole+='<option value="'+ roles[i].role_id +'">'+roles[i].role_name+'</option>';
        }
        $("#node_role").append(popRole);


        //  线程方向弹框
        var popDirect = '<ul class="popdirect"><li>同意</li><li>拒绝</li><li>弃权</li></ul>';
        $(".GooFlow").append(popDirect);
        $(".poprole li").click(function(){
            $(".poprole li").removeClass("active");
            $(this).addClass("active");
            $("textarea").val($(this).html() +"  ");
            $(".poprole").hide();
        });
        $(".popdirect li").click(function(){
            $(".popdirect li").removeClass("active");
            $(this).addClass("active");
            $("textarea").val($(this).html() +"  ");
            $(".popdirect").hide();
        });
        
    }

    // 导出数据
    function Export() {
//        console.log(demo.exportData());
        document.getElementById("result").value = JSON.stringify(demo.exportData());
//         console.log(document.getElementById("result").value);
        return document.getElementById("result").value;
    }

    // 获取角色
    function getRoles(){
        var roles;
        $.ajax({
            url:"../role/getAllRoles",
            type: 'POST',
            async:false,
            success:function(data){
                if(data.ret.succeed){
                    roles=data.list;
                }else{
                    layer.msg(data.ret.retMsg);
                }
            }
        });
        return roles;
    }

    //  加载流程图数据  渲染流程图
    function loadData(json,currentNodes){
    	console.log(json);
    	
    	demo.clearData(); demo.loadData(json,currentNodes);  }
    // 清除流程图数据
    function clearData(){ demo.clearData(); }

    //  流程图 放大,缩小功能
    function enlarge(){
        var _iframe = window.parent;
        var _div =_iframe.document.getElementById('parDiv');
        _div.style.display = 'block';
        Export();

    }
    
    function narrow(){
        var _iframe = window.parent;
        var _iframe_big_div =_iframe.document.getElementById('parDiv');
        _iframe_big_div.style.display = 'none';
        // 大的流程编辑 缩放时  将数据保存到本地 以供小的流程图预览实时 显示最新流程
        var data = Export();
        localStorage.setItem("jsondata",data);
        if(window.location.href.indexOf("edit")>0)
        	window.parent.lcsave();
    }

	function copyFlowModel(modelId){
        $.ajax({
            url:"../workflowModel/getWithJson",
            data:{"id":modelId},
            type: 'POST',
            success:function(data){
                if(data.ret.succeed){
                	console.log(data.json);
                	jsondata=data.json;
            		if(window.parent.document.getElementById("bigiframe")!=undefined&&window.parent.document.getElementById("bigiframe")!=null){
            			window.parent.document.getElementById("bigiframe").contentWindow.jsondata=data.json;
            		}
                	layer.msg("成功复制到创建面板");
                }else{
                    layer.msg(data.ret.retMsg);
                }
            }
        });
	}
    
	function loadCopy(){
		loadData(jsondata);
		Export();
		
		
		if(window.parent.document.getElementById("bigiframe")!=undefined&&window.parent.document.getElementById("bigiframe")!=null){
			console.log(window.parent.document.getElementById("bigiframe"));
			console.log('jsondata= '+jsondata);
			window.parent.document.getElementById("bigiframe").contentWindow.loadData(jsondata);
			window.parent.document.getElementById("bigiframe").contentWindow.Export();
		}
	}
	
	function bindCopy(modelId){
		$("#copy").click(function(){
			copyFlowModel(modelId);
		});
	}
	
	function unbindCopy(modelId){
		$("#copy").unbind();
	}
    //  节点窗口按钮操作
    function nodeClose(){
        $(".shade,.pop_node").hide();
    }

    // 双击获取节点信息
    function getNodeInfo(id){
        var jsonDate = JSON.parse( JSON.stringify(demo.exportData()));
        var nodeInfo  = jsonDate.nodes[id];
        $("#node_name").val(nodeInfo.name);
        $("#node_role").val(nodeInfo.role);
        $('#node_limit input').prop("checked",false);
        $('#node_limit input[value="'+ nodeInfo.limit +'"]').prop("checked",true);
    }

    
    function listAuthority(){
    	$.ajax({
            url:"../authority/getDiffAuthority",
            type: 'POST',
            async:false,
            success:function(data){
                if(data.ret.succeed){
                    var authorities=data.clist;
                    $('#node_limit').empty(); 
                    for(var i=0;i<authorities.length;i++){
                    	var authority=authorities[i];
                    	var html='<li><input class="ipt1" value="'+authority.authority_short_name+'" name="node_limit" type="radio"><span class="sel_name">'+authority.authority_name+'</span></li>'
                    	$('#node_limit').append(html);
                    }
                }else{
                    layer.msg(data.ret.retMsg);
                }
            }
        });
    }
</script>

</body>
</html>

data2.js:  流程图数据结构示例,默认此数据展示

GooFunc.js,json2.js:  流程图默认设置,无需更改

GooFlow.js: 流程图功能,展示相关,可自行优化项目需要

上面百度云项目优化的地方:

①头部,左侧按钮的优化

②  添加节点  样式控制

③节点,连线  单击双击事件,与节点信息弹框相关联

//绑定双击编辑事件
this.$workArea.delegate(".GooFlow_item > .span","dblclick",{inthis:this},function(e){
	var oldTxt=this.innerHTML;
	var This=e.data.inthis;
	var id=this.parentNode.id;
	var t=getElCoordinate(This.$workArea[0]);

	// 结束节点 禁止打开弹框
	if(oldTxt.indexOf("归档") > 0) return;

	This.$textArea.data("id",This.$focus).focus();
	This.$workArea.parent().one("mousedown",function(e){    // 仅第一次双击不触发
		if(e.button==2)return false;
		This.$textArea.data("id",This.$focus).focus();
		node_name = $("#node_name").val();
		node_role = $("#node_role").val();
		node_limit = $("#node_limit input:checked").val();
		node_role_val = $('#node_role option[value="'+node_role+'"]').html();
		node_limit_val = $('#node_limit input[value="'+node_limit+'"]').siblings("span").html();
		This.setName(This.$textArea.data("id"),node_name,"node", node_role, node_role_val, node_limit,node_limit_val);
		This.$textArea.val("").removeData("id").hide();
		$(".shade,.pop_node").hide();
	});

	// 角色弹框  圆圈按钮角色选择
	$(".shade,.pop_node").show();
	getNodeInfo(This.$textArea.data("id"));
	$(".pop_node .btn_sure").click(function(e){
		if(e.button==2)return false;
		node_name = $("#node_name").val();
		node_role = $("#node_role").val();
		node_limit = $("#node_limit input:checked").val();
		node_role_val = $('#node_role option[value="'+node_role+'"]').html();
		node_limit_val = $('#node_limit input[value="'+node_limit+'"]').siblings("span").html();
		if(!node_name) { layer.msg('请输入节点名称'); return; }
		if(!node_role) { layer.msg('请选择节点角色');  return; }
		if(!node_limit) { layer.msg('请选择节点权限'); return;  }
		This.setName(This.$textArea.data("id"),node_name,"node", node_role, node_role_val, node_limit,node_limit_val);
		This.$textArea.val("").removeData("id").hide();
		$(".shade,.pop_node").hide();
});

		});
this.$workArea.delegate(".ico + td","dblclick",{inthis:this},function(e){
	var oldTxt=this.innerHTML;
	var This=e.data.inthis;
	var id=$(this).parents(".GooFlow_item").attr("id");
	var t=getElCoordinate(This.$workArea[0]);

	This.$textArea.data("id",This.$focus).focus();
	This.$workArea.parent().one("mousedown",function(e){    // 仅第一次双击不触发
	if(e.button==2)return false;
	This.$textArea.data("id",This.$focus).focus();
	node_name = $("#node_name").val();
	node_role = $("#node_role").val();
	node_limit = $("#node_limit input:checked").val();
	node_role_val = $('#node_role option[value="'+node_role+'"]').html();
	node_limit_val = $('#node_limit input[value="'+node_limit+'"]').siblings("span").html();
	This.setName(This.$textArea.data("id"),node_name,"node", node_role, node_role_val, node_limit,node_limit_val);
	This.$textArea.val("").removeData("id").hide();
		$(".shade,.pop_node").hide();
	});

			// 角色弹框  方框按钮角色选择
	$(".shade,.pop_node").show();
	getNodeInfo(This.$textArea.data("id"));
	$(".pop_node .btn_sure").click(function(e){
		if(e.button==2)return false;
		node_name = $("#node_name").val();
		node_role = $("#node_role").val();
		node_limit = $("#node_limit input:checked").val();
		node_role_val = $('#node_role option[value="'+node_role+'"]').html();
		node_limit_val = $('#node_limit input[value="'+node_limit+'"]').siblings("span").html();
		if(!node_name) { layer.msg('请输入节点名称'); return; }
		if(!node_role) { layer.msg('请选择节点角色');  return; }
		if(!node_limit) { layer.msg('请选择节点权限'); return; }
		This.setName(This.$textArea.data("id"),node_name,"node", node_role, node_role_val, node_limit,node_limit_val);
		This.$textArea.val("").removeData("id").hide();
		$(".shade,.pop_node").hide();
	});

});

1.小窗口预览

<iframe class="spinfo sp_lc" src="gooflow.html?size=small" name="iframe" id="iframe" frameborder="no" scrolling="no"></iframe>

2.全屏大窗口查看  可编辑

// 流程图大窗口  在公共js里添加,不需要每个html页面都添加一次
if (window.location.href.indexOf("xtgl_lcgl") > 0) {  // 流程图可编辑大窗口
	var popBigLcDiv = '<div class="pop_big_lc" id="parDiv"><iframe name="bigiframe" id="bigiframe" class="spinfo sp_lc" src="gooflow.html?size=big:edit=true" frameborder="no" scrolling="no"></iframe></div>';
} else {    // 流程图不可编辑大窗口
	var popBigLcDiv = '<div class="pop_big_lc" id="parDiv"><iframe name="bigiframe" id="bigiframe" class="spinfo sp_lc" src="gooflow.html?size=big" frameborder="no" scrolling="no"></iframe></div>';
}

3.全屏大窗口  每个节点编辑

iframe 跨页面操作示例如下:

父页面操作子页面:

// 流程图 保存
function lcsave() {
	var datajson = JSON.parse(localStorage.getItem("jsondata"));
	document.getElementById("iframe").contentWindow.loadData(datajson);
}
/**
 * 展示流程进度图
 */
function showCommonFlowProgress(project_id, type) {
	// var project_id = $("#project_name")[0].lang;
	$.ajax({
		url : "../workflowModel/getWorkflowProgress",
		data : {
			project_id : project_id,
			workflow_type : type
		},
		type : "POST",
		success : function(data) {
			if (data.ret.succeed) {
				document.getElementById("iframe").contentWindow.loadData(
						data.json, data.currentNodes);
				document.getElementById("bigiframe").contentWindow.loadData(
						data.json, data.currentNodes);
			} else {
				// layer.msg(data.ret.retMsg);
				document.getElementById("iframe").contentWindow.clearData();
				document.getElementById("bigiframe").contentWindow.clearData();
			}
		}

	});
}

子页面操作父页面:

//  流程图 放大,缩小功能
    function enlarge(){
        var _iframe = window.parent;
        var _div =_iframe.document.getElementById('parDiv');
        _div.style.display = 'block';
        Export();

    }
    
    function narrow(){
        var _iframe = window.parent;
        var _iframe_big_div =_iframe.document.getElementById('parDiv');
        _iframe_big_div.style.display = 'none';
        // 大的流程编辑 缩放时  将数据保存到本地 以供小的流程图预览实时 显示最新流程
        var data = Export();
        localStorage.setItem("jsondata",data);
        if(window.location.href.indexOf("edit")>0)
        	window.parent.lcsave();
    }

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zjl199303/article/details/80625994

智能推荐

python青果教务系统抢课_名额不够,技术来凑,利用Python实现教务系统强制性抢课...-程序员宅基地

文章浏览阅读1.3k次。最近一学期一次的抢课大戏又来了,几家欢乐几家愁。O(∩_∩)O哈哈~(l我每次一选就过了hah,我还是有欧的时候滴)。看着他们盯着教务系统就着急,何况我们那教务系统,不想说什么。emmm 想周围的朋友,正好下午利用扩容前一段时间写了个小脚本帮助朋友抢课。(当然抢到了啦,^_^)私信小编001即可获取大量Python学习资料,名额有限因为时间不够,来不及仔细琢磨,我第一想法就是直接提交选课的数据包(..._青果教务系统抢课

windows 加 switchyomega + burp 抓https包-程序员宅基地

文章浏览阅读4.6k次。很简单,下载证书后导入到受信任根目录证书下载,直接在代理状态浏览器访问burp点击CA就可以下载了 设置该证书全部信任,,switchyomega 设置如下即可 就可以抓https的包了 ...

用C语言写循环赛日程表,循环赛的方法与编排-程序员宅基地

文章浏览阅读1k次。一、循环赛的种类与特点(一)循环赛的种类循环赛又称循环法。是指参赛队(或个人,下同)之间,都要互相轮流比赛,最后按照各参赛队在全部比赛中的胜负场数、得分多少排定名次的比赛方法。它在对抗性项目比赛中经常被采用。循环赛包括单循环、双循环或分组循环三种。单循环是所有参赛队(人)相互轮赛一次;双循环是所有参赛队(人)相互轮赛二次;分组循环是参赛队(人)较多时,采用种子法,把强队(人)分散在各组,先进行小组..._c语言循环赛互打一场比赛 甲队两胜

springboot项目访问html页面,发现端口不一致&继承WebMvcConfigurationSupport类会导致自动配置失效_springboot项目前端端口号不同怎么办-程序员宅基地

文章浏览阅读1.6k次,点赞4次,收藏6次。最后的解决方法“在config--WebMvcConfig中不要继承WebMvcConfigurationSupport,而是实现WebMvcConfigurer接口”,且不要在idea中直接点击浏览器图标打开对应的html页面,要自己在浏览器输入url。在本次debug过程中,更加清楚地明白了,springboot项目启动过程中,只扫描引导类同包或子包下的程序,而在resources目录下的静态资源文件(没放到),需要被映射,才能被扫描到。_springboot项目前端端口号不同怎么办

k8s.配置管理.configmap&secret_configmap @value-程序员宅基地

文章浏览阅读80次。configmap 和secret 都需要提前创建configmap和secret都可以为pod提供挂载和变量的方式变量的方式有envfrom全部变量和valuefrom单个变量的引用configmap和secret 需要和引用的pod或者资源对象在同一个ns下。_configmap @value

System.TypeInitializationException: 'The type initializer for 'MySql.Data.MySqlClient.Replication.Re...-程序员宅基地

文章浏览阅读2.2k次。下午在调试的时候报错数据库连接就报错我就很纳闷后面用原来的代码写发现还是报错System.TypeInitializationException:'The type initializer for 'MySql.Data.MySqlClient.Replication.ReplicationManager' threw an exception.'应该是出在Mysql包上的问题..._system.typeinitializationexception:““mysql.data.mysqlclient.mysqlpoolmanag

随便推点

二、RSA加密_ctf rsa 多个n和多个c-程序员宅基地

文章浏览阅读3.4k次。CTF中的RSA及攻击方法笔记1 数论基础1.1 模运算规则2 RSA相关题目2.1 已知 n,e,c 求 m2.2 已知 p,q,e 求 d2.3 已知dp,dq,c,p,q 求m2.4 仅已知c,c特别大 【c = m^e mod n】2.5 已知n1,n2,c1,c2,n 求 m2.6 已知n1,n2,e,c2 求m2.7 已知e,d,N 求p,q1 数论基础参考链接:https://www.freebuf.com/articles/web/257835.html1.1 模运算规则模运算与基_ctf rsa 多个n和多个c

mysql中把bigint类型转换为时间格式,与hive中unix_timestamp、FROM_UNIXTIME两个函数之间的区别_bigint转日期-程序员宅基地

文章浏览阅读2w次,点赞4次,收藏15次。数据库中时间类型是这样的,13位bigInt类型的数据select date_format(FROM_UNIXTIME(列名/1000),'%Y%m%d') from xx表原理就是把13位的时间格式/1000等于时间戳,使用FROM_UNIXTIME把时间戳转换成具体的日期ps:将时间转换为时间戳select unix_timestamp('2018-08-30..._bigint转日期

exit status 5: �ܾ����ʡ� exit status 1: ���_exit status 5: exit status 1:-程序员宅基地

文章浏览阅读1.1k次。使用nvm切换node版本出现上述乱码时。使用管理员模式打开CMD就可以解决了~_exit status 5: exit status 1:

对Java和Linux的认识,Java类的认识-程序员宅基地

文章浏览阅读279次。Java使用类来构造自己的数据类型,类其实就是对一类数据和行为的数据封装;可以达到低耦合功能;Java注意啦:用类也是我们为了定义自己数据类型的一种方法,所以结构体,共用体也是一样的;都是为了处理数据而用的方法!类的存放问题: java源代码文件是以类为中心的,一个类的定义源码必须只在一个源文件实现;一个“文件名.java”文件名必须与文件中用public class 修饰的类名一致,java语法..._linux和java

快给你的Vue项目添加一个编辑图片组件吧_vue-image-editor-程序员宅基地

文章浏览阅读8.2k次,点赞20次,收藏59次。快给你的Vue项目添加一个编辑图片组件吧给大家推荐一款功能极其强大的图片编辑插件 tui.image-editor快速体验首选在你的前端项目中安装:npm i tui-image-editor// oryarn add tui-image-editor现在你就去新建一个.vue文件,复制进去下面这段代码:<template> <div id="tui-image-editor"></div></template><scr_vue-image-editor

Flutter混合开发-Null check operator used on a null value_flutter null check operator used on a null value-程序员宅基地

文章浏览阅读4.8k次。标题Flutter与Android混编在Android与Flutter混编中导入flutter的GetX框架时,配置getPages参数出错,在编译时不报错,但是运行之后,debug模式下出现红底白色的错误,错误显示为 Null check operator used on a null value,看一眼懵了,本地开发版本使用的是flutter2,配置的Getx库也确实在很早的版本中就支持了Null safety ,且配置的getPages为数组并且可为空,按照常理怎么也不可能出现这个错误!尝试的方案_flutter null check operator used on a null value

推荐文章

热门文章

相关标签