怎么使用vue3+Pinia+TypeScript实现封装轮播图组件

广告:宝塔Linux面板高效运维的服务器管理软件 点击【 https://www.bt.cn/p/uNLv1L 】立即购买

怎么使用vue3+Pinia+TypeScript实现封装轮播图组件

为什么封装?

迎合es6模块化开发思想

注册为全局组件,可以更好地复用,需要用到的地方,直接使用标签即可

静态结构 后面再进行更改
<script lang="ts" setup name="XtxCarousel">defineProps()</script><template>  <div class="xtx-carousel">    <ul class="carousel-body">      <li class="carousel-item fade">        <RouterLink to="/">          <img            src="https://cache.yisu.com/upload/information/20220725/112/220.jpg"            alt=""          />        </RouterLink>      </li>      <li class="carousel-item">        <RouterLink to="/">          <img            src="https://cache.yisu.com/upload/information/20220725/112/220.jpg"            alt=""          />        </RouterLink>      </li>      <li class="carousel-item">        <RouterLink to="/">          <img            src="https://cache.yisu.com/upload/information/20220725/112/220.jpg"            alt=""          />        </RouterLink>      </li>    </ul>    <a href="javascript:;" 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"  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">.xtx-carousel {  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>
登录后复制请求数据都存放在pinia里面
import { defineStore } from 'pinia'import request from '@/utils/request'import { BannerItem, IApiRes } from '@/types/data'export default defineStore('home', {  persist: {    enabled: true  },    state() {    return {      bannerList: [] as BannerItem[]    }  },  actions: {    // 拿轮播图数据    async getBannerList() {      const res = await request.get<IApiRes<BannerItem[]>>('/home/banner')      console.log('拿轮播图数据', res)      this.bannerList = res.data.result    }  }})
登录后复制类型检测
// 所有的接口的通用类型export interface IApiRes<T> {  msg: string,  result: T}// 轮播图数据中的项export type BannerItem = {  id: string;  imgUrl: string;  hrefUrl: string;  type: string;}
登录后复制页面级组件
<script lang="ts" setup>import useStore from '@/store';const { home } = useStore()// 发请求home.getBannerList()</script><template>  <div class="home-banner">    <!-- 轮播图子组件 -->    <XtxCarousel :slides="home.bannerList" :autoPlay="true" :duration="1000"/>  </div></template><style scoped lang="less">.home-banner {  width: 1240px;  height: 450px;  position: absolute;  left: 0;  top: 0;  z-index: 98;  background-color: #ccc;}/deep/ .xtx-carousel .carousel-btn.prev {  left: 270px !important;}/deep/ .xtx-carousel .carousel-indicator {  padding-left: 250px;}</style>
登录后复制全局组件
<script lang="ts" setup name="XtxCarousel">import { BannerItem } from '@/types/data'import { onBeforeUnmount, onMounted, ref } from 'vue';// 定义propsconst { slides, autoPlay, duration } = defineProps<{  slides: BannerItem[],   autoPlay?: boolean, // 是否开启自动播放  duration?: number // 自动播放的间隔时间}>()// 当前哪个图片选中 高亮const active = ref(1)// 点击右侧箭头++const hNext = () => {  active.value++  if(active.value === slides.length){    active.value = 0  }}// 点击左侧箭头--const hPrev = () => {  active.value--  if(active.value < 0){    active.value = slides.length - 1  }}// 如果开启了自动播放,则每隔duration去播放下一张: hNext()onMounted(() => {  start()})onBeforeUnmount(() => {  stop()})let timer = -1// 鼠标离开要继续播放const start = () => {  if(autoPlay) {    timer = window.setInterval(() => {      hNext()    }, duration)  }}// 鼠标hover要暂停播放const stop = () => {  clearInterval(timer)}</script><template>  <div class="xtx-carousel" @mouseleave="start()" @mouseenter="stop()">    <ul class="carousel-body">      <li class="carousel-item"       :class="{ fade: idx === active}"      v-for="(it, idx) in slides" :key="it.id">        <RouterLink to="/">          <img :src="it.imgUrl" alt="" />        </RouterLink>      </li>    </ul>    <a @click="hPrev" href="javascript:;" 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 @click="hNext" href="javascript:;" 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="(it, idx) in slides"      :class="{ active: active===idx}"      @mouseenter="active = idx"      ></span>    </div>  </div></template><style scoped lang="less">.xtx-carousel {  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>
登录后复制

以上就是怎么使用vue3+Pinia+TypeScript实现封装轮播图组件的详细内容,更多请关注9543建站博客其它相关文章!

广告:SSL证书一年128.66元起,点击购买~~~

9543建站博客
一个专注于网站开发、微信开发的技术类纯净博客。
作者头像
admin创始人

肥猫,知名SEO博客站长,14年SEO经验。

上一篇:uniapp怎么避免“返回上一个页面”
下一篇:实现css

发表评论

关闭广告
关闭广告