共计 2979 个字符,预计需要花费 8 分钟才能阅读完成。
成果
说在后面
因为本人有需要,想要一个能够自在拖拽排序的流程图组件,在网上没有找到适合的 demo,所以便本人动手做了这样一个雏形。
组件设计
首先须要设计好配置参数,而后就是讲配置参数融入到款式的设计解决上,最初是实现组件拖动并实时展现成果。
参数
整体参数
参数 | 形容 |
---|---|
title | 题目(String) |
dragAble | 是否可拖拽(Boolean) |
width | 图标最小宽度(number) |
radius | 是否圆角(Boolean) |
data | 流程项(Array) |
data 流程项参数
构造如下
[
{icon:require('@/assets/logo.png'),// 图标
text:'筹备'// 文字
},
{icon:require('@/assets/1.png'),
text:'开始'
},
]
性能
监听鼠标事件
// 是否可拖拽
if(this.chartData.dragAble){window.addEventListener('mouseup',this.handleMouseup);
window.addEventListener('mouseover',this.handleMouseover);
}
初始化数据
// 初始化数据
initData(){
let data = this.vChartDataList;
let res = [],flag = true,temp = [];
for(let i = 1; i <= data.length; i++){data[i - 1].id = 'item' + '-' + res.length + '-' + (i - 1);
if(flag) temp.push(data[i - 1]);
else temp.unshift(data[i - 1]);
if(i % this.itemNum == 0 || i == data.length){res.push([...temp]);
temp = [];
flag = !flag;
}
}
this.chartDataList = res;
}
拖拽性能
//item 点击事件
itemClick(index1,index,id,item){if(!this.chartData.dragAble) return;
this.selectedItem = {...item};
this.selectedItem.opacity = '0.5';
let num = parseInt(id.split('-')[2]);
let dom = document.getElementById('moveDiv');
let dom1 = document.getElementById(id);// 展现的节点
let d = document.getElementById('chartContent');
d.style.border="dashed 1px blue";
// this.vChartDataList.splice(num,1);
this.oldInd = num;
this.initData();
this.operateDom = dom;// 记录操作的节点
this.operateDomNum = num;
this.startX = dom1.offsetLeft;
this.startY = dom1.offsetTop;
dom.style.visibility = 'inherit';
dom.style.position = 'fixed';
dom.style.left = dom1.offsetLeft;
dom.style.top = dom1.offsetTop;
},
// 挪动时实时展现成果
handleMouseover(event){if(this.vChartDataList.length < this.chartData.data.length){this.vChartDataList.unshift({...this.chartData.data[0]});
}
if(this.operateDom != null){
const w = this.operateDom.offsetWidth,h = this.operateDom.offsetHeight;
let x = event.pageX,y = event.pageY;
this.operateDom.style.position = 'fixed';
this.operateDom.style.opacity = '0.5';
this.operateDom.style.left = x - w / 2 + 'px';
this.operateDom.style.top = y - h / 2 + 'px';
let {tx,ty} = this.getItemCoords(x,y);
let oldInd = this.oldInd;
if(oldInd >= 0){this.vChartDataList.splice(oldInd,1);
this.initData();}
let nty = (parseInt(ty) % 2 == 0 ? parseInt(tx) : this.itemNum - parseInt(tx));
nty = Math.min(nty,this.itemNum);
nty = Math.max(nty,0);
oldInd = parseInt(ty) * this.itemNum + nty;
oldInd = Math.min(this.chartData.data.length - 1,oldInd);
oldInd = Math.max(0,oldInd);
this.oldInd = oldInd;
if(oldInd < 0) return;
this.vChartDataList.splice(oldInd,0,{...this.selectedItem});
this.initData();}
},
// 确定最终地位
handleMouseup(event){const chartContent = document.getElementById('chartContent');
const dom = document.getElementById('moveDiv');
const w = chartContent.offsetWidth,
h = chartContent.offsetHeight,
l = chartContent.offsetLeft,
t = chartContent.offsetTop;
const x = event.pageX,y = event.pageY;
dom.style.visibility = 'hidden';
// if(x > l && x < (l + w) && y > t && y < (t + h)){//}else{//}
if(this.vChartDataList[this.oldInd]) this.vChartDataList[this.oldInd].opacity = 1;
chartContent.style.border='none';
this.operateDom = null;
this.operateDomNum = null;
this.oldInd = null;
},
代码
Gitee 地址:https://gitee.com/zheng_yongtao/jyeontu-component-warehouse
预览地址
http://jyeontu.xyz/JYeontuComponents/#/flowChartView
正文完