上篇文章,咱們已經實現了首頁的頭部導航欄組件、底部的tabBar導航欄組件、中間的視頻列表組件以及視頻列表組件中的視頻播放組件,傳入視頻列表渲染後已經能夠上下滑動進行視頻切換和播放,接下來咱們將完成首頁的剩餘部分, 左側信息欄組件、 右側圖標欄組件,以及 完善視頻切換動畫、 播放控制等功能。
左側的信息欄組件,主要分三塊: 做者名、 視頻標題名、 音樂名。這個左側信息欄信息是和當前播放視頻相關聯的,因此應該在循環視頻列表的時候,將左側信息欄組件一塊兒渲染出來,因此 左側信息欄組件應該加到<swiper-item>中。
// components/list-left.vuesegmentfault
<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"> @祝曉晗創做的原聲 @祝曉晗創做的原聲 </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.vueapp
<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.vueide
<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>
當點擊頭像下部的加號圖標,能夠對該用戶進行關注,即 隱藏加號圖標,還有就是 收藏愛心圖標顏色切換,當點擊收藏愛心圖標,愛心圖標變成紅色,再次點擊收藏愛心圖標,愛心圖標變回白色,這裏先只處理顏色的變化,具體後臺交互暫不處理。
// 在頭像圖標下方經過絕對定位添加一個加號圖標,並定位到頭像底部oop
<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.vuethis
<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>
至此,首頁已經完成,效果圖以下: