99行代码实现vue左滑删除
2018-04-16 本文已影响54人
TOPro
文档先欠着
demo
<template lang="pug">
slide-out
左滑我就可以看见删除
template(slot="actions")
button(text="删除", @click="toast('点我删除')")
</template>
源码
<template lang="pug">
.slide-out.root( @touchstart="startHandler" ,@touchmove="moveHandler" ,@touchend="endHandler" ,@click="clickHandler" ,:class="[viewMode]" )
.so-scroller(:style="{left:offsetX}")
.so-content
slot
.so-actions(ref="actions")
slot(name="actions")
span.blank-label 没有操作
</template>
<script type="text/javascript">
const MODE_IN = "normal";
const MODE_OUT = "expanded";
const DISTANCE = 45;
const INSTANCE_POLL = new Map();
export default {
name:"SlideOut",
data(){
return {
actionsWidth:0,
viewMode:MODE_IN
}
},
computed:{
offsetX(){return (this.viewMode == MODE_IN?0:-this.actionsWidth) + "px"}
},
methods:{
freshSize(){
this.actionsWidth = this.$refs.actions.offsetWidth;
},
startHandler(){
this._startX = event.touches[0].clientX;
this._startSlide = true;
},
moveHandler(){
var m = this;
if(!m._startSlide) return;
this._currentX = event.touches[0].clientX;
this._distance = this._currentX - this._startX;
if(Math.abs(m._distance) > DISTANCE) {
m.viewMode = m._distance<0?MODE_OUT:MODE_IN;
console.log(m.viewMode,m._distance<0?MODE_OUT:MODE_IN);
this._startSlide = false;
}
},
endHandler(){
this._startSlide = false;
},
clickHandler(e){
var m = this;
return m.$emit("click",e);
}
},
mounted(){
var m = this;
m.freshSize();
m.$watch("viewMode",v=>{
if(v==MODE_OUT) INSTANCE_POLL.forEach(el=>{
if(el.$$$id!=this.$$$id) el.viewMode=MODE_IN
})
})
},
created(){
this.$$$id = INSTANCE_POLL.size;
INSTANCE_POLL.set(this.$$$id,this)
},
beforeDestroy(){
INSTANCE_POLL.delete(this.$$$id)
}
}
</script>
<style scoped type="text/css" lang="less">
.root{overflow: hidden;}
.so-content{
display: flex;
align-items: center;
}
.so-content,.so-scroller,.so-actions{
height: 100%;
}
.so-scroller{
position: relative;
transition:left 0.618s cubic-bezier(1.000, 0.000, 0.000, 1.000)
}
.so-actions{
position: absolute;
top: 0;
right: 0;
transform:translateX(100%);
display: flex;
align-items: stretch;
white-space: nowrap;
}
.blank-label{
color: #666;
display: flex;
align-items: center;
}
</style>