bili-video
仿bilibili視頻網站項目,非官方網站,本項目僅供學習和參考!!
一、前言
由於疫情原因,在家待了很長時間,所以在這段時間裏對前端的知識進行了鞏固及學習,然而在學了一段時間以後,有一種掌握了一些技術但卻無處可施的感覺,於是腦海中就浮現了做一個項目的念頭。有了這個念頭之後,就開始想做什麼呢?在一次逛B站的時候,對不起,我對它動手了(仿嗶哩嗶哩視頻webapp)
從一開始對這個項目進行業務分析後,讓我有着堅定的決心要長期維護這個項目,這個項目無論是從數據接口,還是運用技術上,我都煞費心血的肝,中途遇到困難真的有想放棄的念頭,因爲這個項目的數據接口一開始就是一個難題,由於網上目前還沒有規範的相關數據接口文檔,但是最後還是克服了,等項目基本完善後會整理出在這個項目中使用的數據接口供大家參考。本人前端大白菜一棵,大佬們輕噴,嘻嘻嘻。
進入GitHub項目倉庫(歡迎star和提pr)
進入項目上線預覽(建議使用chrome打開)
[注]本項目目前階段還比較粗糙,後續會進行改進和優化哦!
項目功能模塊
首頁
- switcher組件
- 輪播圖組件
- scroll組件(better-scroll二次封裝)
- 視頻推薦列表
- loading組件
- confirm組件
視頻播放頁
- 視頻播放器
- 視頻簡介
- 視頻推薦
- 視頻評論
搜索頁
- 熱門搜索標籤
- 歷史搜索記錄
- 防抖搜索關鍵詞及高亮顯示
- 搜索結果列表
視頻分區
- 分區分類視頻列表
視頻分區排行榜
- 分區視頻排行榜列表
真實數據來源
- 通過自己研究獲取的部分視頻數據
- 由GitHub上的SocialSisterYi提供的部分視頻數據(感謝給我節省了大量工作量)
本項目中所用的的數據接口:項目數據接口
注:本項目所有使用到的api全部放在src/api文件夾中
二、項目介紹
項目整體架構
這是項目大體目前期望的整體架構,可能在後續開發中還會變化。。。
目錄結構
這裏只了介紹src文件夾中的內容
├─api //數據請求接口、相關函數和基礎配置
├─base //基礎UI組件
├─common //通用樣式、工具類函數和icon圖標
├─components //核心功能組件
├─router //路由配置文件
└─store //vuex狀態管理文件
App.vue //根組件
main.js //入口文件
技術棧
vue2.5
:一套用於構建用戶界面的漸進式框架vue-router
: Vue.js 官方的路由管理器vue-lazyload
:在應用程序中懶散加載圖像的Vue模塊vue-awesome-swiper
:基於swiper封裝的vue滑動特效插件fastclick
:消除物理點擊和在移動瀏覽器上觸發點擊事件之間300毫秒的延遲better-scroll
:解決移動端各種滾動場景需求的插件axios
:請求後端api數據vuex
:專爲 Vue.js 應用程序開發的狀態管理模式
項目問題
- 目前的項目性能較差,優化空間非常多,所以項目開發完成後會對性能進行優化
- 搜索框的內容中不可帶有空格如果帶有空格,會導致搜索出的結果出現代碼無法編譯的問題
- 搜索框需要清空文本框後輸入纔可顯示搜索提示詞
- 播放器的播放功能在Safari瀏覽器不兼容,導致無法播放
- 項目中的video-list模塊設計思路錯誤
(以上問題是本菜雞發現但還未解決的問題,後期會進行處理)
三、功能介紹
首頁部分
視頻播放頁
搜索頁
視頻排行榜
視頻分區頁
五、部分功能代碼展示
搜索框防抖核心代碼
// 防抖
export function debounce (func, delay) {
let timer
return function (...args) {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
func.apply(this, args)
}, delay)
}
}
高亮搜索詞核心代碼
// 高亮關鍵詞
export function setHighlight (keyword, item, className) {
let s = new Set()
for (let k of keyword) {
s.add(k)
}
s.forEach(function (value) {
item = item.replace(value, function () {
return `<em class="${className}">${value}</em>`
})
})
return item
}
switcher組件實現標籤切換效果
功能:該組件提供兩種狀態,爲提供絲滑的交互動畫,該組件靈活度高,底部移動條會自動根據元素寬度變化。只需要傳入需要顯示的列表數組。當發生點擊時會響應當前位置的下標給調用組件。
- 當組件需要使用在滾動導航欄上時,該組件樣式切換爲靠右排布,如下:
- 當組件需要使用於不需要滾動的切換tab上時,該組件樣式切換爲居中排布,如下:
<template>
<div class="switcher" ref="switcher" :class="switcherType">
<div class="switcher-tab" v-for="(item, index) in list" :key="index" :class="{active : index === indexTab}" @click="switchTab(index)">
<span>{{item}}</span>
</div>
<div ref="anchor" class="switcher-header-anchor"></div>
</div>
</template>
<script type="text/ecmascript-6">
export default {
props: {
list: {
type: Array,
default: () => []
},
indexTab: {
type: Number,
default: 0
},
displayType: {
type: String, // start居左,around居中
default: 'start'
}
},
computed: {
switcherType () {
return this.displayType === 'start' ? 'switcher-start' : 'switcher-around'
}
},
created () {
setTimeout(() => {
this.moveAnchor(this.indexTab)
}, 20)
},
methods: {
switchTab (index) {
if (this.indexTab !== index) {
this.$emit('switchTab', index)
this.moveAnchor(index)
}
},
moveAnchor (index) {
let tab = this.$refs.switcher.childNodes[index]
this.$refs.anchor.style['transform'] = `translateX(${tab.offsetLeft + 16}px)`
this.$refs.anchor.style.width = tab.offsetWidth - 32 + 'px'
}
},
watch: {
indexTab (newIndex) {
if (newIndex) {
this.moveAnchor(newIndex)
}
}
}
}
</script>
<style lang="stylus" scoped rel="stylesheet/stylus">
@import '~common/stylus/variable.styl';
.switcher {
position: relative;
display: flex;
flex-direction: row;
font-size: $font-size-medium;
&.switcher-around {
justify-content: space-evenly;
}
&.switcher-start {
text-align: left;
}
.switcher-tab {
display: inline-block;
text-align: center;
vertical-align: middle;
height: 40px;
line-height: 40px;
white-space: nowrap;
padding: 0 16px;
color: #505050;
&.active {
color: $color-theme;
}
}
.switcher-header-anchor {
display: block;
position: absolute;
left: 0;
bottom: 0;
height: 2px;
border-radius: 2px;
background: $color-theme;
transition: 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
}
}
</style>
四、未來期望
目前這個項目還有很多功能還未實現,所以在之後的時間裏儘快將剩餘功能實現,呈現出一個完善的webapp項目出來,同時我也非常樂意大家的star以及提pr的嘻嘻嘻,這個項目還在努力開發中。。。。