transMove.vue 实现动画外衣
<template>
<div :class="['kyol-transMove',[className]]" :style="{'--transMoveDuration':duration + 's' ,height:height+'px',width:width+'px'}">
<slot name="title"/>
<!-- 迭代插槽作用域 -->
<transition-group name="moving" @after-leave="after" tag="div" v-if="dataList.length" class="content" >
<!-- 注意 循环样式写在 content-item 类上-->
<div v-for="item in dataList" :key="'move_' + random +'_'+ item['_index']" class="content-item" @mouseenter="onMouseEnter(item)" @mouseleave="onMouseLeave(item)">
<slot :row="item" :_index="item._index">
{{item._index}}
</slot>
</div>
</transition-group>
</div>
</template>
<script>
export default {
// 动画列表组件
name:'transMove',
props:{
rowKey:String,//行唯一标识符
data:{
type:Array,defaulte:()=>[]
},
//动画时长
duration:{
type:Number,default:1
},
// 动画速度 0-无穷
speed:{
type:Number,default:1500
},
// 类定义名称
className:String,
// 自动执行动画
auto:{
type:Boolean,default:true
},
// 默认显示几行,小于或者等于当前行数 不执行动画效果
showLine:{
type:Number,default:3
},
mouseEnter:Function,
mouseLeave:Function,
height:Number,
width:Number,
test:Boolean,// 测试
},
data(){
return {
testList:[{a:1,b:'bbb111',c:3},{a:222,b:'bbbb2',c:3},{a:3333,b:'bbbb33',c:3},{a:44444,b:'bbbb33',c:3}],
dataList:[],// 列表数据
random:Math.random().toFixed(4)*10000
}
},
watch:{
'data':{
handler(cval){
const isArray_object = Array.isArray(cval) && cval.length && !Array.isArray(cval)[0] && typeof(cval[0]) === 'object'
if(!isArray_object) return
this.dataList = cval.map((item,i) => ({...item,_index:item.rowKey || i}))
if(this.dataList.length && !this.run.id && this.auto) setTimeout(_ => this.run(),2000)
},
immediate:true
}
},
methods:{
run(){
const run = _ =>{
if(this.dataList.length <= this.size) return this.stop()
this.run.row = this.dataList.shift()
}
this.run.id = setInterval(run,this.speed)
},
stop(){
if(this.run.id) {
clearInterval(this.run.id)
this.run.id = null
}
this.$emit('stop')
},
after(){
this.dataList.push(this.run.row)
this.$emit('after-leave')
},
onMouseEnter(item){
this.mouseEnter ? this.mouseEnter(item) : this.stop()
},
onMouseLeave(){
this.mouseLeave ? this.onMouseLeave(item) : this.auto? this.run() : ''
}
},
beforeRouteLeave (to, from, next) {
// ...
this.stop()
}
}
</script>
<style lang="scss" scoped>
.kyol-transMove{
$speed:var(--transMoveDuration);
position: relative;
overflow: hidden;
/*动画*/
.content{
position: relative;
}
.moving-leave-to{
opacity:0;
transform: translateY(-50%);
}
.moving-enter-to{
opacity: 0;
}
.moving-leave-active,.moving-enter-active{
transition:all $speed ease;
position: absolute;
left: 0;
right: 0;
}
.moving-enter-active{
opacity: 0;
}
.moving-leave{
opacity: 1;
}
.moving-move{
transition:all $speed ease;
}
}
</style>