vue实现同事拿到了一份设计稿,是carousel的轮播效果,于是上网搜索了一下,找到了jquery实现的效果。有空就会看源码,研究一下它的实现原理。想用Vue的数据驱动的方式实现一个,但是这个效果和我以前做的demo效果不一样,每次想想都卡壳了。拖了好几天,转念一想,想出了一个方案,于是实现了。轮播效果实例:优酷频道页面的实际应用。首先分析一下jquery的实现效果。其实就是把轮播item的dom进行左右分组,设置好每个dom的宽高,级联参数,透明度和位置偏移,然后通过jqueryanimationapi,对dom组进行一次数据切换(复制下一个dom的数据)。比如ABC有3个,B在中间。当从右向左切换时,B获取C的数据,C获取A的数据,A替换B的数据成为BCA。计算插件接受指定数量的数据:整体宽高、主项的宽高(中间最大的)、其他项依次缩小的比例。关于位置,如图:主项要居中,所以它相对于父元素向左的位置偏移量(绝对定位)应该是整体宽度和自身宽度之差的一半。对于两侧的其他物品,如果直接隔开,剩余空间将按数量平分。比如父元素的宽度是800px,主item的宽度是400px,那么左边的剩余空间应该是(800-400)/2=200px,假设左边有两个item,两者会直接将自己的部分显示为200/2=100px;这个值就是我们需要考虑的绝对定位左值。同样,我们可以得到右边部分的左边值。至于项目的居中绝对定位,类似,更简单。其次,考虑到中间的物品为主,两边的物品要叠放。参数(z-index)越靠近中间,数值越大,越往两边透明度越小。具体的代码逻辑可以在这里找到。vue的概念实现vue是数据驱动的,所以需要转换jquery插件的实现。同样,它也接受几个静态数据:整体的宽高,中间项的宽高,缩小比例。<级联循环:list="list":cur-width="400":all-width="800":all-height="300":cur-height="280":scale="0.8">将jquery对dom的数据操作转换为数组存储,数组元素存储每个dom的数据(宽高、绝对定位偏移值、透明度和级联参数),遍历模板处的实际项数组,它的style通过索引获取store数组的元素数据。切换数据,通过对store的出队、入队或者反向出队入队操作实现切换逻辑;然后通过在style中设置transition来设置动画效果。.item{transition:all.8sease;}进行数据初始化,代码如下://storearrayvaritems=[];//复制物理数据varrlist=copyArr(this.list);//获取中间数组元素索引varlevel=Math.floor(this.list.length/2);//如果数据是偶数,则再复制一份数据。if(this.list.length%2==0){varcenter=this.list[0];rlist.push(Object.assign({},center));}//左边部分varlefts=rlist.slice(0,level);//右边部分varrights=rlist.slice(level);那个=这个;//两侧(一侧)剩余空间varleftGap=(this.allWidth-this.curWidth)/2;//平分剩余空间,即间隙vargap=leftGap/level;lefts.forEach(function(e,i){//遍历左边部分varobj={};//从左到右,左边的值为gapmultiplegrowthobj.left=i*gap;//级联参数逐级增加1obj.zIndex=i+1;//透明度只是逐级增加obj.opacity=1/(level+1-i);//宽高根据数量选择距离中间的项目obj.width=that.curWidth*Math.pow(that.scale,level-i);obj.height=that.curHeight*Math.pow(that.scale,level-i);//底部距离为最大高度与当前item高度差的一半obj.bottom=(that.allHeight-obj.height)/2;items.push(obj);});//遍历右边部分,包括中间项rights.forEach(function(e,i){varobj={};obj.width=that.curWidth*Math.pow(that.scale,i);obj.height=that.curHeight*Math.pow(that.scale,i);//偏移值可以反过来想,就是全宽减去右边的偏移量和自己的宽度obj.left=that.allWidth-(level-i)*gap-obj.width;obj.zIndex=level-i+1;obj.opacity=1/(i+1);obj.bottom=(that.allHeight-obj.height)/2;items.push(obj);});return{items:items,rlist:rlist,timer:null,dir:'right'}添加定时器和方向选择,效果就出来了,如下:https://jsfiddle.net/dont27/L...如果访问不了,可以看看runjs。一开始我一直想着绕不过去,一直无从下手。但是,当我抓到突破点的时候,我真的写出来了,发现还是挺简单的!但是在处理偶数项上,我只是简单的复制一份再复制一份,比较粗糙!PS:如果大家有兴趣有想法,欢迎留言,也欢迎指教~原文在我的博客:http://shellphon.wang/gibl...
