摘要:预览地址图片的轮播假设需要轮播三张图片,以前的思路就如图所示,添加两个节点。通过索引的切换实现组件的无缝轮播。这样子父组件就可以通过钩子和来实时通知子组件,从而控制内容的展示。这个判断只需让子组件来做就行了。
预览地址
图片的轮播假设需要轮播三张图片(1,2,3),以前的思路就如图所示,添加两个节点。通过索引(index)的切换实现组件的无缝轮播。
这种想法的确可行,而且实现出来效果还不错。
缺点在于
大量的dom操作。
代码逻辑相对挺复杂,量也更多。
重构或添加新功能会更麻烦
现在的思路创建两个组件分别为 carousel和 carousel-item
结构如下
1 2 3
selected即为显示的内容的name,用sync做一个"双向绑定"。这样子父组件就可以通过 updated钩子和$children来实时通知子组件,从而控制内容的展示。
updated(){ this.updateChildrens(this.selected) } methods:{ updateChildrens(){ //被选中的那个可以显示了,其他的关闭 } }
也就是说 carousel负责数据通信,而carousel-item只需完成动画过渡效果就行了,这样逻辑就非常清晰了。
这里当然就存在动画正向与反向的问题,需要两种方向不同的切入切出的动画。
carousel需要做一次判断然后在updateChildrens的时候就告诉子组件方向。
需要一个变量记录上一次的selected数值,假设就为 oldSelected 和newSelected
自动轮播是默认正向的(往后播放),到最后一个的时候回到第一个应该也是正向的
圆点(图片索引图标)选取切换,只需判断两次变量的大小就行
方向键切换(箭头图标),和自动轮播同理,方向应时刻和箭头方向一致
解决跳过中间图片的问题不管轮播图数量多少,这里始终只在两张图里面切换。这样就涉及到一个问题就是会
跳过中间的图片
首先carousel-item有一个默认的图片过渡时间,这里可以通过计算oldSelected 和newSelected之间的差值来确定跳过图片的数量。当然也有动画方向的问题。
clickSelected(newSelected){ clearInterval(this.timer2) if(oldSelected===newSelected)return lastSelected = oldSelected // ............. this.‘控制时长的函数’(lastSelected,newSelected) }, "控制时长的函数"(lastSelected,newSelected){ //........ let newIndex = newSelected let animationDuration = "计时器的间隔时长" theIndex = ‘下一个展示的图片索引’ //....... this.duration = duration this."carousel组件".forEach(vm=>vm.duration=duration) this.$emit("update:selected",names[theIndex])//通知一下父组件将要展示的下一个图片的索引 if(theIndex===newIndex)return this.timer2 = setInterval(()=>{ if(theIndex===newIndex){ this.clearAndSet() } this.$emit("update:selected",names[theIndex]) oldIndex>newIndex?theIndex--:theIndex++ },duration*animationDuration) }
基本就能完成跳过中间图片的这样子的问题了,后面的click改为 hover触发功能就很简单了。
## Card卡片化
需要默认三个同时出现的图片,这意味着需要一个数组。
但是依然不需要改变selected的数据类型(还是字符串)。这种情况用传递数组只会添加许多不必要的麻烦和降低性能,像是需要做深拷贝,遍历判断这类的。
因为这个应该出现的图片的数组里面的index都是连号的。这个判断只需让子组件来做就行了。
现在在carousel-item通过计算得到一个数组
this.cardSelected = [selected-1,selected,selected+1] if(`最后一张图`){ //..... }else if(`第一张图`){ }
现在实时显示的三张图片的数组已经有了,我只需要分配好他们的位置(左边,中间,右边
"我是决定位置的函数"(){ let [index,position] = [this.cardSelected.indexOf(Number(this.name)),["left","main","right"]] return `position-${position[index]}` }
简单的两行就搞定了。
然后绑定一下
:class="{......,[我是决定位置的函数]:card}">
剩下的定位还是动画什么的,都可以交给css去完成了。
&.position-left{ width: 50%; position: absolute; top: 0; left: -10px; transform:scale(0.82); } &.position-main{ width: 50%; transform: translateX(50%); position: relative; z-index: 3; } &.position-right{ transform: translateX(100%) scale(0.82); width: 50%; position: absolute; top: 0; left: 10px; }
最后就是点击两侧图片会切换
调用父组件的方法就ok了
"调用父组件的方法"(){ let [direction,index] = [this."我是决定位置的函数".slice(9,16),this.$parent.selectedIndex] if(direction==="main")return let move = {left:"back", right:"go"} this.$parent."我是父组件的方法"(index,move[direction]) }
## 尚未完善的细节
其实我认为动画还是有一点点瑕疵的,后面会在css上修改一下,顺便简单调整样式和更换动态svg。最后,有待加强的地方希望大佬们指出来交流,要是觉得还行的话,给我的项目点个star就是最好的了。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/102800.html
摘要:图片描述移动端的轮播图可以有很多方式实现,最常见的可以使用定位手指事件。四手指移入移出开关定时器 图片描述 移动端的轮播图可以有很多方式实现,最常见的可以使用定位 + 手指事件。但是我这里介绍的是 CSS3 中的 2d 变换和手指事件,因为变换属性的代码更加简洁优雅 一. 移动端的准备工作 * { padding: 0; margin: 0; } img { d...
摘要:过渡实现轮播图过渡的过渡系统是内置的,在元素从中插入或移除时自动应用过渡效果。 Vue 过渡实现轮播图 Vue 过渡 Vue 的过渡系统是内置的,在元素从 DOM 中插入或移除时自动应用过渡效果。 过渡的实现要在目标元素上使用 transition 属性,具体实现参考Vue2 过渡 下面例子中我们用到列表过渡,可以先学习一下官方的例子 要同时渲染整个列表,比如使用 v-for,我们需要...
摘要:实现原理无缝滚动预处理为了无缝滚动,在传进来的数组首部增加末尾元素,在尾部追加首元素看图数据绑定视图为当前显示的轮播图索引,然后只需要对进行操作,监听的变化,一旦到达了边界就重置,显示出对应的图片。 该文章请对应源码阅读,github源码地址,DEMO使用地址,线上DEOM展示。 做一个vue基础组件系列,使用vue以最简洁的方式实现常用组件,可用于快速二次定制化开发。 (๑•̀ㅂ•́...
摘要:实现原理无缝滚动预处理为了无缝滚动,在传进来的数组首部增加末尾元素,在尾部追加首元素看图数据绑定视图为当前显示的轮播图索引,然后只需要对进行操作,监听的变化,一旦到达了边界就重置,显示出对应的图片。 该文章请对应源码阅读,github源码地址,DEMO使用地址,线上DEOM展示。 做一个vue基础组件系列,使用vue以最简洁的方式实现常用组件,可用于快速二次定制化开发。 (๑•̀ㅂ•́...
阅读 795·2019-08-30 15:54
阅读 438·2019-08-30 12:51
阅读 2021·2019-08-29 16:28
阅读 2841·2019-08-29 16:10
阅读 2330·2019-08-29 14:21
阅读 408·2019-08-29 14:09
阅读 2126·2019-08-23 16:13
阅读 1234·2019-08-23 13:59