<template> <div class="pl-design"> <div class="pl-design-head"> <div class="pl-fr tool"> <!-- <button class="pl-btn pl-btn-round pl-btn-primary" @click="handleAddColumn">添加栏目</button> --> <!-- <button class="pl-btn pl-btn-round pl-btn-primary" @click="hackResetPortal=!hackResetPortal">恢复默认</button> --> <button class="pl-btn pl-btn-round pl-btn-primary" @click="handleSave">{{$t("hivuiMain_des_save")}}</button> </div> <div class="pl-fl"></div> </div> <div class="pl-design-main"> <div class="pl-design-area" ref="dom-designArea"> <template v-if="hackResetPortal"> <Portal :ref="'cmp-desPortal'+index" :cols="item.layoutCols" :index="index" :key="index" v-for="(item,index) in layoutRows" @onDel="onDelPortal"></Portal> </template> </div> <!-- <Portal v-show="choosLayout" :cols="choosLayout" ref="dom-clonePortal"></Portal> --> </div> <div class="pl-design-aside"> <div class="pl-design-aside-head"> {{$t("hivuiMain_des_columnLayout")}} </div> <div class="pl-design-aside-body"> <div class="pl-design-aside-tabs" v-if="false"> <button class="pl-btn pl-btn-round pl-btn-primary">{{$t("hivuiMain_des_selectTemplate")}}</button> <button class="pl-btn pl-btn-round">{{$t("hivuiMain_des_addSingleLine")}}</button> </div> <div class="pl-design-aside-msg"> *{{$t("hivuiMain_des_demoLayoutTip")}} </div> <div> <div class="pl-design-layoutDemo" ref="dom-layoutDome"> <div class="preview"> <input type="hidden" value="24"/> <div class="name"> {{$t("hivuiMain_des_row24")}} </div> <div class="view"> <div class="pl-design-row pl-row"> <div class="pl-design-col pl-col-24">24</div> </div> </div> </div> <div class="preview"> <input type="hidden" value="12 12"/> <div class="name"> {{$t("hivuiMain_des_rowAvg2")}} </div> <div class="view"> <div class="pl-design-row pl-row"> <div class="pl-design-col pl-col-12">12</div> <div class="pl-design-col pl-col-12">12</div> </div> </div> </div> <div class="preview"> <input type="hidden" value="8 16"/> <div class="name"> {{$t("hivuiMain_des_row8_16")}} </div> <div class="view"> <div class="pl-design-row pl-row"> <div class="pl-design-col pl-col-8">8</div> <div class="pl-design-col pl-col-16">16</div> </div> </div> </div> <div class="preview"> <input type="hidden" value="16 8"/> <div class="name"> {{$t("hivuiMain_des_row8_16")}} </div> <div class="view"> <div class="pl-design-row pl-row"> <div class="pl-design-col pl-col-16">16</div> <div class="pl-design-col pl-col-8">8</div> </div> </div> </div> <div class="preview"> <input type="hidden" value="8 8 8"/> <div class="name"> {{$t("hivuiMain_des_rowAvg3")}} </div> <div class="view"> <div class="pl-design-row pl-row"> <div class="pl-design-col pl-col-8">8</div> <div class="pl-design-col pl-col-8">8</div> <div class="pl-design-col pl-col-8">8</div> </div> </div> </div> <div class="preview"> <input type="hidden" value="6 6 6 6"/> <div class="name"> {{$t("hivuiMain_des_rowAvg4")}} </div> <div class="view"> <div class="pl-design-row pl-row"> <div class="pl-design-col pl-col-6">6</div> <div class="pl-design-col pl-col-6">6</div> <div class="pl-design-col pl-col-6">6</div> <div class="pl-design-col pl-col-6">6</div> </div> </div> </div> <div class="pl-design-aside-msg"> *{{$t("hivuiMain_des_customLayoutTip")}} </div> <div class="preview"> <div class="name"> {{$t("hivuiMain_des_custom")}} </div> <div class="view"> <input type="text" value="" :placeholder="$t('hivuiMain_des_spaceSeparate')"/> </div> </div> </div> </div> </div> </div> <Dialog ref="cmp-dd" :width="600"></Dialog> </div> </template> <script> import Dialog from "@main/components/dialog"; import Portal from "./portal"; import Sortable from 'sortablejs'; export default { components: { Dialog,Portal }, provide(){ let me=this; return { addPanel(position,data){ me.addPanel(position,data) }, editPanel(data){ me.editPanel(data) }, delPanel(data){ me.delPanel(data) }, getPanels(index){ return me.getRowPanels(index); }, updatePanelPosition(ops){ me.updatePanelPosition(ops) } } }, data(){ return { hackResetPortal:true,//ui补丁,用于拖拽强制重新渲染 layoutRows:this.$store.getters.portalList, choosLayout:null, SortableList:[] } }, watch:{ layoutRows(newVal,oldVal){ //强制刷新子组件portal this.resetPortal(); } }, mounted() { let me =this; me.$store.dispatch('portal/loadList').then(data=>{ me.layoutRows = data; });//工作台门户列表 new Sortable(this.$refs["dom-designArea"], { group: "portal-layout", handle: '.pl-design-portal-head', // handle's class animation: 150, onMove(evt, originalEvent) { return evt.to==evt.from; }, onEnd(evt){ let rows=[...me.layoutRows]; console.log('dom-designArea : ',me.layoutRows); rows[evt.oldIndex] = rows.splice(evt.newIndex, 1, rows[evt.oldIndex])[0]; me.$set(me,'layoutRows',rows); me.resetPortal(); me.$store.dispatch('portal/setList',rows); } }); new Sortable(this.$refs["dom-layoutDome"], { sort:false, chosenClass:"ghostClass", filter: ".pl-design-aside-msg", group: { name: 'portal-layout', pull: 'clone' // To clone: set pull to 'clone' }, animation: 150, // Element dragging ended onEnd: function (evt) { var itemEl = evt.item; // dragged HTMLElement if(evt.to!=evt.from) { let cols = itemEl.querySelector('input').value.split(' '); if(cols.length&&cols[0]!=""){ let hasInt = true,tmpArr = [...me.layoutRows]; console.log('dom-layoutDome : ',me.layoutRows); cols = cols.map((item,i)=>{ if(isNaN(parseInt(item))){ hasInt = false; } return item*1 }); if(!hasInt) return;//如果自定义列不是整数 let portal = me.makePortalItem(cols,evt.newIndex); me.layoutRows.splice(evt.newIndex,0,portal); } itemEl.remove(); } me.choosLayout = null; }, onMove: function (evt, originalEvent) { if(evt.to==evt.from) return false; // Example: https://jsbin.com/nawahef/edit?js,output let cols = evt.dragged.querySelector('input').value.split(' '); let hasInt = true; cols = cols.map((item,i)=>{ if(isNaN(parseInt(item))){ hasInt = false; } return item*1 }); if(cols.length&&hasInt) { me.choosLayout = cols; }else{ // return false; } }, }); }, methods: { getRowPanels(index){ return this.layoutRows[index].panels; }, updatePanelPosition(ops){ let me=this; let oldPanel = me.layoutRows[ops.oldRowIndex].panels[ops.oldColIndex].splice(ops.oldPanelIndex,1); let taget = me.layoutRows[ops.newRowIndex].panels[ops.newColIndex]; oldPanel[0].paths=[ops.newRowIndex,ops.newColIndex,ops.newPanelIndex]; taget.splice(ops.newPanelIndex,0,oldPanel[0]); me.resetPortal(); this.$store.dispatch('portal/setList',me.layoutRows); }, /** * 创建一个门户版块 */ addPanel(position,data){ let rowIndex = position[0], colIndex=position[1], layoutRows = this.layoutRows, tagetPanels = layoutRows[rowIndex].panels[colIndex]; data.paths=[rowIndex,colIndex,tagetPanels.length] tagetPanels.push(data); // console.log('创建一个门户版块:',layoutRows); this.$set(this,'layoutRows',layoutRows); this.$store.dispatch('portal/setList',layoutRows); }, /** * 创建一个门户版块 */ editPanel(data){ let layoutRows = this.layoutRows; let paths = data.paths; let rowIndex=paths[0],colIndex=paths[1],index=paths[2]; layoutRows[rowIndex].panels[colIndex].splice(index,1,data); this.$set(this,'layoutRows',layoutRows); this.$store.dispatch('portal/setList',layoutRows); }, delPanel(data){ let layoutRows = this.layoutRows; let paths = data.paths; let rowIndex=paths[0],colIndex=paths[1],index=paths[2]; layoutRows[rowIndex].panels[colIndex].splice(index,1); this.$set(this,'layoutRows',layoutRows); this.$store.dispatch('portal/setList',layoutRows); }, /** * vue 是vnode 节点,性能上最大化利用节点 * 因此,当行布局增加时,插入布局的地方是原来的旧节点,影响新局结构 * 然后 布局的增加,只会在最后一个子组件进行创建,原来的是复用的 * 这样 拖拽功能就留下之前布局的痕迹在,新的布局上 */ resetPortal(){ this.hackResetPortal= false; this.$nextTick(() => { this.hackResetPortal= true; }); }, /** * 创建一个门户行 */ makePortalItem(cols,rowIndex){ let me=this; let rowPanel = { layoutCols:cols,//布局列数、所占大小 panels:[]//当前行的所有门户面板,以下标对应列中,每个面板有多个栏目 }; cols.map((col,index)=>{ /* demo : 模拟默认一个栏目 */ // rowPanel.panels[index]=[{title:`栏目组 ${rowIndex}-${index}`}];//初始化对应列中的 面板列表,面板中有多个栏目 rowPanel.panels[index]=[]; }); return rowPanel; }, handleAddColumn() { this.$refs["cmp-dd"].setContent('<h1></h1>'); this.$refs["cmp-dd"].show(); }, handleSave(){ let me =this; let portalList = me.$store.getters.portalList; let l = me.$message.loading({ message: me.$t("hivuiMain_des_saving"), position: 'center', hasMask: true }) me.$store.dispatch('portal/savePortal',portalList).then(r=>{ l.close(); me.$message.success(me.$t("hivuiMain_des_saveSuc")); }).catch(r=>{ l.close(); me.$message.error(me.$t("hivuiMain_des_saveError")); }); }, onDelPortal(index){ this.layoutRows.splice(index,1); } } }; </script>