vue实现easyui-layout的伸缩拖拽功能
最近在做一个vue项目,需要一个类似于easyui-layout的伸缩功能,要求可伸缩并且可拖拽,由于vue也提供了过度和动画的特性,决定利用vue提供的过渡特性自己动手写一个实现。Vue官网对于transition组件的解释:Vue 提供了 transition 的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡条件渲染 (使用 v-if)条件展...
·
最近在做一个vue项目,需要一个类似于easyui-layout的伸缩功能,要求可伸缩并且可拖拽,由于vue也提供了过度和动画的特性,决定利用vue提供的过渡特性自己动手写一个实现。
Vue官网对于transition组件的解释:Vue 提供了 transition
的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡
-
条件渲染 (使用
v-if
) -
条件展示 (使用
v-show
) -
动态组件
-
组件根节点
利用transition组件实现左侧div的伸缩隐藏,组织以下代码:
<template>
<div id="app">
<!-- 左侧伸缩部分 -->
<transition name='left'>
<div v-if='leftshow' id='leftDiv' class='layout-left'>
this is in leftDiv
</div>
</transition>
<!-- 伸缩按钮部分 -->
<div class='layout-area'>
<div @click='slide'>
<span v-if='leftshow'><</span>
<span v-if='!leftshow'>></span>
</div>
</div>
<!-- 中间内容部分 -->
<div id='centerDiv' class='layout-center'>
this is in centerDiv
</div>
</div>
</template>
定义左侧伸缩部分的过渡css,过渡时间为1.5s,为了同步中间部分宽度设置中间div过渡为1.5s:
/* 过渡类 */
.left-enter,.left-leave-to{
margin-left:-200px;
}
.left-enter-active,.left-leave-active{
transition:1.5s;
}
...
/* 中间部分样式 */
.layout-center{
float:right;
background-color:gray;
width:calc(100% - 230px);
height:100%;
transition:1.5s;
border:1px solid gray;
}
通过leftshow控制左侧的显示和隐藏,左侧部分隐藏之后调整中间部分的width,:
export default {
name: 'App',
data:() => {
return{
leftshow:true,
}
},
methods:{
/*左侧伸缩隐藏*/
slide(){
this.leftshow = !this.leftshow;
let leftDom = document.querySelector('#leftDiv');
let centerDom = document.querySelector('#centerDiv');
if(!this.leftshow){
centerDom.style.width = 'calc(100% - 20px)';
}else{
centerDom.style.width = 'calc(100% - 220px)';
}
},
},
}
至此,点击按钮实现伸缩功能完成:
下一步实现可拖拽:
更改template结构,添加一个可拖拽的代理div:
<template>
<div id="app">
<!-- 左侧伸缩部分 -->
<transition name='left'>
<div v-show='leftshow' id='leftDiv' class='layout-left'>
this is in leftDiv
</div>
</transition>
<!-- 伸缩按钮部分 -->
<div class='layout-area' >
<div @click='slide'>
<span v-if='leftshow'><</span>
<span v-if='!leftshow'>></span>
</div>
</div>
<!-- 添加拖动代理div -->
<div id='proxyDiv' class='layout-proxy' @mousedown.prevent='dragStart'>
</div>
<!-- 中间内容部分 -->
<div id='centerDiv' class='layout-center'>
this is in centerDiv
</div>
</div>
</template>
设置css:
/* 拖拽div */
.layout-proxy{
position:absolute;
cursor:w-resize;
opacity:0;
left:200px;
width:10px;
height:100%;
background-color: blue;
}
为代理div添加鼠标按下事件事件,并且更改左侧伸缩隐藏处理:
/*左侧伸缩隐藏*/
slide(){
this.leftshow = !this.leftshow;
let proxyDom = document.querySelector('#proxyDiv');
let leftDom = document.querySelector('#leftDiv');
let centerDom = document.querySelector('#centerDiv');
let that = this;
if(!this.leftshow){ //隐藏左侧div
proxyDom.style.left = -that.layoutX + 'px';
leftDom.style.marginLeft = -that.layoutX + 'px';
centerDom.style.width = 'calc(100% - 20px)';
}else{
setTimeout(function(){
proxyDom.style.left = that.layoutX + 'px';
leftDom.style.marginLeft = '0px';
centerDom.style.width = 'calc(100% - 20px - '+that.layoutX+'px)';
},30)
}
},
/*拖拽*/
dragStart(e){
let that = this;//保存this到that
let leftDom = document.querySelector('#leftDiv');
let centerDom = document.querySelector('#centerDiv');
e.target.style.opacity = .8;
/*当鼠标在拖动div按下时绑定鼠标移动事件*/
document.onmousemove = function(event){
e.target.style.left = event.clientX + 'px'; //拖动时更改代理div的位置,跟随鼠标运动
}
document.onmouseup = function(event){
that.layoutX = event.clientX; //保存鼠标抬起的位置,
e.target.style.opacity = 0; //代理div不可见
leftDom.style.width = event.clientX + 'px';
centerDom.style.width = 'calc(100% - 20px - '+event.clientX+'px)';
//还原事件
document.onmousemove = null;
document.onmouseup = null;
}
},
拖拽效果如下:
完成代码github地址:https://github.com/jianfeng418/vue-layout
更多推荐
已为社区贡献5条内容
所有评论(0)