用戶
 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

掃一掃,登錄網站

小程序社區 首頁 教程 查看內容

拜仁vs汉诺威96:uni-app開發一個小視頻應用(二)

汉诺威96升级 www.wikuss.com.cn Rolan 2019-10-9 00:32

一、前情回顧uni-app開發一個小視頻應用(一)上篇文章,我們已經實現了首頁的頭部導航欄組件、底部的tabBar導航欄組件、中間的視頻列表組件以及視頻列表組件中的視頻播放組件,傳入視頻列表渲染后已經可以上下滑動進 ...

一、前情回顧

uni-app開發一個小視頻應用(一)

上篇文章,我們已經實現了首頁的頭部導航欄組件、底部的tabBar導航欄組件、中間的視頻列表組件以及視頻列表組件中的視頻播放組件,傳入視頻列表渲染后已經可以上下滑動進行視頻切換和播放,接下來我們將完成首頁的剩余部分,左側信息欄組件、右側圖標欄組件,以及完善視頻切換動畫、播放控制等功能。

二、創建左側信息欄組件

左側的信息欄組件,主要分三塊: 作者名、視頻標題名、音樂名。這個左側信息欄信息是和當前播放視頻相關聯的,所以應該在循環視頻列表的時候,將左側信息欄組件一起渲染出來,所以左側信息欄組件應該加到<swiper-item>中。

// components/list-left.vue

<template>
    <view class="list-left">
        <view class="author">
            @祝曉晗
        </view>
        <view class="title">
            媽呀,遇到老同學了,緣分吶! @老丈人說車 @抖音小助手
        </view>
        <view class="music-box"> <!--該music-box主要是為了在music內容滾動的時候在超出music-box范圍后能夠隱藏超出部分-->
            <view class="music">
                @祝曉晗創作的原聲 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  @祝曉晗創作的原聲
            </view>
        </view>
    </view>
</template>
<style scoped>
    .list-left{
        width: 70%;
        height: 120px;
        color: white;
    }
    .author {
        height: 35px;
        line-height: 35px;
        font-size: 17px;
    }
    .title {
        width: 100%;
        line-height: 25px;
        font-size: 12px;
        word-wrap: break-word;
        color: #FFFAF0;
    }
    .music-box {
        overflow: hidden; <!--滾動的時候超出部分隱藏-->
        width: 70%;
    }
    .music {
        width: 200%;
        height: 35px;
        line-height: 35px;
        font-size: 12px;
        animation: scroll-x 5s linear 0.2s infinite; <!--應用動畫-->
    }
    @keyframes scroll-x{ <!--添加文字水平滾動動畫-->
        0% {
            transform: translate3d(80%, 0, 0); <!--80%位置出現,然后向左邊滾動-->
        }
        100% {
            transform: translate3d(-80%, 0, 0); <!--動畫結束后到達-80%位置-->
        }
    }
</style>

// components/video-list.vue

<template>
    <view class="video-list">
        <view class="swiper-box">
            <swiper class="swiper" :vertical="true">
                <swiper-item v-for="(item,index) in videos" :key="index">
                    <view class="swiper-item">
                        <video-player                         
                             :video="item"                        
                            :index="index">
                        </video-player>
                    </view>
                    <view class="left-box"> <!--將左側信息欄組件放到<swiper-item>中同視頻一起渲染出來-->
                        <list-left></list-left>
                    </view>
                </swiper-item>
            </swiper>
        </view>
    </view>
</template>

<style>
.left-box { <!--給左側列表組件添加絕對定位 并設置z-index以顯示到視頻上方-->
        position: absolute;
        bottom: 50px;
        left: 10px;
        z-index: 20; 
}
</style>

三、創建右側圖標欄組件

右側圖標欄組件,主要分為: 頭像圖標(頭像設置border-radius)、收藏圖標(iconfont圖標)、評論圖標(iconfont圖標)、分享圖標(iconfont圖標)、音樂圖標(圖片設置border-radius),右側圖標欄組件設置一個固定寬度,然后讓各種圖標依次排列即可,如:

// components/list-right.vue

<template>
    <view class="list-right">
        <view class="author-img">
            <img class="img" src="../static/zxh.jpg"/>
        </view>
        <view class="right-box">
            <view class="icon iconfont icon-xin"></view>
            <view class="count">72.2w</view>
        </view>
        <view class="right-box">
            <view class="icon iconfont icon-pinglun1"></view>
            <view class="count">1.8w</view>
        </view>
        <view class="right-box">
            <view class="icon iconfont icon-arrow-"></view>
            <view class="count">6645</view>
        </view>
        <view class="music-img">
            <img class="img" src="../static/music.jpg"/>
        </view>
    </view>
</template>

<style scoped>
    .list-right {
        width: 60px;
    }
    .author-img {
        width: 60px;
        text-align: center;
    }
    .img {
        width: 50px;
        height: 50px;
        border-radius: 50%;
    }
    .author-img img{
        border: 2px solid #FFFFFF;
    }
    .right-box {
        margin: 20px auto;
        color: white;
        text-align: center;
        font-size: 12px;
    }
    .icon {
        font-size: 40px;
    }
    .music-img {
        width: 60px;
        height: 51px;
        text-align: center;
        margin-top: 20px;
        animation: around 1.5s linear 0.2s infinite; <!--使用動畫-->
    }
    @keyframes around { <!--添加360環繞旋轉動畫-->
        0% {
            transform: rotate(0deg);
        }
        100% {
            transform: rotate(360deg);
        }
    }
</style>

四、給右側圖標組件添加上相應的事件

當點擊頭像下部的加號圖標,可以對該用戶進行關注,即隱藏加號圖標,還有就是收藏愛心圖標顏色切換,當點擊收藏愛心圖標,愛心圖標變成紅色,再次點擊收藏愛心圖標,愛心圖標變回白色,這里先只處理顏色的變化,具體后臺交互暫不處理。

// 在頭像圖標下方通過絕對定位添加一個加號圖標,并定位到頭像底部

<view class="author-img">
    <img class="img" src="../static/zxh.jpg"/>
    <view class="follow iconfont icon-jiahao" v-show="showFollow" @click="hideFollow"><!--添加一個加號圖標,以及監聽hideFollow事件-->
    </view>
</view>

<view class="right-box">
    <view class="icon iconfont icon-xin" :class="{fav: isFav}" @click="changeColor"></view><!--監聽切換收藏愛心圖標顏色-->
    <view class="count">72.2w</view>
</view>

<script>
    export default {
        data() {
            return {
                showFollow: true,
                isFav: false
            }
        },
        methods: {
            hideFollow() { // 隱藏關注加號圖標
                this.showFollow = false;
            },
            changeColor() {
                this.isFav = !this.isFav; // 切換收藏愛心顏色
            }
        }
    }
</script>
<style scoped>
.follow {
        color: white;
        position: absolute;
        width: 18px;
        height: 18px;
        line-height: 18px;
        background: red;
        border-radius: 50%;
        text-align: center;
        left: 23px;
        bottom: -5px;
        font-weight: bold;
}
.fav {
        color:red;
}
</style>

五、實現滑動播放功能

所謂滑動播放,即向上滑動的時候,暫停當前播放視頻并且播放下一個視頻,向下滑動的時候,暫停當前播放視頻,播放上一個視頻,而這最關鍵的就是如何判斷是向上滑動還是向下滑動。<swiper>組件給我們提供了一個change事件,我們可以監聽這個change事件,拿到滑動完成后滑動到了第幾頁,即<swiper-item>的序號(從0開始),然后與滑動前的當前page相比較,就可以知道是向上滑還是向下滑了。
判斷好了是上滑還是下滑后,我們還需要對上滑和下滑作出正確的處理,我們需要能夠拿到每個視頻播放組件,然后調用視頻播放組件上的相關方法對播放進行控制,這就是涉及到了父組件如何調用子組件上方法,父組件要想調用子組件上的方法,關鍵是父組件要能夠拿到子組件對象,我們可以通過ref實現,因為每一個視頻播放組件是video-list視頻列表組件的一個子組件,所以我們可以在video-list視頻列表組件中給每一個video-player視頻播放組件添加上一個ref="player",即可拿到對應的視頻播放組件了。

// components/video-list.vue

<swiper class="swiper" :vertical="true" @change="slider"> <!--監聽change事件-->
    <swiper-item v-for="(item,index) in videos" :key="index">
        <view class="swiper-item">
            <video-player
                ref="players" <!--給每一個視頻播放組件添加一個ref標識-->
                :video="item"                        
                :index="index">
            </video-player>
        </view>
    </swiper>
</swiper>
<script>
export default {
    data() {
        return {
            currentPage: 0 // 保存當前page的編號
        }
    },
    methods: {
        slider(e) {
            const targetPage = e.detail.current;
            if (targetPage === this.currentPage + 1) {
                console.log("向上滑動");
                this.$refs.players[this.currentPage + 1].playFromHead(); // 下一個開始播放并且從頭開始播放
                this.$refs.players[this.currentPage].pause(); // 當前視頻暫停播放
            } else if(targetPage === this.currentPage - 1) {
                console.log("向下滑動");
                this.$refs.players[this.currentPage - 1].playFromHead(); // 上一個開始播放并且從頭開始播放
                this.$refs.players[this.currentPage].pause(); // 當前視頻暫停播放
            }
                this.currentPage = targetPage;
        }
    }
}
</script>
需要注意的是,this.$refs.players返回的是一個數組,即所有播放組件的實例,我們通過不同的索引即可取得對應的視頻播放組件,然后進行相應的播放控制了,接下來就是要給每一個視頻播放組件添加上播放控制的方法,我們需要給<video>組件添加上一個id,然后通過這個id可以創建出video上下文,即可調用play()、pause()、seek()等相關方法對播放進行控制。

// components/video-player.vue

<template>
    <view class="video-player">
        <video class="video"
               id="myVideo" <!--給video組件添加一個id,以便獲取到video上下文對象-->
               :src= "video.src" 
               :controls="false"
               :loop="true">
        </video>
    </view>
</template>
<script>
export default {
    onReady() {
            this.videoContext = uni.createVideoContext("myVideo", this); // 獲取video上下文對象
    },
    methods: {
        play() {
            this.videoContext.play();
        },
        pause() {
            this.videoContext.pause();
        },
        playFromHead() { // 跳轉到開始位置并播放
            this.videoContext.seek(0);
            this.play();
        }
    }
}
</script>

六、實現單擊播放暫停切換以及雙擊關注用戶功能

要想實現單擊視頻播放組件,視頻可以進行播放和暫停切換,那么我們需要給視頻播放組件添加一個isPlay屬性表示視頻是否處于播放中,如果是播放中,那么點擊就暫停,如果不是播放中,那么點擊就播放,同時,由于uni-app不支持vue的dblclick事件的,所以我們還需要對單擊和雙擊操作進行判斷,我們需要定義一個變量用于記錄用戶點擊次數,如果300ms內用戶點擊次數大于等于2,那么就是雙擊,否則就是單擊,如:
<template>
    <view class="video-player">
        <video class="video"
               id="myVideo"
               :src= "video.src" 
               :controls="false"
               :loop="true"
               @click="doClick"><!--添加click事件進行視頻播放和暫停的切換-->
        </video>
    </view>
</template>
<script>
    let timer = null; // 定義一個定時器
    export default {
        data() {
            return {
                isPlay: false, // 當前視頻是否在播放中,默認為false
                clickCount: 0 // 記錄當前用戶點擊次數,默認為0
            }
        },
        methods: {
            play() {
                this.videoContext.play();
                this.isPlay = true; // 進入視頻播放狀態設置isPlay為true
            },
            pause() {
                this.videoContext.pause();
                this.isPlay = false; // 進入視頻暫停狀態設置isPlay為false
            },
            playFromHead() {
                this.videoContext.seek(0);
                this.play();
            },
            doClick() { // 進行視頻播放和暫停的切換
                if (timer) {
                    clearTimeout(timer);
                }
                this.clickCount++; // 每次單擊視頻播放組件,點擊次數加1
                timer = setTimeout(() => {
                    if (this.clickCount >=2 ) { // 如果300ms內點擊次數大于等于2就表示是雙擊了
                        console.log("雙擊");
                        this.$emit("follow"); // 雙擊的話向video-list父組件(視頻列表組件)發送一個follow事件
                    } else {
                        console.log("單擊");
                        if (this.isPlay) {
                            this.pause();
                        } else {
                            this.play();
                        }
                    }
                    this.clickCount = 0; // 重置點擊次數為0
                }, 300);
            }
        }
    }
</script>
雙擊的時候會向video-list父組件(視頻列表組件)發送一個follow事件,video-list組件監聽到follow事件后再通知<list-right>組件調用其方法讓其愛心圖標變紅即可,如:
<template>
    <video-player
        @follow="follow">
    </video-player>
    <view class="right-box">
        <list-right ref="listRight"></list-right> <!--給list-right組件添加ref標識-->
    </view>
</template>
<script>
    export default {
        follow() {
            this.$refs.listRight[0].follow();
        }
    }
</script>

七、實現首個視頻自動播放功能

之前我們的視頻播放組件接收了一個index屬性,即當前視頻對應的索引號,我們可以通過這個索引號判斷當前視頻是否是第一個,然后將其video組件的autoPlay設置為true即可自動播放。
<template>
    <view class="video-player">
        <vide :autoplay="auto> <!--綁定autoplay屬性控制是否自動播放-->
        </video>
    </view>
</template>
<script>
    export default {
        data() {
            return {
                auto: false // 是否自動播放
            }
        },
        methods: {
            autoPlay() {
                if (this.index === 0) {
                    this.auto = true;
                }
            }
        },
        created() {
            this.autoPlay();
        }
    }
</script>
至此,首頁已經完成,效果圖如下:

分享至 : QQ空間
收藏
原作者: JS_Even_JS 來自: segmentfault