vue做一个自定义拖拽配置的页面
这次项目有一个需求,就是首页会对应不同的系统,产品要给出一个可以让客户自己拖拽组件布局的方案,所以这边调研了搞了一个demo。使用vue-draggable和本地存储来做操作与保存因为是demo,所以我用了色块来模拟组件github仓库源码<template><div><!-- 使用draggable组件 --><div class="itxst">
·
这次项目有一个需求,就是首页会对应不同的系统,产品要给出一个可以让客户自己拖拽组件布局的方案,所以这边调研了搞了一个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>
更多推荐
已为社区贡献2条内容
所有评论(0)