vue3與ts組件封裝提高代碼復(fù)用性
引言
對于一名前端程序員來說封裝組件是一個(gè)必備技能。當(dāng)我們在日常的工作中總有所用的組件庫滿足不了需求的情況,這就需要我們有封裝組件的基本功了。 封裝組件,可以提高我們代碼的復(fù)用性,提高工作效率,提高代碼的可閱讀性。
組件我自己的理解的話,分為兩種吧,一種是工具類的組件,一種是頁面級別的組件,工具類的組件就是說封裝后,在以后的項(xiàng)目中如果用相同的應(yīng)用場景時(shí),可復(fù)用。頁面類組件的話就是將一個(gè)大的頁面分成很多的小組件,然后進(jìn)行拼接,組成大頁面,讓頁面看起來不臃腫,美觀,提高代碼的閱讀性。方便后期的維護(hù)管理。
輪播圖組件的封裝
在父組件中留出位置放子組件(子組件為全局組件。)在pinia中發(fā)送請求拿數(shù)據(jù) 在拿到數(shù)據(jù)后cope value 去拿泛型。父傳子的方式去在子組件中接收數(shù)據(jù),在子組件中去做相應(yīng)的業(yè)務(wù)邏輯,自動(dòng)播放,按鈕,前進(jìn)后退等功能。
在pinia中發(fā)請求拿到數(shù)據(jù)
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:{
// 獲取輪播圖數(shù)據(jù)
async getBannerList(){
const res = await request.get<IApiRes<banneritem[]>>('/home/banner')
console.log(res,'2222222');
this.bannerlist = res.data.result
},
types/data中進(jìn)行泛型補(bǔ)充:
// 所有的接口的通用類型
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>
在父組件中使用傳入相應(yīng)的參數(shù)即可。
在子組件中
相應(yīng)的樣式及業(yè)務(wù)邏輯,都有注釋,我就不一一寫了。
<script lang="ts" setup name="Carousel">
import { banneritem } from '@/types/data';
import { onBeforeMount, onMounted, ref } from 'vue';
// 接收父組件傳過來的數(shù)據(jù)
const {slides, autoplay=true, duration=3000} = defineProps<{
slides:banneritem[],
autoplay:boolean,
duration:number
}>()
// 當(dāng)前選擇的是那一張圖片。
let active = ref(0)
// 左側(cè)箭頭
const hleft = ()=>{
active.value--
if(active.value < 0){
active.value = slides.length-1
}
}
// 右側(cè)箭頭
const hright = ()=>{
active.value++
if(active.value > slides.length - 1){
active.value = 0
}
}
let timer = -1
// 鼠標(biāo)離開開啟自動(dòng)播放
const start = ()=>{
if(autoplay){
// 在ts中,使用定時(shí)器,注意:window.setInterval
timer =window.setInterval(()=>{
hright()
},duration)
}
}
// 鼠標(biāo)進(jìn)入停止自動(dòng)播放
const stop = ()=>{
clearInterval(timer)
}
// 點(diǎn)擊小圓點(diǎn)跳轉(zhuǎn)
const ind= (id:number)=>{
active.value = id
}
//在頁面加載時(shí) 自動(dòng)播放
onMounted(()=>{
start()
})
// 在頁面關(guān)閉時(shí),銷毀組件 停止播放
onBeforeMount(()=>{
stop()
})
</script>
<template>
<!-- fade類表示當(dāng)前圖片可見 -->
<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>
<!-- 小圓點(diǎn) -->
<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>以上就是vue3與ts組件封裝提高代碼復(fù)用性的詳細(xì)內(nèi)容,更多關(guān)于vue3與ts組件封裝的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Vue3+TypeScript實(shí)現(xiàn)遞歸菜單組件的完整實(shí)例
Vue.js中的遞歸組件是一個(gè)可以調(diào)用自己的組件,遞歸組件一般用于博客上顯示評論,形菜單或者嵌套菜單,文章主要給大家介紹了關(guān)于Vue3+TypeScript實(shí)現(xiàn)遞歸菜單組件的相關(guān)資料,需要的朋友可以參考下2021-08-08
vue打包的時(shí)候自動(dòng)將px轉(zhuǎn)成rem的操作方法
這篇文章主要介紹了vue打包的時(shí)候自動(dòng)將px轉(zhuǎn)成rem的操作方法,需要的朋友可以參考下2018-06-06
前端配合后端實(shí)現(xiàn)Vue路由權(quán)限的方法實(shí)例
一開始我還以為vue的路由只能用在工程化的項(xiàng)目里面,其實(shí)不然,下面這篇文章主要給大家介紹了關(guān)于前端配合后端實(shí)現(xiàn)Vue路由權(quán)限的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05
vue3中關(guān)于i18n字符串轉(zhuǎn)義問題
這篇文章主要介紹了vue3中關(guān)于i18n字符串轉(zhuǎn)義問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04
vue?實(shí)現(xiàn)動(dòng)態(tài)設(shè)置元素的高度
這篇文章主要介紹了在vue中實(shí)現(xiàn)動(dòng)態(tài)設(shè)置元素的高度,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08

