深圳网站建设公司 交通,新余做网站的,wordpress 家具,网站更改备案信息在哪里文章目录轮播图功能-获取数据轮播图-通用轮播图组件轮播图-数据渲染轮播图-逻辑封装轮播图功能-获取数据 目标: 基于pinia获取轮播图数据 核心代码#xff1a;
#xff08;1#xff09;在types/data.d.ts文件中定义轮播图数据的类型声明
// 所有接口的通用类型
export typ…
文章目录轮播图功能-获取数据轮播图-通用轮播图组件轮播图-数据渲染轮播图-逻辑封装轮播图功能-获取数据 目标: 基于pinia获取轮播图数据 核心代码
1在types/data.d.ts文件中定义轮播图数据的类型声明
// 所有接口的通用类型
export type ApiRes T {code: string,msg: string,result: T
}
// 轮播图类型
export type BannerItem {hrefUrl: stringid: stringimgUrl: stringtype: string
}2在store/home.ts文件中封装接口用于获取轮播图数据
import { ApiRes, BannerItem } from /types/data
import request from /utils/request
import { defineStore } from piniaexport default defineStore(home, {state: () ({bannerList: [] as BannerItem[],}),actions: {async getBannerList() {const {data: res} await request.getApiResBannerItem[](/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 langts setup
import useStore from /storeconst { home } useStore()
home.getBannerList()
/script轮播图-通用轮播图组件
项目中会多次使用到轮播图组件但是轮播图渲染的数据是不一样的。
但是轮播图的基本功能都是一样的比如图片切换自动播放等等。
因此需要封装一个通用的轮播图组件。
1通用轮播图的基本结构src/components/carousel/index.vue
fade 类用于控制图片的显示和隐藏
active 类用于控制小圆点高亮
script langts setup nameCarousel
defineProps()
/scripttemplatediv classcarouselul classcarousel-bodyli classcarousel-item fadeRouterLink to/imgsrchttp://yjy-xiaotuxian-dev.oss-cn-beijing.aliyuncs.com/picture/2021-04-15/1ba86bcc-ae71-42a3-bc3e-37b662f7f07e.jpgalt//RouterLink/lili classcarousel-itemRouterLink to/imgsrchttp://yjy-xiaotuxian-dev.oss-cn-beijing.aliyuncs.com/picture/2021-04-15/1ba86bcc-ae71-42a3-bc3e-37b662f7f07e.jpgalt//RouterLink/lili classcarousel-itemRouterLink to/imgsrchttp://yjy-xiaotuxian-dev.oss-cn-beijing.aliyuncs.com/picture/2021-04-15/1ba86bcc-ae71-42a3-bc3e-37b662f7f07e.jpgalt//RouterLink/li/ula hrefjavascript:; classcarousel-btn previ classiconfont icon-angle-left/i/aa hrefjavascript:; classcarousel-btn nexti classiconfont icon-angle-right/i/adiv classcarousel-indicatorspan classactive/spanspan/spanspan/spanspan/spanspan/span/div/div
/templatestyle scoped langless
.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;}}
}
/style2全局注册通用轮播图 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
templatediv classhome-banner!-- 轮播图 --Carousel/XtxCarousel/div
/template4覆盖样式控制箭头和小圆点的位置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 :slideshome.bannerList/Carousel2子组件接收数据src/components/carousel/index.vue 了解写法如果通过js的方法定义类型需要单独引入PropType进行编写 script langts setup nameCarousel
import { BannerItem } from /types/data
// import { PropType } from vue// defineProps({
// slides: {
// type: Array as PropTypeBannerItem[],
// required: true,
// },
// })
defineProps{slides: BannerItem[]
}()
/script3渲染轮播图数据src/components/carousel/index.vue
templatediv classcarouselul classcarousel-bodyli classcarousel-item fade v-foritem in slides :keyitem.idRouterLink :toitem.hrefUrlimg :srcitem.imgUrl alt //RouterLink/li/ula hrefjavascript:; classcarousel-btn previ classiconfont icon-angle-left/i/aa hrefjavascript:; classcarousel-btn nexti classiconfont icon-angle-right/i/adiv classcarousel-indicatorspan v-foritem in slides :keyitem.id classactive/span/div/div
/template4控制高亮的下标
script langts setup nameCarouselconst active ref(0)
/script5高亮渲染 添加的fade的图片才会展示所以根据当前索引号进行判断索引号等于active的才进行展示添加了active类名的小圆点才会高亮高亮逻辑跟图片一致 templatediv classcarouselul classcarousel-bodyliclasscarousel-item:class{ fade: active index }v-for(item, index) in slides:keyitem.idRouterLink :toitem.hrefUrlimg :srcitem.imgUrl alt //RouterLink/li/ula hrefjavascript:; classcarousel-btn previ classiconfont icon-angle-left/i/aa hrefjavascript:; classcarousel-btn nexti classiconfont icon-angle-right/i/adiv classcarousel-indicatorspanv-for(item, index) in slides:keyitem.id:class{ active: active index }/span/div/div
/template轮播图-逻辑封装 实现需求 轮播图里面的图片需要从父组件传入(因为轮播组件可以复用)父组件需要控制轮播图的是否自动播放、动画时间处理默认值逻辑 是否自动播放和动画时间都是需要默认值的(如果不传就可以使用轮播组件自己提供的默认值) 播放逻辑 点击小圆点可以切换图片点击prev和next按钮可以播放指定图片(根据图片个数判断播放的循环)如果父组件配置了自动播放则需要定时播放图片鼠标进入轮播图暂停轮播鼠标离开轮播图继续轮播注意点组件卸载的时候需要清除定时轮播效果(不然组件重新加载的时候会导致多个定时器开启) 1父组件传值给轮播图src/views/home/components/home-banner.vue
templatediv classhome-banner!-- 轮播图 --Carousel :slidesslides autoPlay :duration3000/XtxCarousel/div
/template2props接收src/components/Carousel.vue
script langts setup nameCarousel
import { BannerItem } from /types/data
import { ref, PropType } from vuedefineProps({slides: {type: Array as PropTypeBannerItem[],required: true,},autoPlay: {type: Boolean,default: false,},duration: {type: Number,default: 3000,},
})const active ref(0)
/script3轮播图的播放逻辑
script langts setup nameCarousel
import { BannerItem } from /types/data
import { onMounted, onUnmounted, PropType, ref } from vue
// import { PropType } from vueconst props defineProps({slides: {type: Array as PropTypeBannerItem[],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.setIntervaltimer window.setInterval(() {next()}, props.duration)
}
const stop () {clearInterval(timer)
}let timer -1
// 自动播放
onMounted(() {play()
})onUnmounted(() {stop()
})
/script4鼠标进入和离开操作
div classcarousel mouseenterstop mouseleaveplay5鼠标经过小圆点切换
spanv-for(item, index) in slides:keyitem.id:class{ active: active index }mouseenteractive index
/span6点击左右箭头切换
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 hrefjavascript:; classcarousel-btn prev clickprevi classiconfont icon-angle-left/i
/a
a hrefjavascript:; classcarousel-btn next clicknexti classiconfont 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 hrefjavascript:; classcarousel-btn prev clickprevi classiconfont icon-angle-left/i
/a
a hrefjavascript:; classcarousel-btn next clicknexti classiconfont icon-angle-right/i
/a