自定义propertiesPanel之前如果引用过原有的属性面板,则要去掉所有关于propertiesPanel引用的js与css,包括原有的属性面板模块propertiesPanelModule、propertiesProviderModule;如果还没使用过原属性面板,则直接忽略下面的官方例子;
//官方例子
import BpmnModeler from 'bpmn-js/lib/Modeler';
import propertiesPanelModule from 'bpmn-js-properties-panel';
import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda';
import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda.json';
var bpmnModeler = new BpmnModeler({
container: canvas,
propertiesPanel: {
parent: '#js-properties-panel'
},
additionalModules: [
propertiesPanelModule,
propertiesProviderModule
],
moddleExtensions: {
camunda: camundaModdleDescriptor
}
});
bpmn.js完全自定义右侧属性面板,其实就是完全自己写template组件,自由开发,最大化满足需求,所有与画布的交互全部通过Modeler的实例对象(modeler);
跟正常开发页面一样,先定义好自己的属性面板组件,传入Modeler以及其他参数进行使用;Modeler怎么自定义(CustomModeler)的请看这里:
template部分:
<el-form>
<el-form-item>
<div ref="paletteBox" class="palette-box"></div>
<div ref="bpmnbox" class="canvas-box"></div>
<custom-properties-panel
ref="propertiesPanel"
:modeler="awaitModeler"
:queryData="queryData"
/>
</el-form-item>
</el-form>
js部分:
import customPropertiesPanel from './properties-panel';
export default {
components:{
customPropertiesPanel
},
data(){
return {
xml:'',
modeler:"",
awaitModeler:'',
queryData:"",
type:'create'
}
},
computed:{
queryData(){
return {
formId: '',
flowId: ''
}
},
},
async mounted(){
await this.getXml()
await this.getModelerInit()
this.createModifyDiagram()
},
methods:{
async getXml(){
this.xml = this.type=='create'?"" : await this.$axios({url:'getXmlDatasUrl',method:'post'...})
},
async getModelerInit(){
this.modeler = await this.getModeler()//自定义Modeler的方法上面有了
},
async createModifyDiagram() {
if(!this.xml) {
//新建
let processId = 'process_'+Math.random()
this.xml = await (require('@/components/bpmnProcess/plugins/newDiagram').default)(processId,'','','')
} else {
//回填
this.xml = this.xml.replace(/CDATA/g,"").replace(/\<\!\[\[/g,'').replace(/\]\]\>/g,"")
}
this.modeler.importXML(this.xml).then((res) => {
this.modeler.get('canvas').zoom('fit-viewport', 'auto')
this.awaitModeler = this.modeler
})
},
}
}
custom-properties-panel部分js代码示例:
export default {
data(){
return {
currentElement:""//当前被选中的图形对象(shape)
}
},
props:["modeler","queryData"],
watch:{
modeler(val){
this.init();
}
},
methods:{
init(){
this.eventBus = this.modeler.get("eventBus")
this.modeling = this.modeler.get("modeling")
this.moddle = this.modeler.get("moddle")
this.bpmnFactory = this.modeler.get("bpmnFactory")
this.elementRegistry = this.modeler.get("elementRegistry")
//选中节点事件
this.modeler.on('selection.changed', e => {
const tempElement =e && e.newSelection && e.newSelection[0]
if(tempElement && tempElement.type !="bpmn:Process"){
this.currentElement = tempElement
...
.......
...............
}
})
}
}
}
这里有一点要注意,就是modeler要取importXML()方法渲染完之后的值(awaitModeler),否则会报错,或者在importXML()之后再执行一次init(),因为importXML()之前和之后的modeler发生了变化;但是复杂对象无法实时watch,开启deep:true
太耗性能,干脆最后才取值;
引导:
关于bpmnjs+vue的更多篇章,小编已经全部整理在这里:
bpmnjs+vue中文文档API常见方法使用总结