Vue组件实现景深卡片轮播示例

目录
  • 前言
  • 需求拆解
  • 开发思路(vue2)
  • 开发过程
  • 后记

前言

朋友的朋友做了个首页,首页用到一个卡片轮播,大概就是这个样子的:

第一版他们是开发出来了,但是各种bug,希望我帮忙改一下。

看完代码以后,发现他们整合了一个缝合怪出来,各个楼层都是从其他地方 CV 过来的,而且各个楼层引用了 n 多个js 和 css 文件,看了一下效果以后,觉得改他的东西确实比重新开发一个要麻烦的多得多,所以就重新写了一下。

在此记录一下,以便于后续复用。

需求拆解

  • 初始化渲染5个容器,用来承载图片和标题,按照景深的效果排列,越靠近自己越大。
  • 点击中间一块的左边的整体向右旋转一格,点击右边的向左旋转一格,点击中间的没有效果。
  • 中间一项显示 content 和 查看更多 按钮,其他不显示。

开发思路(vue2)

  • 景深效果可以选择使用 css3 的转换来制作,通过对每个容器进行不通比例的缩放来实现5个容器大小不一致的效果。
  • 因为使用到了css3的转换,就需要用到过渡,动画效果就使用 transition-group 来实现。
  • 至此就可以轮播就可以滚动起来了,只需要给5个容器循环赋值css样式,就可以实现缩放和位置转换,结合渐变,就成了一个循环动画效果。
  • 点击事件,一开始的思路是通过获取点击事件中的鼠标的坐标,如果在左半个屏幕就走左边的逻辑,但是页面有个最小宽度 1280,当分辨率被拖动的时候就不行了,所以pass掉了。最后选择的方案是,给容器一套下标(_id)的同时全局声明一个变量用来记录当前展示的容器的下标,每次点击都要和展示项作比较,通过比较结果来确定左右逻辑。
  • 思维发散:
    • 可以扩展为7个甚至更多容器的轮播
    • 扩展为n个容器,但是只显示5个的轮播
    • 景深效果以及动画效果改变
    • ...

开发过程

首先是html+css部分,这部分很简单,而且很普通。

  • 写 5 个div,每个都用绝对定位的方式铺满整个屏幕,每个宽度都是 20%。
  • 绑定各数据,并用 几个 状态值来控制 content 的显示隐藏,以及当前展示项。

代码如下:

<script>
// 引入图片资源
import loop1 from '@assets/images/loop1.png';
import loop2 from '@assets/images/loop2.png';
import loop3 from '@assets/images/loop3.png';
import loop4 from '@assets/images/loop4.png';
import loop5 from '@assets/images/loop5.png';
/**
 * 根据 id 获取下标
 * @params arr object[]
 * @params id number
 * @result number n>=-1
 */
const findIdxById = (arr, id) => {
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] === id) {
      return i;
    }
  }
  return -1;
};
export default {
  data() {
    return {
      // 轮播数据
      baseData: [
        {
          desc:
            '可折叠式智能移动影院Royle-X展现了惊人的高科技技术和全球首创的可折叠设计,配备了柔宇科技自助研发的首款智能移动显示操作系统,设计非常人性化。可能会可折叠计自助研发的首款智能移动显示操作系统,设计非常人性化。可能会可折自助研发的首款智能移动显示操作系统,设计非常人性化。可能会可折自助研发的首款智能移动显示操作系统,设计非常人性化。可能会可折',
          title: '这里是标题',
          cover: loop1,
        },
        {
          desc:
            '可折叠式智能移动影院Royle-X展现了惊人的高科技技术和全球首创的可折叠设计,配备了柔宇科技自助研发的首款智能移动显示操作系统,设计非常人性化。可能会可折叠计自助研发的首款智能移动显示操作系统,设计非常人性化。可能会可折自助研发的首款智能移动显示操作系统,设计非常人性化。可能会可折自助研发的首款智能移动显示操作系统,设计非常人性化。可能会可折',
          title: '这里是标题',
          cover: loop2,
        },
        {
          desc:
            '可折叠式智能移动影院Royle-X展现了惊人的高科技技术和全球首创的可折叠设计,配备了柔宇科技自助研发的首款智能移动显示操作系统,设计非常人性化。可能会可折叠计自助研发的首款智能移动显示操作系统,设计非常人性化。可能会可折自助研发的首款智能移动显示操作系统,设计非常人性化。可能会可折自助研发的首款智能移动显示操作系统,设计非常人性化。可能会可折',
          title: '这里是标题',
          cover: loop3,
        },
        {
          desc:
            '可折叠式智能移动影院Royle-X展现了惊人的高科技技术和全球首创的可折叠设计,配备了柔宇科技自助研发的首款智能移动显示操作系统,设计非常人性化。可能会可折叠计自助研发的首款智能移动显示操作系统,设计非常人性化。可能会可折自助研发的首款智能移动显示操作系统,设计非常人性化。可能会可折自助研发的首款智能移动显示操作系统,设计非常人性化。可能会可折',
          title: '这里是标题',
          cover: loop4,
        },
        {
          desc:
            '可折叠式智能移动影院Royle-X展现了惊人的高科技技术和全球首创的可折叠设计,配备了柔宇科技自助研发的首款智能移动显示操作系统,设计非常人性化。可能会可折叠计自助研发的首款智能移动显示操作系统,设计非常人性化。可能会可折自助研发的首款智能移动显示操作系统,设计非常人性化。可能会可折自助研发的首款智能移动显示操作系统,设计非常人性化。可能会可折',
          title: '这里是标题',
          cover: loop5,
        },
      ],
      // 当前展示项
      loopCenterIdx: 2,
      // 轮播样式模板,用来循环赋值给 容器
      loopModules: [
        {
          loopIdx: 0,
          style: {
            'z-index': 7,
            background: '#fff',
            transform: `scale(${1})`,
            left: 'calc(100% / 5 * 0)',
            height: '320px',
            opacity: 0.8,
          },
        },
        {
          loopIdx: 1,
          style: {
            'z-index': 8,
            transform: `scale(${1.4})`,
            background: '#fff',
            left: 'calc(100% / 5 * .9)',
            height: '320px',
            opacity: 0.9,
          },
        },
        {
          loopIdx: 2,
          style: {
            transform: `scale(${1.7})`,
            'z-index': 9,
            background: '#fff',
            left: 'calc(100% / 5 * 2)',
            opacity: 1,
            'box-shadow': '0 0 5px #ccc',
            height: '370px',
          },
        },
        {
          loopIdx: 3,
          style: {
            transform: `scale(${1.4})`,
            'z-index': 8,
            background: '#fff',
            left: 'calc(100% / 5 * 3.1)',
            opacity: 0.9,
            height: '320px',
          },
        },
        {
          loopIdx: 4,
          style: {
            'z-index': 7,
            transform: `scale(${1})`,
            background: '#fff',
            left: 'calc(100% / 5 * 4)',
            height: '320px',
            opacity: 0.8,
          },
        },
      ],
    };
  },
  created(){
    // todo Ajax ...
  },
  mounted() {
    // 初始化轮播
    this.initLoop();
    console.log('centerIdx = ', this.loopCenterIdx);
  },
  methods: {
    // 初始化轮播
    initLoop() {
      this.loopModules = this.loopModules.map((item, idx) => {
        item.desc = this.baseData[idx];
        return item;
      });
      console.log(this.loopModules);
    },
    // 下一张
    handleNext() {
      this.loopCenterIdx = this.loopCenterIdx + 1 > 4 ? 0 : this.loopCenterIdx + 1;
      this.loopModules = this.loopModules.map((item, idx) => {
        item.desc = this.baseData[idx];
        return item;
      });
      this.loopModules.unshift(this.loopModules.pop());
    },
    // 上一张
    handleLast() {
      this.loopCenterIdx = this.loopCenterIdx - 1 < 0 ? 4 : this.loopCenterIdx - 1;
      this.loopModules = this.loopModules.map((item, idx) => {
        item.desc = this.baseData[idx];
        return item;
      });
      this.loopModules.push(this.loopModules.shift());
    },
    // 点击容器
    handleLoop(checkId) {
      console.log('checkId = ', checkId, ', loopCenterIdx = ', this.loopCenterIdx);
      // 当前项
      if (checkId === this.loopCenterIdx) {
        return;
      }
      if (checkId > this.loopCenterIdx) {
        if (this.loopCenterIdx === 0 && checkId === 4) {
          return this.handleLast(checkId);
        } else {
          return this.handleNext(checkId);
        }
      }
      if (checkId < this.loopCenterIdx) {
        if (checkId === 0 && this.loopCenterIdx === 4) {
          return this.handleNext(checkId);
        } else {
          return this.handleLast(checkId);
        }
      }
    },
  },
};
</script>

js代码里面有两个地方需要注意的:

  • 可以看到在上一张和下一张对应的方法里面,有两个一行代码。其作用就是让5个容器转起来。
this.loopModules.unshift(this.loopModules.pop());
// [1,2,3,4] =&gt; [2,3,4,1]
this.loopModules.push(this.loopModules.shift());
// [1,2,3,4] =&gt; [4,1,2,3]
  • 在 handleLoop 方法中,需要注意展示项为 第一个 和 最后一个 的时候,和正常判断逻辑相反。

后记

轮播作为一个日常开发中最常见的组件,想必每一个前端都在学习js的时候将他作为一个很有意思的 demo 练过手,而景深卡片轮播算是比基础轮播稍微难一点的效果了。

这个组件值得记录下来的是把数据驱动视图的思路更好的进行了一次展示,这也是基于框架开发和原生开发的一个重要的转变。如果在 jquery 中,可能会用 $(selector).animate() 去控制动画效果,原生 js 中也会封装一个类似 animate() 的方式去逐帧的实现一系列的动画,而在 vue 中,直接修改数据的顺序,或者修改数据值,就让 dom 动起来了。

数据驱动视图的思路下,我们就不必去关注视图的变化,也不用频繁的去操作dom元素,只需考虑清除一组可以控制视图变化的链路就好了。例如:分页组件只需要关注当前页码和每页显示数量,表格组件只需要关注列数据的变化等等。其他的部分框架已经做了很多。

路还很长,每走一步都有新感悟!

以上就是Vue组件实现景深卡片轮播示例的详细内容,更多关于Vue景深卡片轮播的资料请关注我们其它相关文章!

(0)

相关推荐

  • Vue+ECharts实现中国地图的绘制及各省份自动轮播高亮显示

    目录 实现效果 完整代码+详细注释 要点小结 实现效果 完整代码+详细注释 <template> <div class="echart"> <div class="content"> <div id="map_cn"></div> </div> </div> </template> <script> import echarts from

  • vue实现卡片翻转轮播展示

    vue卡片翻转轮播展示,同时在翻转时切换数据,供大家参考,具体内容如下 效果及代码 代码: <template> <div class="list-container"> <div class="reason" v-if="list1.length > 0 || list2.length > 0"> <div class="logo"> <svg-icon cl

  • vue3.x使用swiper实现卡片轮播

    本文实例为大家分享了vue3.x使用swiper实现卡片轮播的具体代码,供大家参考,具体内容如下 版本号: vue/cli:4.5.12swiper:^6.8.4 安装 npm install --save swiper 使用以及配置 <div class="swiper-container home_swiper">     <div class="swiper-wrapper">         <div class="s

  • vue3封装轮播图组件的方法

    目的 封装轮播图组件,直接使用,具体内容如下 大致步骤 准备my-carousel组件基础布局,全局注册 准备home-banner组件,使用my-carousel组件,再首页注册使用. 深度作用选择器覆盖my-carousel组件的默认样式 在home-banner组件获取轮播图数据,传递给my-carousel组件 在my-carousel组件完成渲染 自动播放,暴露自动轮播属性,设置了就自动轮播 如果有自动播放,鼠标进入离开,暂停,开启 指示器切换,上一张,下一张 销毁组件,清理定时器 落

  • Vue实现首页banner自动轮播效果

    本文实例为大家分享了Vue实现首页banner自动轮播的具体代码,供大家参考,具体内容如下 效果如图: ①创建Banner.vue组件,需传入banner数组,可设置轮播间隔ms <template>   <div class="m-banner-wrap" v-if="bannerData.length">     <div class="m-banner-list">       <div      

  • Vue组件实现景深卡片轮播示例

    目录 前言 需求拆解 开发思路(vue2) 开发过程 后记 前言 朋友的朋友做了个首页,首页用到一个卡片轮播,大概就是这个样子的: 第一版他们是开发出来了,但是各种bug,希望我帮忙改一下. 看完代码以后,发现他们整合了一个缝合怪出来,各个楼层都是从其他地方 CV 过来的,而且各个楼层引用了 n 多个js 和 css 文件,看了一下效果以后,觉得改他的东西确实比重新开发一个要麻烦的多得多,所以就重新写了一下. 在此记录一下,以便于后续复用. 需求拆解 初始化渲染5个容器,用来承载图片和标题,按照

  • vue移动端轻量级的轮播组件实现代码

    一个简单的移动端卡片滑动轮播组件,适用于Vue2.x c-swipe 2.0 全新归来.重写了全部的代码,更靠谱的质量,更优秀的性能 English Document 安装 npm install c-swipe --save 使用 注册组件 // main.js // 引入 c-swipe 主文件 import 'c-swipe/dist/swipe.css'; import { Swipe, SwipeItem } from 'c-swipe'; // 全局注册组件 Vue.componen

  • react 组件实现无缝轮播示例详解

    目录 正文 无缝轮播 实现思路 构思使用时代码结构 Carousel组件 CarouselItem组件 完善组件 完成小圆点 正文 需求是做一个无缝轮播图,我说这不是有很多现成的轮子吗?后来了解到他有一个特殊的需求,他要求小圆点需要在轮播图外面,因为现在大部分插件都是将小圆点写在轮播图内部的,这对于不了解插件内部结构的小伙伴确实不知道如何修改. 很久没有写插件的我准备写一个插件(react) 无缝轮播 无缝轮播从最后一张到第一张的过程中不会原路返回,它就像轮子似的,从结束到开始是无缝连接的,非常

  • 利用Vue实现移动端图片轮播组件的方法实例

    前言 轮播图的插件也有很多,用jQuery写起来也不难,这里分享的是关于利用Vue实现移动端图片轮播组件的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍: wc-swiper 基于 Vue 的移动端的图片轮播组件. Why 之前一直在用 vue-awesome-swiper, 功能很齐全, 但是唯一的问题就是体积比较大. 我只是想要一个简单的图片轮播, 但是却要引入 100多k 大小的文件, 这样是不对的. 特点 支持自动播放 & 无限轮播 (loop) 效果 支持用户滑

  • Vue中使用better-scroll实现轮播图组件

    better-scroll 是什么 better-scroll 是一款重点解决移动端(已支持 PC)各种滚动场景需求的插件.它的核心是借鉴的 iscroll 的实现,它的 API 设计基本兼容 iscroll,在 iscroll 的基础上又扩展了一些 feature 以及做了一些性能优化. better-scroll 是基于原生 JS 实现的,不依赖任何框架.它编译后的代码大小是 63kb,压缩后是 35kb,gzip 后仅有 9kb,是一款非常轻量的 JS lib. 今天我们利用它实现一个横向

  • vue使用swiper插件实现轮播图的示例

    hello大家好,最近我在做一个仿饿了么的项目,我会将我的项目经验同步到这里,与大家分享! vue - 使用swiper插件实现轮播图 下载安装: npm install swiper --save Msite.vue的HTML部分: <!--在页面msite_nav导航部分使用swiper--> <div class="swiper-container"> <div class="swiper-wrapper"> <div

  • Vue封装Swiper实现图片轮播效果

    图片轮播是前端中经常需要实现的一个功能.最近学习Vue.js,就针对Swiper进行封装,实现一个简单的图片轮播组件. 一.Swiper 在实现封装之前,先介绍一下Swiper. Swiper是纯Javascript打造的滑动特效插件,面向手机.平板电脑等移动终端. Swiper能实现触屏焦点图.触屏Tab切换.触屏多图切换等常用效果. Swiper开源.免费.稳定.使用简单.功能强大,是架构移动终端网站的重要选择. Swiper的应用场景广泛,实现效果很好,下面个这实际案例就是Swiper的典

  • vue自定义js图片碎片轮播图切换效果的实现代码

    定义一个banner.js文件,代码如下 ;window.requestAnimationFrame = window.requestAnimationFrame||function(a){return setTimeout(a,1000/60)}; window.cancelAnimationFrame = window.cancelAnimationFrame||clearTimeout; var FragmentBanner = function(option) { //实例化时,可传的参

  • vue组件中使用iframe元素的示例代码

    本文介绍了vue组件中使用iframe元素的示例代码,分享给大家,具体如下: 需要在本页面中展示vue组件中的超链接,地址栏不改变的方法: <template> <div class="accept-container"> <div class="go-back" v-show="goBackState" @click="goBack">GoBack</div> <ul&g

随机推荐