用戶
 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

掃一掃,登錄網站

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

德甲联赛奥格斯堡对汉诺威96:uni-app開發一個小視頻應用(一)

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

一、uni-app簡介uni-app 是一個使用 Vue.js開發所有前端應用的框架,是一種終極的跨平臺解決方案,這里的平臺,主要指的是App平臺(android、ios)、小程序平臺、H5平臺??⒄弒嘈匆惶狀?,可發布到iOS、Android、H ...

一、uni-app簡介

uni-app 是一個使用 Vue.js 開發所有前端應用的框架,是一種終極的跨平臺解決方案,這里的平臺,主要指的是App平臺(android、ios)、汉诺威96升级平臺、H5平臺??⒄弒嘈匆惶狀?,可發布到iOS、Android、H5、以及各種小程序(微信/支付寶/百度/頭條/QQ/釘釘)等多個平臺。
uni-app將常用的組件和api進行了跨平臺封裝,并且保持與微信小程序的組件和api一致,同時兼容以微信的方式去調用api,即在uni-app中除了可以使用全局的uni對象去調用微信小程序中同名的api還可以使用全局的wx對象去調用api。uni-app使用vue的語法以及微信小程序api,所以學習成本非常低。
<script>
    export default {
        onLoad() {
            uni.showLoading({
                title: '加載中-uni'
            });
            // 二者是等價的
            wx.showLoading({
                title: '加載中-uni'
            })
        }
    }
</script>

二、uni-app初始目錄及文件介紹

① pages.json : 該文件是用來對 uni-app 進行全局配置,決定頁面文件的路徑(pages)、窗口樣式(globalStyle)、原生的導航欄(globalStyle)、底部的原生tabbar(tabBar) 等。
它類似微信小程序中app.json的頁面管理部分。需要注意的是,微信小程序權限配置也是在app.json文件中,通過permission進行配置,而uni-app則將權限配置移到了manifest.json文件中。

② manifest.json: 該文件是應用的配置文件,主要用于指定應用的名稱、圖標、權限等。

③ App.vue : 該文件是應用的主組件,所有頁面都是在App.vue下進行切換的,是頁面入口文件,在這個文件里,你可以初始化一些通用的組件,調用一些應用生命周期函數,應用生命周期(onLaunch、onShow、onHide)僅可在App.vue中監聽,在其它頁面監聽無效,以及設置一些全局的樣式,即在App.vue中的<style></style>內置設置全局樣式。

④ main.js: 該文件是應用的入口文件,主要作用是初始化App.vue主組件并安裝需要的插件,如vuex,需要注意的是,uni-app中是不能使用vue-router插件的,因為路由須在pages.json中進行配置。

// main.js

import Vue from 'vue'
import App from './App'

Vue.config.productionTip = false

App.mpType = 'app'

const app = new Vue({ // ①官方寫法
    ...App
})
// const app = new Vue(App); // ②等價于上面的寫法

// const app = new Vue({ // ③可正常渲染出頁面,但onLaunch、onShow、onHide應用生命周期失效
//      render: h => h(App)
// });
app.$mount()
main.js中官方寫法是在創建Vue實例的時候傳入一個對象,并且對根組件App.vue進行解構后傳入,其寫法和直接傳入根組件是一樣的,但是如果通過寫法③雖然可以正常渲染出頁面,但是根組件上的應用生命周期函數將失效

⑤ pages文件夾: 主要用于存放應用中的頁面,應用中的頁面就是.vue組件。

⑥ static文件夾: 主要用于存放應用中的圖片等靜態資源。

⑦ uni.scss: 主要存放uni-app內置的常用樣式變量。

⑧ unpackage文件夾: 主要存放uni-app編譯運行后生成的打包相關輸出文件。

三、開始開發一個小視頻應用

① 初始化項目

打開HBuilderX IDE,新建一個名稱為mini-video的初始化uni-app項目,這里勾選uni-app即可創建,項目創建完成后,打開pages/index/index.vue,將<template>中的模板內容content部分清空,將uni-app初始項目中與應用無關的東西進行清空、修改即可。

② 創建底部導航欄組件

首先要弄清楚我們的uni-app已經提供了tabBar的配置,即提供了底部導航欄的,那為什么還需要自定義底部導航欄呢 ?因為uni-app提供的默認底部導航欄tabBar的背景顏色只支持十六進制,所以無法設置為透明。同時我們又需要將底部導航欄中的頁面設置為tabBar頁面,所以我們還是要進行tarBar的配置,而一配置tabBar,那么就會自動出現uni-app提供的默認導航欄,所以我們必須在應用啟動onLaunch的時候將默認tabBar進行隱藏,那么沒有了默認導航欄,我們怎么進行tabBar頁面的切換呢?我們可以通過<navigator>組件設置不同的跳轉方式,實現應用內各種頁面之間的跳轉。記住APP和微信小程序是不支持<a>標簽跳轉的。

底部導航欄有五個頁面: 首頁(index.vue)、關注(follow.vue)、加號(添加好友friend.vue)、消息(news.vue)、我(personal.vue)。所以需要在pages中模仿index新建出剩余的四個頁面,頁面新建完成后,需要配置到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的時候隱藏掉uni-app自帶的tabBar

<script>
    export default {
        setTimeout(() => {
            uni.hideTabBar(); // 隱藏tabBar
        }, 1000);
    }
</script>
在ios和安卓App平臺上運行時,會出現tabBar隱藏失敗的情況,解決辦法就是隱藏的時候需要添加一個1000ms左右的延遲

// 項目根目錄下新建一個components目錄,并在其中新建一個tab-bar.vue即自定義底部導航欄組件

<template>
    <view class="tab">
        <navigator open-type="switchTab" url="/pages/index/index" class="tab-box">
            首頁
        </navigator>
        <navigator open-type="switchTab" url="/pages/follow/follow" class="tab-box">
            關注
        </navigator>
        <view class="tab-box">
            + <!--暫時用加號代替,后面會替換成字體圖標-->
        </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>

③ 添加圖標字體

添加圖標字體非常簡單,就是登錄iconfont網站,然后創建一個圖標項目,然后搜索自己需要的圖標,比如加號、搜索、返回,將它們加入到項目中,然后點擊下載即可,下載完成后解壓,找到iconfont.css這個文件,這個就是我們要用到的圖標字體的css樣式,直接引入到項目中即可,為了方便使用,我們將圖標字體css文件作為一個全局樣式引入到App.vue組件中。使用的時候,我們只需要在需要添加圖標字體的標簽上,添加上"iconfont 具體的圖標樣式名"即可,如:

// App.vue

<style>
    /*每個頁面公共css */
    @import url("./static/iconfont.css");
</style>

// components/tab-bar.vue

<view class="tab-box">
    <view class="iconfont icon-jiahao icon-box" ><!--添加一個加號圖標字體樣式,注意是兩個樣式名哦-->
    </view>
</view>

④ 創建首頁頭部導航欄

首頁頭部導航欄,最左側是一個搜索圖標,中間是推薦和同城,右側無內容。同樣,我們的uni-app是有一個默認頭部導航欄的,所以我們首先要隱藏掉默認的頭部導航欄,要隱藏默認頭部導航欄,我們需要在pages.json文件中設置其navigationStyle屬性值為custom即自定義,如:
{
    "globalStyle": {
        "navigationStyle":"custom" // 設置頭部導航欄為自定義模式,頭部導航欄會自動消失
    }
}

// /components/index-header.vue

<template>
    <view class="index-header"><!--固定定位到首頁頂部-->
        <view class="iconfont icon-icon-- icon"></view> <!--絕對定位到左側-->
        <view class="middle"> <!--搜索圖標絕對定位后,middle將會上移動到頂部,在搜索圖標下面,里面內容居中顯示即可-->
            <view class="text">推薦</view>|
            <view class="text">同城</view><!--變成行內元素-->
        </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>

⑤ 創建視頻播放組件

視頻播放組件即一個全屏的頁面,然后里面嵌入一個<video>組件即可實現。這里需要特別說一下如何讓頁面全屏顯示,我們設置頁面全屏通?;崛瞇枰戀腦厴柚蒙?strong style="box-sizing: border-box;">width: 100%; height: 100%;可是當我們給視頻播放組件根元素標簽設置上width為100%,height為100%后,它并沒有全屏顯示,因為當樣式屬性值為百分數的時候,其是相對于父元素的,即是父元素寬高的100%,而此時視頻播放組件的父元素是html、body,它們并沒有設置寬高,所以我們需要在App.vue中設置一下全局樣式,將html和body的寬高設置為100%,此后其中的子元素設置百分數的時候才會其作用。

// 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>

⑥ 創建視頻列表組件

視頻列表組件,我們使用的是<swiper>組件,里面<swiper-item>部分則為上面的視頻播放組件。

// /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>

⑦ 向視頻列表組件傳入列表數據

視頻列表組件和視頻播放組件都已經完成后,就可以在首頁onLoad的時候獲取視頻數據,然后傳遞給視頻列表組件,視頻列表組件在遍歷傳遞過來的視頻列表將視頻地址傳入對應的視頻播放組件中即可,這里采用mock數據的方式提供視頻列表。

// pages/index/index.vue

<template>
    <view class="content">
        <index-header></index-header> <!--首頁頭部導航欄組件-->
        <video-list :list="list"></video-list> <!--視頻列表組件-->
        <tab-bar></tab-bar> <!--首頁底部導航欄組件-->
    </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: "//alimov2.a.yximgs.com/bs2/gdtPostRoll/postRoll-MTA3MDY0NDY3Mzk.mp4",
                        autho: "張三",
                        title: "仙娜美",
                        loveNumber: 10000,
                        commentNumber: 2000,
                        shareNumber: 30000
                    },
                    {
                        id: 1,
                        src: "//upmov.a.yximgs.com/upic/2019/02/13/22/BMjAxOTAyMTMyMjUxMTlfNDc4ODM2MzlfMTA3Mjc5ODU2MjhfMV8z_b_B1fbc185eaca8cc06efa2d4f713e13e8c.mp4",
                        autho: "李四",
                        title: "【搞笑】最強猜歌王",
                        loveNumber: 40000,
                        commentNumber: 5000,
                        shareNumber: 60000
                    },
                    {
                        id: 2,
                        src: "//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>
分享至 : QQ空間
收藏
原作者: JS_Even_JS 來自: segmentfault