下面我将详细讲解"vue3+Pinia+TypeScript 实现封装轮播图组件"的完整攻略:
1. 前置知识
在开始之前需要先掌握以下知识:
- Vue3基础语法
- TypeScript基础语法
- Pinia要点
2. 创建轮播图组件
- 创建组件文件
首先需要在项目中创建Carousel
组件的.vue
和.ts
文件,用于定义组件的模板和业务逻辑代码。
- 引入Pinia
在创建组件的.ts
文件中引入Pinia:
import { defineComponent } from 'vue'
import { useStore } from 'pinia'
- 定义Carousel组件
import { defineComponent } from 'vue'
import { useStore } from 'pinia'
export default defineComponent({
name: 'Carousel',
props: ['items'],
setup(props) {
const store = useStore()
// 内部业务逻辑代码
return {}
}
})
在setup
函数中,我们初始化了一个store
实例,后续我们将使用它来管理轮播图数据。其中,props
用于接收从父组件传递过来的props,这里我们接收了一个items
数组,表示轮播图的图片列表。
- 添加轮播图数据State
接着,在创建Carousel.store.ts
file文件中定义 Carousel
组件的状态,如下所示:
import { defineStore } from 'pinia'
interface CarouselState {
items: string[]
currentIndex: number
timer: null | number
}
export const useCarouselStore = defineStore({
id: 'carousel',
state: (): CarouselState => ({
items: [],
currentIndex: 0,
timer: null
})
})
在上面的代码中,我们使用了Pinia提供的defineStore
函数定义了一个名为useCarouselStore
的store实例,并定义了轮播图的状态,包括items
(图片列表)、currentIndex
(当前索引)和timer
(轮播定时器)。
我们在这里也可以定义mutations, actions等来修改state中的属性
- 定义轮播图组件逻辑
结合上面创建的Carousel
组件和useCarouselStore
store实例,来实现轮播图组件的业务逻辑,代码如下:
import { defineComponent } from 'vue'
import { useStore } from 'pinia'
import { useCarouselStore } from './Carousel.store'
export default defineComponent({
name: 'Carousel',
props: ['items'],
setup(props) {
const carouselStore = useCarouselStore()
const store = useStore()
// 初始化轮播图数据
carouselStore.items = props.items
carouselStore.timer = setInterval(() => {
carouselStore.currentIndex =
(carouselStore.currentIndex + 1) % carouselStore.items.length
}, 3000)
// 定义方法
const goTo = (index: number) => {
carouselStore.currentIndex = index
}
const prev = () => {
carouselStore.currentIndex =
(carouselStore.currentIndex - 1 + carouselStore.items.length) %
carouselStore.items.length
}
const next = () => {
carouselStore.currentIndex =
(carouselStore.currentIndex + 1) % carouselStore.items.length
}
return { carouselStore, goTo, prev, next }
}
})
在这里,在setup
里面,我们初始化了store和轮播图的数据。我们还定义了一些函数用于处理轮播图的点击事件,比如goTo
函数用于跳转到某个指定索引的图片、prev
函数用于向前翻页、next
函数用于向后翻页。
3. 应用轮播图组件到Vue页面
- 在Vue页面中引入
Carousel
组件。
<template>
<div>
<Carousel :items="items"></Carousel>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import Carousel from '@/components/Carousel.vue'
export default defineComponent({
name: 'App',
components: {
Carousel
},
data() {
return {
items: [
'https://picsum.photos/500/300',
'https://picsum.photos/500/301',
'https://picsum.photos/500/302',
'https://picsum.photos/500/303'
]
}
}
})
</script>
- 在Vue页面中绑定数据到
Carousel
组件。
<template>
<div>
<Carousel :items="items"></Carousel>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import Carousel from '@/components/Carousel.vue'
export default defineComponent({
name: 'App',
components: {
Carousel
},
data() {
return {
items: [
'https://picsum.photos/500/300',
'https://picsum.photos/500/301',
'https://picsum.photos/500/302',
'https://picsum.photos/500/303'
]
}
}
})
</script>
在这里,数据通过items
props传递到了Carousel
组件中,且开始展示轮播图。
4. 示例说明
示例一
在轮播图组件中自定义前进/后退按钮,点击按钮可分别前进/后退一张图片。
<template>
<div>
<ul>
<li v-for="(item, index) in items" :key="index">
<img
v-if="currentIndex === index"
:src="item"
alt=""
style="display:block;margin:0 auto;"
/>
</li>
</ul>
<button @click="prev">prev</button>
<button @click="next">next</button>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { useStore } from 'pinia'
import { useCarouselStore } from './Carousel.store'
export default defineComponent({
name: 'Carousel',
props: ['items'],
setup(props) {
const carouselStore = useCarouselStore()
const store = useStore()
// 初始化轮播图数据
carouselStore.items = props.items
carouselStore.timer = setInterval(() => {
carouselStore.currentIndex =
(carouselStore.currentIndex + 1) % carouselStore.items.length
}, 3000)
// 定义方法
const goTo = (index: number) => {
carouselStore.currentIndex = index
}
const prev = () => {
carouselStore.currentIndex =
(carouselStore.currentIndex - 1 + carouselStore.items.length) %
carouselStore.items.length
}
const next = () => {
carouselStore.currentIndex =
(carouselStore.currentIndex + 1) % carouselStore.items.length
}
return { carouselStore, goTo, prev, next }
}
})
</script>
示例二
对于轮播图组件,可以添加自动播放和暂停功能。
<template>
<div>
<ul>
<li v-for="(item, index) in items" :key="index">
<img
v-if="currentIndex === index"
:src="item"
alt=""
style="display:block;margin:0 auto;"
/>
</li>
</ul>
<button @click="prev">prev</button>
<button @click="next">next</button>
<button @click="stopTimer" v-if="isPlaying">pause</button>
<button @click="startTimer" v-else>play</button>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { useStore } from 'pinia'
import { useCarouselStore } from './Carousel.store'
export default defineComponent({
name: 'Carousel',
props: ['items'],
setup(props) {
const carouselStore = useCarouselStore()
const store = useStore()
// 初始化轮播图数据
carouselStore.items = props.items
carouselStore.timer = setInterval(() => {
carouselStore.currentIndex =
(carouselStore.currentIndex + 1) % carouselStore.items.length
}, 3000)
// 定义方法
const goTo = (index: number) => {
carouselStore.currentIndex = index
}
const prev = () => {
carouselStore.currentIndex =
(carouselStore.currentIndex - 1 + carouselStore.items.length) %
carouselStore.items.length
}
const next = () => {
carouselStore.currentIndex =
(carouselStore.currentIndex + 1) % carouselStore.items.length
}
const startTimer = () => {
carouselStore.timer = setInterval(() => {
carouselStore.currentIndex =
(carouselStore.currentIndex + 1) % carouselStore.items.length
}, 3000)
}
const stopTimer = () => {
clearInterval(carouselStore.timer)
carouselStore.timer = null
}
return { carouselStore, goTo, prev, next, startTimer, stopTimer, isPlaying }
},
computed: {
isPlaying() {
return this.carouselStore.timer !== null
}
}
})
</script>
在这里,我们添加了自动播放和暂停功能,当点击暂停按钮时,清除定时器,点击播放按钮时重新设置定时器,达到轮播效果。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vue3+Pinia+TypeScript 实现封装轮播图组件 - Python技术站