<template> <Dialog ref="cmp-dd" :title="dialogTitle" :width="650" :height="465"> <div class="pl-design-row pl-row transfer-tip"> <div class="pl-design-col pl-col-11"> <div class="pl-field"> <div class="pl-field-lb">{{$lang("setHeight")||"设置高度"}}</div> <div class="pl-field-val"> <input class="pl-field-text" type="text" v-model="panelHeight" onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')" /> </div> </div> </div> <div class="pl-design-col pl-col-2"></div> <div class="pl-design-col pl-col-11"> <i class="move iconfont icon-moveSort2"></i>{{$lang("dragOrderFlag")||"拖动排序标识"}} <!-- <i class="del iconfont icon-close"></i>删除标识 --> </div> </div> <div class="pl-design-row pl-row transfer-box"> <div class="pl-design-col pl-col-11"> <v-jstree ref="cmp-tree" :data="columns" show-checkbox multiple allow-batch collapse text-field-name="name" @item-click="itemClick"></v-jstree> </div> <!-- <div class="pl-design-col pl-col-11"> <div class="transfer-item" v-for="(item,index) in columns" @click="item.checked=!item.checked"> <i class="iconfont" :class="item.checked?'icon-checkbox':'icon-checkbox-empty'"></i> <span>{{item.title}}</span> </div> </div> --> <div class="pl-design-col pl-col-2"> <div><i class="iconfont icon-arrow-right-circle" @click="handleMoveRight"></i></div> <div><i class="iconfont icon-arrow-left-circle" @click="handleMoveLeft"></i></div> <div><i class="iconfont icon-arrow-rightMore-circle" @click="handleMoveAllRight"></i></div> <div><i class="iconfont icon-arrow-leftMore-circle" @click="handleMoveAllLeft"></i></div> </div> <div class="pl-design-col pl-col-11" ref="dom-selected"> <div class="transfer-item" v-for="(item,index) in selectList" :resId="item.resId"> <i class="move iconfont icon-moveSort2"></i> <i class="iconfont" :class="item.selected?'icon-checkbox':'icon-checkbox-empty'" @click="item.selected=!item.selected" ></i> <span @click="item.selected=!item.selected">{{item.name}}</span> <!-- <i class="del iconfont icon-close"></i> --> </div> </div> </div> <template slot="footer"> <button class="pl-btn pl-btn-round" @click="handleCancel">{{$lang("cancel")||"取消"}}</button> <button v-if="!isEdit" class="pl-btn pl-btn-round pl-btn-primary" @click="handleOk">{{$lang("ok")||"确定"}}</button> <button v-if="isEdit" class="pl-btn pl-btn-round pl-btn-primary" @click="handleEdit">{{$lang("ok")||"确定"}}</button> </template> </Dialog> </template> <script> import findIndex from 'lodash/findIndex'; import cloneDeep from 'lodash/cloneDeep'; import VJstree from 'vue-jstree' import Dialog from "@main/components/dialog"; import Sortable from 'sortablejs'; import {strFormat} from '@main/utils/index'; export default { props:['portalPanel'], components:{ Dialog,VJstree }, data(){ return { columns:[], defHeight:300, panelHeight:300,//面板高度 selectList:[],//存放选中的栏目列表 Sortable:null,//拖拽对象 /** * 提取字段 */ fields:['resId','resKey','resUrl','parentId','type','isShow','name','selected'] } }, computed:{ // columns(){ // let data = cloneDeep(this.$store.getters.portalColumns); // return data; // }, isEdit(){ return !!this.portalPanel; }, dialogTitle(){ let title=''; if(this.portalPanel){ let paths = this.portalPanel.paths; title = strFormat(this.$lang("editSerialRowLayout"),paths[0]+1,paths[1]+1,paths[2]+1); }else{ title = this.$lang("addColunms")||"添加门户栏目" } debugger return title; } }, mounted(){ let me=this; me.Sortable&&me.Sortable.destroy(); me.$nextTick(r=>{ me.Sortable = new Sortable(me.$refs['dom-selected'], { group: "transfer-item", handle: '.move', // handle's class animation: 150, onEnd(evt){ // let itemEl = evt.item, // list = [...me.selectList]; // list[evt.oldIndex] = list.splice(evt.newIndex, 1, list[evt.oldIndex])[0]; // me.$set(me,'selectList',list); // console.log(me.selectList); } }) }); if(me.$store.getters.portalColumns.length==0){ me.$store.dispatch('portal/loadColumns').then((res)=>{ me.columns = cloneDeep(me.$store.getters.portalColumns); }); }else{ me.columns = cloneDeep(me.$store.getters.portalColumns); } }, beforeDestroy(){ this.Sortable&&this.Sortable.destroy(); }, methods:{ resetForm(){ let me=this; me.panelHeight = me.defHeight; me.Sortable=null; me.$set(me,'selectList',[]); }, setForm(data){ console.log("portal->columnsSelect.vue :" ,data); let me=this,columns = []; data.columns.map(item=>{ let tplObj={}; me.fields.map(key=>{ tplObj[key] = item[key]; }); tplObj.selected=false; columns.push(tplObj); }); me.panelHeight = data.height||me.defHeight; me.$set(me,'selectList',columns); }, show(){ this.$refs['cmp-dd'].show(); this.$nextTick(()=>{ this.resetTreeSeleted(); }) }, hide(){ this.$refs['cmp-dd'].hide(); }, /** * 因为拖动后排序,所以要重新获取 */ getSelectList(){ let me=this,arr=[]; let els = me.$refs['dom-selected'].children; for(let i=0,l=els.length;i<l;i++){ let resId = els[i].getAttribute('resId'); for(let n=0,k=me.selectList.length;n<k;n++){ if(me.selectList[n].resId==resId){ arr[i] = me.selectList.splice(n,1)[0]; break; } } } return arr; }, handleCancel(){ let me=this; me.$set(me,'selectList',[]); me.hide() }, handleOk(){ let me=this,data=[]; let list = me.getSelectList(); list.map(item=>{ let tplObj={}; me.fields.map(key=>{ tplObj[key] = item[key]; }); data.push(tplObj); }); let h = parseFloat(me.panelHeight); h = isNaN(h)?me.defHeight:h; me.$emit('onOk',data,h); me.resetForm(); me.hide(); }, handleEdit(){ let me=this,columns=[],newData={...this.portalPanel}; let list = me.getSelectList(); list.map(item=>{ let tplObj={}; me.fields.map(key=>{ tplObj[key] = item[key]; }); columns.push(tplObj); }); let h = parseFloat(me.panelHeight); h = isNaN(h)?me.defHeight:h; Object.assign(newData,{columns,height:h}); console.log("portal->columnsSelect.vue -> onUpdate:" ,newData); me.$emit('onUpdate',newData); me.resetForm(); me.hide(); }, resetTreeSeleted(){ let me=this,$tree = me.$refs['cmp-tree'],data=$tree.data; me.setNodesChecks(data,false); }, setNodesChecks(nodes,checked){ let dd = (nodes)=>{ nodes.map(item=>{ item.selected=checked; item.children&&dd(item.children); }); } dd(nodes); }, getTreeLeafs(){ let data=[]; let $tree = this.$refs['cmp-tree'],nodes=$tree.data; let dd = (nodes)=>{ nodes.map(item=>{ if(item.children.length==0){ item.selectList=false; data.push(item); } item.children&&dd(item.children); }); } dd(nodes); return data; }, getTreeChecked(){ let data=[]; let $tree = this.$refs['cmp-tree'],nodes=$tree.data; let dd = (nodes)=>{ nodes.map(item=>{ if(item.selected&&(!item.children||item.children.length==0)){ data.push(item); } item.children&&dd(item.children); }); } dd(nodes); return data; }, handleMoveLeft(){ let me = this,chks=[],unChks = []; me.selectList.map((item,index)=>{ if(item.selected){ chks.push(item); }else{ unChks.push(item) } }); me.$set(me,'selectList',unChks); me.resetTreeSeleted(); }, handleMoveAllLeft(){ let me=this; me.$set(me,'selectList',[]); me.resetTreeSeleted(); }, handleMoveRight(){ let me=this, chks = me.getTreeChecked(), oldSelds = me.selectList, newSelds = []; chks.map(item=>{ let tplObj = {},hasItem = findIndex(oldSelds,o=>{ return o.resId == item.resId; }); if(hasItem==-1){ me.fields.map(key=>{ tplObj[key] = item[key]; }); tplObj.selected = false; newSelds.push(tplObj); } }); chks.length&&me.$set(me,'selectList',[...newSelds,...oldSelds]); me.resetTreeSeleted(); }, handleMoveAllRight(){ let me = this; me.$set(me,'selectList',me.getTreeLeafs()); me.resetTreeSeleted(); }, itemClick (node, item, e) { return; let index = findIndex(this.selectList,o =>o.id == node.id); if(index==-1){ if(node.model.selected){ this.selectList.push({ id:node.model.id, pid:node.model.pid, title:node.model.title, href:node.model.resUrl, loadType:node.model.loadType||'iframe' }); }else{ this.selectList.splice(index,1); } }else{ this.selectList.splice(index,node.model.selected?0:1); } } } } </script> <style lang="less" scoped> .transfer-tip{ padding-bottom:5px; color:#999; } .transfer-box { >.pl-col-11{ border: 1px #ddd solid; height: 300px; padding:5px; overflow: auto; box-shadow: inset 0px 0px 20px 1px rgba(0,0,0,0.05); } >.pl-col-2{ text-align: center; padding-top: 70px; .iconfont{ display: block; font-size:24px; color:#999; cursor: pointer; margin-bottom: 15px; &:hover{ color:#0066cc; } } } .transfer-item{ padding:5px; &:hover{ color:#0066cc; background: #efefef; } >.iconfont{ margin-right:5px; } >.move{ cursor: move; } >.del{ float:right; cursor: pointer; } } } </style>