vue3 ts组件封装
穿山甲钻代码 人气:1引言
对于一名前端程序员来说封装组件是一个必备技能。当我们在日常的工作中总有所用的组件库满足不了需求的情况,这就需要我们有封装组件的基本功了。 封装组件,可以提高我们代码的复用性,提高工作效率,提高代码的可阅读性。
组件我自己的理解的话,分为两种吧,一种是工具类的组件,一种是页面级别的组件,工具类的组件就是说封装后,在以后的项目中如果用相同的应用场景时,可复用。页面类组件的话就是将一个大的页面分成很多的小组件,然后进行拼接,组成大页面,让页面看起来不臃肿,美观,提高代码的阅读性。方便后期的维护管理。
轮播图组件的封装
在父组件中留出位置放子组件(子组件为全局组件。)在pinia中发送请求拿数据 在拿到数据后cope value 去拿泛型。父传子的方式去在子组件中接收数据,在子组件中去做相应的业务逻辑,自动播放,按钮,前进后退等功能。
在pinia中发请求拿到数据
import request from '@/utils/request' import { defineStore } from 'pinia' import {IApiRes, banneritem } from '@/types/data' export default defineStore('home',{ state:()=>{ return{ bannerlist: [] as banneritem[] } }, actions:{ // 获取轮播图数据 async getBannerList(){ const res = await request.get<IApiRes<banneritem[]>>('/home/banner') console.log(res,'2222222'); this.bannerlist = res.data.result },
types/data中进行泛型补充:
// 所有的接口的通用类型 export interface IApiRes<T> { code: string msg: string result: T } // banner轮播图类型 export type banneritem={ id: string; imgUrl: string; hrefUrl: string; type: string; }
父组件中
<script lang="ts" setup> import useStore from '@/store'; //子组件引入 import Carousel from '@/components/Carousel/index.vue'; const { home} = useStore() home.getBannerList() </script> <template> <div class="home-banner"> <!-- 轮播图 --> <!-- <carousel :slides="home.Bannerlist" :autoPlay="true" :duration="2000"></carousel> --> <Carousel :slides="home.bannerlist" :autoplay="true" :duration="2000" ></Carousel> </div> </template>
在父组件中使用传入相应的参数即可。
在子组件中
相应的样式及业务逻辑,都有注释,我就不一一写了。
<script lang="ts" setup name="Carousel"> import { banneritem } from '@/types/data'; import { onBeforeMount, onMounted, ref } from 'vue'; // 接收父组件传过来的数据 const {slides, autoplay=true, duration=3000} = defineProps<{ slides:banneritem[], autoplay:boolean, duration:number }>() // 当前选择的是那一张图片。 let active = ref(0) // 左侧箭头 const hleft = ()=>{ active.value-- if(active.value < 0){ active.value = slides.length-1 } } // 右侧箭头 const hright = ()=>{ active.value++ if(active.value > slides.length - 1){ active.value = 0 } } let timer = -1 // 鼠标离开开启自动播放 const start = ()=>{ if(autoplay){ // 在ts中,使用定时器,注意:window.setInterval timer =window.setInterval(()=>{ hright() },duration) } } // 鼠标进入停止自动播放 const stop = ()=>{ clearInterval(timer) } // 点击小圆点跳转 const ind= (id:number)=>{ active.value = id } //在页面加载时 自动播放 onMounted(()=>{ start() }) // 在页面关闭时,销毁组件 停止播放 onBeforeMount(()=>{ stop() }) </script> <template> <!-- fade类表示当前图片可见 --> <div class="xtx-carousel" @mouseleave="start" @mouseenter="stop" > <ul class="carousel-body"> <li class="carousel-item " :class="{fade :index === active}" v-for="(item,index ) in slides" :key="item.id"> <RouterLink to="/"> <img :src="item.imgUrl" alt="" /> </RouterLink> </li> </ul> <!-- 左边箭头 --> <a href="javascript:;" rel="external nofollow" rel="external nofollow" class="carousel-btn prev" @click="hleft" ><i class="iconfont icon-angle-left"></i ></a> <!-- 右边箭头 --> <a href="javascript:;" rel="external nofollow" rel="external nofollow" class="carousel-btn next" @click="hright" ><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}" @mouseenter="ind(index)" ></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>
加载全部内容