需求:

轮播图加载了视频后自动播放视频,视频播放完成后,切换到下张图。

现有的swiper在嵌了video之后出现了各种各样的问题,比如切换下一张/切换回视频显示不全。

所以打算自己另外写一个轮播组件,不使用任何swiper组件。

中心思想就是直接硬切,轮播区域有且仅有一个元素,也就不存在video层级高遮挡的问题。

另外加上了uView的Transition组件,使得切换的时候没有那么生硬。

至于轮播指示器,可以考虑使用cover-view,然后简单布局就完成了

布局部分:

<template>
    <view style="height: 700rpx;">
        <view style="height: 700rpx;">
            <block v-for="(item, imgUrlsIndex) in imgUrls" 
            :key="imgUrlsIndex">
                <u-transition :show="!checkIsVideo(item) && imgUrlsIndex === currents" mode="fade-left"
                    class="slide-image" duration="500">
                    <image :src="item" />
                </u-transition>
                <u-transition :show="checkIsVideo(item) && imgUrlsIndex === currents" mode="fade-left"
                    class="slide-image" duration="500">
                    <video :show-fullscreen-btn="false" :src="item" :id="`myVideo${imgUrlsIndex}`" @ended="playEnded"
                        :initial-time="0" controls style="width: 100%;height: 100%;" />
                </u-transition>
            </block>
        </view>
    </view>
</template>

js部分:

<script>
    import {
        DEVICE_API_URL
    } from "@/config";
    export default {
        name: "ProductConSwiper",
        props: {
            imgUrls: {
                type: Array,
                default: () => [] //就是个资源url数组
            }
        },
        data() {
            let that = this;
            return {
                currents: 0,
                currentVideo: null,
                videoIndex: [],
                speed: 5000
                
            };
        },
        methods: {
            //判断视频
            checkIsVideo(url) {
                if (url.indexOf('.') != -1) {
                    var ext = url.substring(url.lastIndexOf('.') + 1);
                    return ['mp4', 'webm', 'mpeg4', 'ogg'].indexOf(ext) != -1
                }
            },
            // 视频播放完毕切换下一个
            playEnded() {
                this.currents += 1
                this.stopVideo()
            },
            // 播放视频
            playVideo(index = 0) {
                this.$nextTick(() => {
                    const id = `myVideo${index}`
                    this.currentVideo = uni.createVideoContext(id, this)
                    this.currentVideo.play()
                })
            },
            // 停止播放视频
            stopVideo(index = 0) {
                this.$nextTick(() => {
                    const id = `myVideo${index}`
                    this.currentVideo = uni.createVideoContext(id, this)
                    this.currentVideo.stop()
                })
            },
        },
        mounted() {
            this.imgUrls.forEach((url, index) => {
                if (this.checkIsVideo(url)) this.videoIndex.push(index)
            })
            if (!this.checkIsVideo(this.imgUrls[0])) setTimeout(() => this.currents = 1, this.speed)
            else if (this.checkIsVideo(this.imgUrls[0])) this.playVideo()
        },
        watch: {
            currents(current) {
                if (this.videoIndex.indexOf(current) > -1) this.playVideo(current)                     
                else {
                    if (this.checkIsVideo(this.imgUrls[current - 1])) this.currentVideo.stop();
                    let next = current + 1
                    if (current === this.imgUrls.length - 1) next = 0
                    setTimeout(() => this.currents = next, this.speed)
                }
            }
        }
    };
</script>

至于css部分就按各自实际场景搭建吧

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐