这次项目有一个需求,就是首页会对应不同的系统,产品要给出一个可以让客户自己拖拽组件布局的方案,所以这边调研了搞了一个demo。使用vue-draggable和本地存储来做操作与保存
因为是demo,所以我用了色块来模拟组件
github仓库
在这里插入图片描述

源码
<template>
    <div>
        <!-- 使用draggable组件 -->
        <div class="itxst">
            <div class="col1">
                <draggable id='darg-top' style="display:flex" :disabled='!candrag' group="site"  animation="300" dragClass="dragClass"  ghostClass="ghostClass" chosenClass="chosenClass" @start="onStart" @end="onEnd">
                </draggable>
                <div style="display:flex">
                    <div class="mapBox" key='darg5'><dragcom5></dragcom5></div>
                    <draggable id='darg-left' :disabled='!candrag' group="site"  animation="300" dragClass="dragClass"  ghostClass="ghostClass" chosenClass="chosenClass" @start="onStart" @end="onEnd">
                    </draggable>
                </div>
            </div>
            <div class="col2">
                <div class="title">你可以把右边的元素拖到左边</div>
                <button @click='savePage'>save</button>
                <button @click='clearPage'>clear</button>
                <draggable id='darg-right' style="transform:scale(0.3);transform-origin:0 0" :disabled='!candrag' group="site"  animation="300" dragClass="dragClass"  ghostClass="ghostClass" chosenClass="chosenClass" @start="onStart" @end="onEnd">
                    <div class="item-con" style="width:300px;height:300px;background-color:red;" id="darg1" key='drag1'><dragcom1></dragcom1><div class="zoom" v-show="candrag"></div></div>
                    <div class="item-con" style="width:300px;height:300px;background-color:blue;" id="darg2" key='drag1'><dragcom2></dragcom2><div class="zoom" v-show="candrag"></div></div>
                    <div class="item-con" style="width:300px;height:300px;background-color:yellow;" id="darg3" key='drag1'><dragcom3></dragcom3><div class="zoom" v-show="candrag"></div></div>
                    <div class="item-con" style="width:900px;height:300px;background-color:pink;" id="darg4" key='drag1'><dragcom4></dragcom4><div class="zoom" v-show="candrag"></div></div>
                </draggable>
            </div>
            <div @click="clickDrag" class="click-btn">drag</div>
        </div>
    </div>
</template>
<script type="text/ecmascript-6">
import draggable from "vuedraggable"
import dragcom1 from './components/drag_com.vue'
import dragcom2 from './components/drag_com.vue'
import dragcom3 from './components/drag_com.vue'
import dragcom4 from './components/drag_com.vue'
import dragcom5 from './components/drag_com.vue'
  export default {
    components:{draggable,dragcom1,dragcom2,dragcom3,dragcom4,dragcom5},
    data () {
      return {
          candrag:false,
          drag:false,
          orignList:{top:[],left:[],right:[{id:'darg1',width:'300',height:'300'},{id:'darg2',width:'300',height:'300'},
          {id:'darg3',width:'300',height:'300'},{id:'darg4',width:'900',height:'300'}]}
      }
    },
    mounted () {
        var that = this;
        $('.item-con').find('.zoom').on('mousedown', function(e) {	
            if(!that.candrag){return}
            that.cancelBubble(e);	
            var $element = $(this).parent(); 
            $(document).on('mousemove', function(e) {
                var x = e.pageX - $element.offset().left; //pagex和offset获取的都是相对document左上角的位置
                var y = e.pageY - $element.offset().top;
                $element.css('width', x);
                $element.css('height', y);								
                return false; //防止鼠标移动时选中文字
            })

            $(document).on('mouseup', function() {
                $(this).off('mousemove');
            })
        })
        this.loadPage();
    },
    methods: {
        //保存拖拽之后的页面
        savePage(){
            let pageList = {
                'top':this.getPagelist('#darg-top'),
                'left':this.getPagelist('#darg-left'),
                'right':this.getPagelist('#darg-right'),
            }
            common_tool.saveDataToLocal('pageList',pageList)
        },
        //加载保存的页面
        loadPage(){
            let pageList = common_tool.getDataFromLocal('pageList') || this.orignList;
            if(!pageList){return}
            this.recoverPage(pageList.top,'#darg-top')
            this.recoverPage(pageList.left,'#darg-left')
            this.recoverPage(pageList.right,'#darg-right')
        },
        //布局恢复
        recoverPage(array,id){
            if(array.length > 0){
                array.forEach(function(value){
                    $('#'+value.id).css({'height':value.id,'width':value.width}).appendTo(id)
                })
            }
        },
        //页面复原
        clearPage(){
            common_tool.clearLocalData('pageList')
            this.loadPage();
        },
        getPagelist(id){
            let List = $(id).children().toArray().map(function(item){
                let domitem = {};
                domitem.id = item.id;
                domitem.width = $('#'+item.id).width();
                domitem.height = $('#'+item.id).height();
                return domitem
            })
            return List
        },
        clickDrag(){
            this.candrag = !this.candrag;
            var that = this;
            if(this.candrag){
                $('.col2').css({display:'block'});
                $('.col2').animate({width:'300px'});
            }else{
                $('.col2').animate({width:'0'},'normal','swing',()=>{
                    $('.col2').css({display:'none'});
                    that.savePage()
                })
            }
        },
        //取消冒泡函数
        cancelBubble(e){
            document.all ? (e.cancelBubble = true) : (e.stopPropagation());
        },
        onStart(){
            this.drag = true;
        },
        onEnd(){
            this.drag = false;
        }

    }
  }
</script>
<style scoped>
.itxst{
    display: flex;
    background-color: white;
    position: relative;
}
.click-btn{
    position: absolute;
    right: 0;
    top: 50%;
    margin-top: -30px;
    height: 60px;
    border: 1px solid #999999;
    writing-mode: vertical-rl;
    text-align: center;
    padding: 4px;
    cursor: pointer;
}
.col1{
    width: 100%;
    border: solid 1px #666666;
    padding: 6px;
}
.col2{
    display: none;
    width: 0px;
    padding: 6px;
}
.mapBox{
    width: 100%;
    height: 900px;
    background-color: black;
}
.item-con{
    position: relative;
}
.zoom{
    position: absolute;
    bottom: 0;
    right: 0;
    width: 5px;
    height: 5px;
    background-color: white;
    cursor: pointer;
}
</style>
Logo

前往低代码交流专区

更多推荐