iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >Vue实现轮播图组件的封装
  • 595
分享到

Vue实现轮播图组件的封装

Vue轮播图组件封装Vue组件封装 2023-05-16 20:05:57 595人浏览 八月长安
摘要

目录轮播图功能-获取数据轮播图-通用轮播图组件轮播图-数据渲染轮播图-逻辑封装轮播图功能-获取数据 目标: 基于pinia获取轮播图数据 核心代码: (1)在types/data.d

轮播图功能-获取数据

目标: 基于pinia获取轮播图数据

核心代码:

(1)在types/data.d.ts文件中定义轮播图数据的类型声明

// 所有接口的通用类型
export type apiRes <T> = {
    code: string,
    msg: string,
    result: T
}
// 轮播图类型
export type BannerItem = {
  hrefUrl: string
  id: string
  imgUrl: string
  type: string
}

(2)在store/home.ts文件中封装接口,用于获取轮播图数据

import { ApiRes, BannerItem } from '@/types/data'
import request from '@/utils/request'
import { defineStore } from 'pinia'
export default defineStore('home', {
  state: () => ({
    bannerList: [] as BannerItem[],
  }),
  actions: {
    async getBannerList() {
      const {data: res} = await request.get<ApiRes<BannerItem[]>>('/home/banner')
      this.bannerList = res.result
    },
  },
})

(3)在store/index.ts中导入

import useCateGoryStore from './modules/category'
import useHomeStore from './modules/home'
export default function useStore() {
  return {
    category: useCategoryStore(),
    home: useHomeStore(),
  }
}

(4)通过开发工具查看数据

<script lang="ts" setup>
import useStore from '@/store'
const { home } = useStore()
home.getBannerList()
</script>

轮播图-通用轮播图组件

项目中会多次使用到轮播图组件,但是轮播图渲染的数据是不一样的。

但是轮播图的基本功能都是一样的,比如图片切换,自动播放等等。

因此需要封装一个通用的轮播图组件。

(1)通用轮播图的基本结构src/components/carousel/index.Vue

fade 类:用于控制图片的显示和隐藏

active 类:用于控制小圆点高亮

<script lang="ts" setup name="Carousel">
defineProps()
</script>
<template>
  <div class="carousel">
    <ul class="carousel-body">
      <li class="carousel-item fade">
        <RouterLink to="/">
          <img
            src="Http://yjy-xiaotuxian-dev.oss-cn-beijing.aliyuncs.com/picture/2021-04-15/1ba86bcc-ae71-42a3-bc3e-37b662f7f07e.jpg"
            alt=""
          />
        </RouterLink>
      </li>
      <li class="carousel-item">
        <RouterLink to="/">
          <img
            src="http://yjy-xiaotuxian-dev.oss-cn-beijing.aliyuncs.com/picture/2021-04-15/1ba86bcc-ae71-42a3-bc3e-37b662f7f07e.jpg"
            alt=""
          />
        </RouterLink>
      </li>
      <li class="carousel-item">
        <RouterLink to="/">
          <img
            src="http://yjy-xiaotuxian-dev.oss-cn-beijing.aliyuncs.com/picture/2021-04-15/1ba86bcc-ae71-42a3-bc3e-37b662f7f07e.jpg"
            alt=""
          />
        </RouterLink>
      </li>
    </ul>
    <a href="javascript:;" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  class="carousel-btn prev"
      ><i class="iconfont icon-angle-left"></i
    ></a>
    <a href="javascript:;" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  class="carousel-btn next"
      ><i class="iconfont icon-angle-right"></i
    ></a>
    <div class="carousel-indicator">
      <span class="active"></span>
      <span></span>
      <span></span>
      <span></span>
      <span></span>
    </div>
  </div>
</template>
<style scoped lang="less">
.xtxcarousel {
  width: 100%;
  height: 100%;
  min-width: 300px;
  min-height: 150px;
  position: relative;
  .carousel {
    &-body {
      width: 100%;
      height: 100%;
    }
    &-item {
      width: 100%;
      height: 100%;
      position: absolute;
      left: 0;
      top: 0;
      opacity: 0;
      transition: opacity 0.5s linear;
      &.fade {
        opacity: 1;
        z-index: 1;
      }
      img {
        width: 100%;
        height: 100%;
      }
    }
    &-indicator {
      position: absolute;
      left: 0;
      bottom: 20px;
      z-index: 2;
      width: 100%;
      text-align: center;
      span {
        display: inline-block;
        width: 12px;
        height: 12px;
        background: rgba(0, 0, 0, 0.2);
        border-radius: 50%;
        cursor: pointer;
        ~ span {
          margin-left: 12px;
        }
        &.active {
          background: #fff;
        }
      }
    }
    &-btn {
      width: 44px;
      height: 44px;
      background: rgba(0, 0, 0, 0.2);
      color: #fff;
      border-radius: 50%;
      position: absolute;
      top: 228px;
      z-index: 2;
      text-align: center;
      line-height: 44px;
      opacity: 0;
      transition: all 0.5s;
      &.prev {
        left: 20px;
      }
      &.next {
        right: 20px;
      }
    }
  }
  &:hover {
    .carousel-btn {
      opacity: 1;
    }
  }
}
</style>

(2)全局注册通用轮播图 src/components/index.ts

import type { App } from 'vue'
import skelecton from './skeleton/index.vue'
+import Carousel from './carousel/index.vue'
export default {
  install(app: App) {
    app.component(skelecton.name, skelecton)
+    app.component(Carousel.name, Carousel)
  },
}

(3)在广告组件中使用src/views/home/components/home-banner.vue

<template>
  <div class="home-banner">
    <!-- 轮播图 -->
    <Carousel></XtxCarousel>
  </div>
</template>

(4)覆盖样式,控制箭头和小圆点的位置src/views/home/components/home-banner.vue

:deep(.carousel-btn.prev) {
  left: 270px!important;
}
:deep(.carousel-indicator) {
  padding-left: 250px;
}

(5)查看效果

轮播图-数据渲染

目的

home-banner组件把数据传递给Carousel组件进行渲染

(1)父传子的方式将数据传给通用轮播图组件src/views/home/components/home-banner.vue

<Carousel :slides="home.bannerList"></Carousel>

(2)子组件接收数据src/components/carousel/index.vue

了解写法:如果通过js的方法定义类型,需要单独引入PropType进行编写

<script lang="ts" setup name="Carousel">
import { BannerItem } from '@/types/data'
// import { PropType } from 'vue'
// defineProps({
//   slides: {
//     type: Array as PropType<BannerItem[]>,
//     required: true,
//   },
// })
defineProps<{
  slides: BannerItem[]
}>()
</script>

(3)渲染轮播图数据src/components/carousel/index.vue

<template>
  <div class="carousel">
    <ul class="carousel-body">
      <li class="carousel-item fade" v-for="item in slides" :key="item.id">
        <RouterLink :to="item.hrefUrl">
          <img :src="item.imgUrl" alt="" />
        </RouterLink>
      </li>
    </ul>
    <a href="javascript:;" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  class="carousel-btn prev">
      <i class="iconfont icon-angle-left"></i>
    </a>
    <a href="javascript:;" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  class="carousel-btn next">
      <i class="iconfont icon-angle-right"></i>
    </a>
    <div class="carousel-indicator">
      <span v-for="item in slides" :key="item.id" class="active"></span>
    </div>
  </div>
</template>

(4)控制高亮的下标

<script lang="ts" setup name="Carousel">
const active = ref(0)
</script>

(5)高亮渲染

  • 添加的fade的图片才会展示,所以根据当前索引号进行判断,索引号等于active的才进行展示
  • 添加了active类名的小圆点才会高亮,高亮逻辑跟图片一致
<template>
  <div class="carousel">
    <ul class="carousel-body">
      <li
        class="carousel-item"
+        :class="{ fade: active === index }"
+        v-for="(item, index) in slides"
        :key="item.id"
      >
        <RouterLink :to="item.hrefUrl">
          <img :src="item.imgUrl" alt="" />
        </RouterLink>
      </li>
    </ul>
    <a href="javascript:;" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  class="carousel-btn prev">
      <i class="iconfont icon-angle-left"></i>
    </a>
    <a href="javascript:;" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  class="carousel-btn next">
      <i class="iconfont icon-angle-right"></i>
    </a>
    <div class="carousel-indicator">
      <span
+        v-for="(item, index) in slides"
        :key="item.id"
+        :class="{ active: active === index }"
      ></span>
    </div>
  </div>
</template>

轮播图-逻辑封装

实现需求:

轮播图里面的图片需要从父组件传入(因为轮播组件可以复用)

父组件需要控制轮播图的是否自动播放、动画时间(处理默认值逻辑)

是否自动播放和动画时间都是需要默认值的(如果不传就可以使用轮播组件自己提供的默认值)

播放逻辑

  • 点击小圆点可以切换图片
  • 点击prev和next按钮可以播放指定图片(根据图片个数判断播放的循环)
  • 如果父组件配置了自动播放,则需要定时播放图片
  • 鼠标进入轮播图,暂停轮播
  • 鼠标离开轮播图,继续轮播
  • 注意点:组件卸载的时候需要清除定时轮播效果(不然组件重新加载的时候会导致多个定时器开启)

(1)父组件传值给轮播图src/views/home/components/home-banner.vue

<template>
  <div class="home-banner">
    <!-- 轮播图 -->
    <Carousel :slides="slides" autoPlay :duration="3000"></XtxCarousel>
  </div>
</template>

(2)props接收src/components/Carousel.vue

<script lang="ts" setup name="Carousel">
import { BannerItem } from '@/types/data'
import { ref, PropType } from 'vue'
defineProps({
  slides: {
    type: Array as PropType<BannerItem[]>,
    required: true,
  },
  autoPlay: {
    type: Boolean,
    default: false,
  },
  duration: {
    type: Number,
    default: 3000,
  },
})
const active = ref(0)
</script>

(3)轮播图的播放逻辑

<script lang="ts" setup name="Carousel">
import { BannerItem } from '@/types/data'
import { onMounted, onUnmounted, PropType, ref } from 'vue'
// import { PropType } from 'vue'
const props = defineProps({
  slides: {
    type: Array as PropType<BannerItem[]>,
    required: true,
  },
  duration: {
    type: Number,
    default: 3000,
  },
  autoPlay: {
    type: Boolean,
    default: false,
  },
})
// const props = defineProps<{
//   slides: BannerItem[]
// }>()
// 控制高亮
const active = ref(0)
const prev = () => {
  if (active.value <= 0) {
    active.value = props.slides.length - 1
  } else {
    active.value--
  }
}
const next = () => {
  if (active.value >= props.slides.length - 1) {
    active.value = 0
  } else {
    active.value++
  }
}
const play = () => {
  // 如果没有自动播放
  if (!props.autoPlay) return
  // 在ts中,使用定时器,window.setInterval
  timer = window.setInterval(() => {
    next()
  }, props.duration)
}
const stop = () => {
  clearInterval(timer)
}
let timer = -1
// 自动播放
onMounted(() => {
  play()
})
onUnmounted(() => {
  stop()
})
</script>

(4)鼠标进入和离开操作

<div class="carousel" @mouseenter="stop" @mouseleave="play">

(5)鼠标经过小圆点切换

<span
  v-for="(item, index) in slides"
  :key="item.id"
  :class="{ active: active === index }"
  @mouseenter="active = index"
></span>

(6)点击左右箭头切换

const prev = () => {
  if (active.value === 0) {
    active.value = props.slides.length - 1
  } else {
    active.value--
  }
}
const next = () => {
  if (active.value === props.slides.length - 1) {
    active.value = 0
  } else {
    active.value++
  }
}
// 注册事件
<a href="javascript:;" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  class="carousel-btn prev" @click="prev">
  <i class="iconfont icon-angle-left"></i>
</a>
<a href="javascript:;" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  class="carousel-btn next" @click="next">
  <i class="iconfont icon-angle-right"></i>
</a>
vascript
const prev = () => {
  if (active.value === 0) {
    active.value = props.slides.length - 1
  } else {
    active.value--
  }
}
const next = () => {
  if (active.value === props.slides.length - 1) {
    active.value = 0
  } else {
    active.value++
  }
}
// 注册事件
<a href="javascript:;" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  class="carousel-btn prev" @click="prev">
  <i class="iconfont icon-angle-left"></i>
</a>
<a href="javascript:;" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  class="carousel-btn next" @click="next">
  <i class="iconfont icon-angle-right"></i>
</a>

到此这篇关于Vue实现轮播图组件的封装的文章就介绍到这了,更多相关Vue轮播图组件封装内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Vue实现轮播图组件的封装

本文链接: https://www.lsjlt.com/news/210536.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Vue实现轮播图组件的封装
    目录轮播图功能-获取数据轮播图-通用轮播图组件轮播图-数据渲染轮播图-逻辑封装轮播图功能-获取数据 目标: 基于pinia获取轮播图数据 核心代码: (1)在types/data.d...
    99+
    2023-05-16
    Vue轮播图组件封装 Vue组件封装
  • vue3+Pinia+TypeScript 实现封装轮播图组件
    目录为什么封装?静态结构 后面再进行更改请求数据都存放在pinia里面类型检测页面级组件全局组件为什么封装? 迎合es6模块化开发思想注册为全局组件,可以更好地复用,需要用到的地方,...
    99+
    2022-11-13
  • vue3封装轮播图组件的方法
    目的 封装轮播图组件,直接使用,具体内容如下 大致步骤 准备my-carousel组件基础布局,全局注册 准备home-banner组件,使用my-carousel...
    99+
    2022-11-12
  • Vue使用Swiper封装轮播图组件的方法详解
    目录Swiper为什么要封装组件开始封装1.下载安装Swiper2.引入css样式文件3.引入js文件4.把官网使用方法中的HTML结构复制粘贴过来5.初始化Swiper自定义效果完...
    99+
    2022-11-13
  • 怎么使用vue轮播组件vue-awesome-swiper实现轮播图
    这篇文章主要讲解了“怎么使用vue轮播组件vue-awesome-swiper实现轮播图”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么使用vue轮播组件vue-awesome-swipe...
    99+
    2023-07-04
  • Vue封装Swiper如何实现图片轮播效果
    小编给大家分享一下Vue封装Swiper如何实现图片轮播效果,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!图片轮播是前端中经常需...
    99+
    2022-10-19
  • Vue怎么封装Swiper实现图片轮播效果
    这篇“Vue怎么封装Swiper实现图片轮播效果”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Vue怎么封装Swiper实现...
    99+
    2023-07-04
  • 基于vue.js轮播组件vue-awesome-swiper实现轮播图的示例分析
    这篇文章主要为大家展示了“基于vue.js轮播组件vue-awesome-swiper实现轮播图的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“基于vu...
    99+
    2022-10-19
  • uniapp vue与nvue轮播图之轮播图组件的示例代码
    vue部分如下: <template> <view class=""> <!-- 轮播图组件 --> <swiper :ind...
    99+
    2022-11-12
  • vue实现轮播图片
    本文实例为大家分享了vue实现轮播图片的具体代码,供大家参考,具体内容如下 1、效果图 2、案例 <template>        <section class...
    99+
    2022-09-27
  • VueEcharts实现图表轮播图以及图表组件封装和节流函数优化讲解
    目录一、为什么要优雅的使用echarts二、最初的表格组件三、初步的封装四、性能优化一、为什么要优雅的使用echarts 为了提高代码的规范性、复用性,vue中最常用的就是将具有某些...
    99+
    2023-01-09
    Vue Echarts图表轮播图 Vue Echarts图表组件封装 Vue Echarts节流函数优化
  • uniapp小程序开发组件封装之自定义轮播图效果
    目录前言:正文1、首先了解swiper组件1.1、小小的demo示例:1.2、自定义轮播图效果展示说明2、完成自定义轮播图效果3、组件封装——自定义轮播图3....
    99+
    2023-02-06
    uniapp自定义轮播图 uniapp小程序开发 uniapp组件封装
  • Vue实现可复用轮播组件的方法
    本文用vue简单的实现了一个轮播图的基础功能,并抽离出来作为一个公共组件,方便复用 html和js部分 <template>   <div     class="i...
    99+
    2022-09-27
  • vue轮播组件如何实现$children和$parent
    这篇文章主要为大家展示了“vue轮播组件如何实现$children和$parent”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“vue轮播组件如何实现$chil...
    99+
    2022-10-19
  • vue使用swiper插件实现轮播图的示例
    目录vue - 使用swiper插件实现轮播图 使用watch与$nextTick解决轮播的Bug hello大家好,最近我在做一个仿饿了么的项目,我会将我的项目经验同步到这里,与大...
    99+
    2022-11-12
  • Vue组件封装怎么实现
    这篇文章主要介绍“Vue组件封装怎么实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Vue组件封装怎么实现”文章能帮助大家解决问题。一、组件封装的优势复用性:组件封装可以将常用的功能或视图模块抽象...
    99+
    2023-07-05
  • vue使用swiper插件实现垂直轮播图
    目录使用swiper插件做垂直轮播图swiper轮播插件使用 一次显示多个slidesSwiper 动态加载数据遇到的坑总结使用swiper插件做垂直轮播图 1.下载安装 cnpm ...
    99+
    2023-01-14
    vue使用swiper插件 vue垂直轮播图 vue swiper插件
  • Vue组件实现景深卡片轮播示例
    目录前言需求拆解开发思路(vue2)开发过程后记前言 朋友的朋友做了个首页,首页用到一个卡片轮播,大概就是这个样子的: 第一版他们是开发出来了,但是各种bug,希望我帮忙改一下。 ...
    99+
    2022-11-13
  • 怎么用vue轮播组件实现$children和$children
    这篇文章主要介绍了怎么用vue轮播组件实现$children和$children的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么用vue轮播组件实现$children和$children文章都会有所收获,下面...
    99+
    2023-07-04
  • vue-echarts如何实现图表组件封装详解
    目录背景:有哪些工具?怎么封装?总结背景: 需要大量使用图表的项目,为了提升开发效率,可以对图表类进行封装成组件,方便页面的搭建,也能进行统一管理维护,即使后面系统风格需要调整,调整...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作