前言
uni-app 是一個(gè)使用 Vue.js 開發(fā)所有前端應(yīng)用的框架武契,是一種終極的跨平臺(tái)解決方案,這里的平臺(tái)荡含,主要指的是App平臺(tái)(android咒唆、ios)、小程序平臺(tái)内颗、H5平臺(tái)钧排。開發(fā)者編寫一套代碼,可發(fā)布到iOS均澳、Android恨溜、H5符衔、以及各種小程序(微信/支付寶/百度/頭條/QQ/釘釘)等多個(gè)平臺(tái)。
開發(fā)一個(gè)小視頻應(yīng)用
一糟袁、初始化項(xiàng)目
打開HBuilderX IDE判族,新建一個(gè)名稱為mini-video的初始化uni-app項(xiàng)目,這里勾選uni-app即可創(chuàng)建项戴,項(xiàng)目創(chuàng)建完成后形帮,打開pages/index/index.vue,將<template>中的模板內(nèi)容content部分清空周叮,將uni-app初始項(xiàng)目中與應(yīng)用無(wú)關(guān)的東西進(jìn)行清空辩撑、修改即可。
二仿耽、創(chuàng)建底部導(dǎo)航欄組件
首先要弄清楚我們的uni-app已經(jīng)提供了tabBar的配置合冀,即提供了底部導(dǎo)航欄的,那為什么還需要自定義底部導(dǎo)航欄呢 项贺?因?yàn)閡ni-app提供的默認(rèn)底部導(dǎo)航欄tabBar的背景顏色只支持十六進(jìn)制君躺,所以無(wú)法設(shè)置為透明。同時(shí)我們又需要將底部導(dǎo)航欄中的頁(yè)面設(shè)置為tabBar頁(yè)面开缎,所以我們還是要進(jìn)行tarBar的配置棕叫,而一配置tabBar,那么就會(huì)自動(dòng)出現(xiàn)uni-app提供的默認(rèn)導(dǎo)航欄奕删,所以我們必須在應(yīng)用啟動(dòng)onLaunch的時(shí)候?qū)⒛J(rèn)tabBar進(jìn)行隱藏俺泣。
那么沒有了默認(rèn)導(dǎo)航欄,我們?cè)趺催M(jìn)行tabBar頁(yè)面的切換呢急侥?我們可以通過<navigator>組件設(shè)置不同的跳轉(zhuǎn)方式砌滞,實(shí)現(xiàn)應(yīng)用內(nèi)各種頁(yè)面之間的跳轉(zhuǎn)侮邀。記住APP和微信小程序是不支持<a>標(biāo)簽跳轉(zhuǎn)的坏怪。
底部導(dǎo)航欄有五個(gè)頁(yè)面: 首頁(yè)(index.vue)、關(guān)注(follow.vue)绊茧、加號(hào)(添加好友friend.vue)铝宵、消息(news.vue)、我(personal.vue)华畏。所以需要在pages中模仿index新建出剩余的四個(gè)頁(yè)面鹏秋,頁(yè)面新建完成后,需要配置到pages.json中的tarBar中亡笑,只需要配置list即可侣夷,如:
{
"tabBar": { // 在pages.json中添加上tabBar配置,如下
"list": [
{"pagePath":"pages/index/index"},
{"pagePath":"pages/follow/follow"},
{"pagePath":"pages/friend/friend"},
{"pagePath":"pages/news/news"},
{"pagePath":"pages/personal/personal"}
]
}
}
// App.vue中onLaunch的時(shí)候隱藏掉uni-app自帶的tabBar
在ios和安卓App平臺(tái)上運(yùn)行時(shí)仑乌,會(huì)出現(xiàn)tabBar隱藏失敗的情況百拓,解決辦法就是隱藏的時(shí)候需要添加一個(gè)1000ms左右的延遲琴锭。
// 項(xiàng)目根目錄下新建一個(gè)components目錄,并在其中新建一個(gè)tab-bar.vue即自定義底部導(dǎo)航欄組件
<template>
<view class="tab">
<navigator open-type="switchTab" url="/pages/index/index" class="tab-box">
首頁(yè)
</navigator>
<navigator open-type="switchTab" url="/pages/follow/follow" class="tab-box">
關(guān)注
</navigator>
<view class="tab-box">
+ <!--暫時(shí)用加號(hào)代替衙传,后面會(huì)替換成字體圖標(biāo)-->
</view>
<navigator open-type="switchTab" url="/pages/news/news" class="tab-box">
消息
</navigator>
<navigator open-type="switchTab" url="/pages/personal/personal" class="tab-box">
我
</navigator>
</view>
</template>
<style>
.tab{
height:50px;
width:100%;
position:fixed;
bottom: 0;
left: 0;
z-index: 20;
}
.tab-box{
float: left;
width: 20%;
color: #FFFFFF;
text-align: center;
height: 50px;
line-height: 50px;
font-size:20px
}
.icon-box{
width: 60%;
height: 30px;
background: #FFFFFF;
color: #000000;
margin: 10px 20%;
line-height:30px;
border-radius: 5px;
font-size: 15px;
}
</style>
三决帖、添加圖標(biāo)字體
添加圖標(biāo)字體非常簡(jiǎn)單,就是登錄iconfont網(wǎng)站蓖捶,然后創(chuàng)建一個(gè)圖標(biāo)項(xiàng)目地回,然后搜索自己需要的圖標(biāo),比如加號(hào)俊鱼、搜索刻像、返回,將它們加入到項(xiàng)目中并闲,然后點(diǎn)擊下載即可绎速,下載完成后解壓,找到iconfont.css這個(gè)文件焙蚓,這個(gè)就是我們要用到的圖標(biāo)字體的css樣式纹冤,直接引入到項(xiàng)目中即可,為了方便使用购公,我們將圖標(biāo)字體css文件作為一個(gè)全局樣式引入到App.vue組件中萌京。使用的時(shí)候,我們只需要在需要添加圖標(biāo)字體的標(biāo)簽上宏浩,添加上"iconfont 具體的圖標(biāo)樣式名"即可知残,如:
// App.vue
<style>
/*每個(gè)頁(yè)面公共css */
@import url("./static/iconfont.css");
</style>
// components/tab-bar.vue
<view class="tab-box">
<view class="iconfont icon-jiahao icon-box" ><!--添加一個(gè)加號(hào)圖標(biāo)字體樣式,注意是兩個(gè)樣式名哦-->
</view>
</view>
四比庄、創(chuàng)建首頁(yè)頭部導(dǎo)航欄
首頁(yè)頭部導(dǎo)航欄求妹,最左側(cè)是一個(gè)搜索圖標(biāo),中間是推薦和同城佳窑,右側(cè)無(wú)內(nèi)容制恍。同樣,我們的uni-app是有一個(gè)默認(rèn)頭部導(dǎo)航欄的神凑,所以我們首先要隱藏掉默認(rèn)的頭部導(dǎo)航欄净神,要隱藏默認(rèn)頭部導(dǎo)航欄,我們需要在pages.json文件中設(shè)置其navigationStyle屬性值為custom即自定義溉委,如:
{
"globalStyle": {
"navigationStyle":"custom" // 設(shè)置頭部導(dǎo)航欄為自定義模式鹃唯,頭部導(dǎo)航欄會(huì)自動(dòng)消失
}
}
// /components/index-header.vue
<template>
<view class="index-header"><!--固定定位到首頁(yè)頂部-->
<view class="iconfont icon-icon-- icon"></view> <!--絕對(duì)定位到左側(cè)-->
<view class="middle"> <!--搜索圖標(biāo)絕對(duì)定位后,middle將會(huì)上移動(dòng)到頂部瓣喊,在搜索圖標(biāo)下面坡慌,里面內(nèi)容居中顯示即可-->
<view class="text">推薦</view>|
<view class="text">同城</view><!--變成行內(nèi)元素-->
</view>
</view>
</template>
<style scoped>
.index-header {
height: 35px;
line-height: 35px;
width: 100%;
position: fixed;
top: 25px;
left: 0;
margin: 0 auto;
background: #000000;
z-index: 20;
}
.icon {
position: absolute;
left: 0;
top: 0;
color: white;
width: 20%;
text-align: center;
}
.middle {
text-align: center;
color: white;
}
.text {
display: inline;
margin: 0 10px;
}
</style>
五、創(chuàng)建視頻播放組件
視頻播放組件即一個(gè)全屏的頁(yè)面藻三,然后里面嵌入一個(gè)<video>組件即可實(shí)現(xiàn)洪橘。這里需要特別說一下如何讓頁(yè)面全屏顯示絮爷,我們?cè)O(shè)置頁(yè)面全屏通常會(huì)讓需要全屏的元素設(shè)置上width: 100%; height: 100%;可是當(dāng)我們給視頻播放組件根元素標(biāo)簽設(shè)置上width為100%,height為100%后梨树,它并沒有全屏顯示坑夯,因?yàn)楫?dāng)樣式屬性值為百分?jǐn)?shù)的時(shí)候,其是相對(duì)于父元素的抡四,即是父元素寬高的100%柜蜈,而此時(shí)視頻播放組件的父元素是html、body指巡,它們并沒有設(shè)置寬高淑履,所以我們需要在App.vue中設(shè)置一下全局樣式,將html和body的寬高設(shè)置為100%藻雪,此后其中的子元素設(shè)置百分?jǐn)?shù)的時(shí)候才會(huì)其作用秘噪。
// App.vue
html,body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
// /components/video-player.vue
<template>
<view class="video-player">
<video class="video"
:src= "video.src"
:controls="false"
:loop="true">
</video>
</view>
</template>
<script>
export default {
props: ["video"]
}
</script>
<style>
.video-player {
width: 100%;
height: 100%;
}
.video {
width: 100%;
height: 100%;
z-index: 19;
}
</style>
六、創(chuàng)建視頻列表組件
視頻列表組件勉耀,我們使用的是<swiper>組件指煎,里面部分則為上面的視頻播放組件。
// /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>
</swiper-item>
</swiper>
</view>
</view>
</template>
<script>
import VideoPlayer from "./video-player.vue";
export default {
components: {
"video-player": VideoPlayer
},
props:['list'],
data() {
return {
videos:[],
}
},
watch:{
list(){
this.videos=this.list;
}
}
}
</script>
<style scoped>
.video-list {
width: 100%;
height: 100%;
}
.swiper-box{
height:100%;
width: 100%;
}
.swiper{
height:100%;
width: 100%;
}
.swiper-item {
width: 100%;
height: 100%;
background: red;
}
</style>
七便斥、向視頻列表組件傳入列表數(shù)據(jù)
視頻列表組件和視頻播放組件都已經(jīng)完成后至壤,就可以在首頁(yè)onLoad的時(shí)候獲取視頻數(shù)據(jù),然后傳遞給視頻列表組件枢纠,視頻列表組件在遍歷傳遞過來的視頻列表將視頻地址傳入對(duì)應(yīng)的視頻播放組件中即可像街,這里采用mock數(shù)據(jù)的方式提供視頻列表。
// pages/index/index.vue
<template>
<view class="content">
<index-header></index-header> <!--首頁(yè)頭部導(dǎo)航欄組件-->
<video-list :list="list"></video-list> <!--視頻列表組件-->
<tab-bar></tab-bar> <!--首頁(yè)底部導(dǎo)航欄組件-->
</view>
</template>
<script>
import TabBar from "../../components/tab-bar.vue";
import IndexHeader from "../../components/index-header.vue";
import VideoList from "../../components/video-list.vue";
export default {
components: {
"tab-bar": TabBar,
"index-header": IndexHeader,
"video-list": VideoList
},
data() {
return {
list: []
}
},
onLoad() {
this.getVideos();
},
methods: {
getVideos() {
const res = [
{
id: 0,
src: "http://alimov2.a.yximgs.com/bs2/gdtPostRoll/postRoll-MTA3MDY0NDY3Mzk.mp4",
autho: "張三",
title: "仙娜美",
loveNumber: 10000,
commentNumber: 2000,
shareNumber: 30000
},
{
id: 1,
src: "http://upmov.a.yximgs.com/upic/2019/02/13/22/BMjAxOTAyMTMyMjUxMTlfNDc4ODM2MzlfMTA3Mjc5ODU2MjhfMV8z_b_B1fbc185eaca8cc06efa2d4f713e13e8c.mp4",
autho: "李四",
title: "【搞笑】最強(qiáng)猜歌王",
loveNumber: 40000,
commentNumber: 5000,
shareNumber: 60000
},
{
id: 2,
src: "http://bdmov.a.yximgs.com/bs2/gdtPostRoll/postRoll-MTA3MDk5Mjc5OTg.mp4",
autho: "王五",
title: "特制流淚芥末醬",
loveNumber: 70000,
commentNumber: 8000,
shareNumber: 90000
}
];
this.list = res;
}
}
}
</script>
<style>
.content {
width: 100%;
height: 100%;
}
</style>
原文作者:Rolan