08335 / hivui-platform-template
hivui平台项目模板
Newer
Older
hivui-platform-template / project / hivuiMain / views / design / index.vue
<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>