hldy_app/component/public/donghua.vue

121 lines
2.3 KiB
Vue

<template>
<view>
<image :src="isError ? defaultImage : links[currentIndex]" :style="{ width: width, height: height }"
:mode="objectFit" @error="isError = true" @load="isError = false" />
<button v-if="showButton" @click="$emit('update:playing', !playing)">
{{ playing ? '停止播放' : '开始播放' }}
</button>
</view>
</template>
<script setup>
import {
ref,
watch,
onUnmounted
} from 'vue'
// 定义组件的 props
const props = defineProps({
links: {
type: Array,
default: () => []
},
width: {
type: String,
default: '65rpx'
},
height: {
type: String,
default: '65rpx'
},
objectFit: {
type: String,
default: 'aspectFill'
},
defaultImage: {
type: String,
default: ''
},
interval: {
type: Number,
default: 80
},
playing: {
type: Boolean,
default: false
},
showButton: {
type: Boolean,
default: false
},
loop: {
type: Boolean,
default: false
}
})
// 定义组件发出的事件
const emit = defineEmits(['update:playing'])
// 组件内部状态
const currentIndex = ref(0) // 当前播放的图片索引
const isPlaying = ref(false) // 是否正在播放
const isError = ref(false) // 当前图片是否加载失败
let timer = null // 定时器
// 开始播放
const startPlay = () => {
if (isPlaying.value) return
isPlaying.value = true
timer = setInterval(() => {
if (props.loop) {
// 循环播放:使用模运算循环索引
currentIndex.value = (currentIndex.value + 1) % props.links.length
isError.value = false
} else {
// 非循环播放:到末尾时停止
if (currentIndex.value < props.links.length - 1) {
currentIndex.value++
isError.value = false
} else {
stopPlay()
}
}
}, props.interval)
}
// 停止播放
const stopPlay = () => {
isPlaying.value = false
clearInterval(timer)
}
// 监听 playing 属性变化
watch(() => props.playing, (val) => {
currentIndex.value = 0
if (val) {
startPlay()
} else {
stopPlay()
setTimeout(() => currentIndex.value = 0, 50)
}
})
// 监听 links 数组变化
watch(() => props.links, () => {
currentIndex.value = 0
isError.value = false
if (isPlaying.value) {
stopPlay()
}
}, {
deep: true
})
// 组件销毁时清理定时器
onUnmounted(() => {
stopPlay()
})
</script>