vue轮播组件实现$children和$parent 附带好用的gif录制(2)

2、既然我们主组件拿到了子组件了,那么就可以直接操作子组件进行操作,其实核心原理在于主组件之间操作子组件。(我看了elementUI源码的走马灯部分,写的比我复杂。)

3、定时器部分

//开始计时器 startTimer() { //预先执行一次,保证不会出现第一次运行延迟双倍实际 this.play(); // 拦截处理 if (this.interval <= 0 || !this.autoplay || this.timer) return; this.timer = setInterval(() => { this.play(); }, this.interval); },

这块其实没啥,除了预先的拦截剩下的就是启动定时器,然后运行动画播放函数

4、核心播放函数部分

//播放实际运行函数 play() { let len = this.items.length - 1; let now = this.active > len ? 0 : this.active; let old = this.active - 1 < 0 ? 0 : this.active - 1; //console.log("当前", now, "老的", old); //关闭老元素 this.items[old].show = false; this.items[old].itemStyle = { transition: "all 1.5s ease", transform: `translateX(${this.axisx}px)` }; //显示新元素 this.items[now].show = true; this.items[now].itemStyle = { transition: "all 1.5s ease", transform: "translateX(0)", animation: "mymove 1.5s 2" }; //记录数据 this.active = now + 1; }

这个其实很简单,每次运行的时候处理一下数据,拿到当前要运行的子元素id和老的元素,当前的展示,老的移动回去。最后记录一下新的id

这里有一个坑点:就是animation部分,记得运行2次,不然只是一次会导致下面的元素看不到抖动效果。原因是在移动的时候就抖动完毕了。

5、主组件css部分

.dht-swiper-side { position: absolute; z-index: 2000; right: 0; display: flex; flex-flow: row; width: 100%; }

三、组件文档

dht-swiper-side   侧边轮播组件   interval   Number   5000   时间间隔,默认5秒转换一次   必须给该组件指定宽度,否则无法正常显示。   内部子元素展示做最侧位置主要由该组件的宽度定义  
autoplay   Boolean   TRUE   是否自动播放,咱不支持false  
zIndex   Number   2000   组件层级  
axisx   Number   1000   隐藏的子元素位置,px单位,默认1000。当内部元素宽度过大时可以调节该参数  
dht-swiper-side-item   dht-swiper-side             dht-swiper-side的子组件,用于存放内容  

四、个人组件效果展示

<dht-swiper-side> <dht-swiper-side-item> <div>我是组件1</div> </dht-swiper-side-item> <dht-swiper-side-item> <div>我是组件2</div> </dht-swiper-side-item> <dht-swiper-side-item> <div>我是组件3</div> </dht-swiper-side-item> <dht-swiper-side-item> <div>我是组件4</div> </dht-swiper-side-item> </dht-swiper-side> .main { width: 500px; .item { width: 100px; height: 100px; background: #009966; border: #409eff 1px solid; text-align: center; line-height: 100px; } }

主组件全部代码

<template> <div @mouseenter.stop="handleMouseEnter" @mouseleave.stop="handleMouseLeave" :style="{ zIndex: zIndex }" > <slot></slot> </div> </template> <script> export default { name: "dhtSwiperSide", props: { // 时间间隔 interval: { type: Number, default: 8000 }, //是否自动播放 autoplay: { type: Boolean, default: true }, zIndex: { type: Number, default: 2000 }, // x轴变化 axisx: { type: Number, default: 1000 } }, watch: { autoplay(val) { val ? this.startTimer() : this.stopTimer(); } }, data() { return { // 计时器 timer: "", //子元素 items: [], // 当前显示的元素 active: 0 }; }, beforeCreate() {}, created() { this.$nextTick(() => { this.updateItems(); this.startTimer(); this.$children[0].show = true; }); }, beforeMount() {}, mounted() {}, destroyed() { clearInterval(this.timer); }, methods: { handleMouseEnter() { this.stopTimer(); }, handleMouseLeave() { this.startTimer(); }, //开始计时器 startTimer() { //预先执行一次,保证不会出现第一次运行延迟双倍实际 this.play(); // 拦截处理 if (this.interval <= 0 || !this.autoplay || this.timer) return; this.timer = setInterval(() => { this.play(); }, this.interval); }, // 停止计时器 stopTimer() { clearInterval(this.timer); }, // 更新元素 updateItems() { this.items = this.$children.filter( // 更新元素需要确认为指定的子元素 child => child.$options.name === "dhtSwiperSideItem" ); }, //播放实际运行函数 play() { let len = this.items.length - 1; let now = this.active > len ? 0 : this.active; let old = this.active - 1 < 0 ? 0 : this.active - 1; //console.log("当前", now, "老的", old); //关闭老元素 this.items[old].show = false; this.items[old].itemStyle = { transition: "all 1.5s ease", transform: `translateX(${this.axisx}px)` }; //显示新元素 this.items[now].show = true; this.items[now].itemStyle = { transition: "all 1.5s ease", transform: "translateX(0)", animation: "mymove 1.5s 2" }; //记录数据 this.active = now + 1; } } }; </script> <style lang="scss"> .dht-swiper-side { position: absolute; z-index: 2000; right: 0; display: flex; flex-flow: row; width: 100%; } </style>

子组件全部代码

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/b9a4f738cf93bed0f7c76a90ed822820.html