您好,登錄后才能下訂單哦!
前言
想必大家都看過斗魚直播吧?這次在下使用從github上面摸下來(lái)的API,為大家重現(xiàn)一下斗魚網(wǎng)站的搭建,使用vue-cli-webpack來(lái)實(shí)現(xiàn)。
聲明
本文章所用API均從網(wǎng)絡(luò)獲取,本文作者不承擔(dān)任何法律責(zé)任,請(qǐng)閱讀本文的小伙伴們用于學(xué)習(xí)用途,不能用于商業(yè)!
如有侵權(quán)行為,請(qǐng)與作者聯(lián)系,作者將于2日內(nèi)刪除。
效果
pc端
移動(dòng)端
開始
好,扯了這么久的淡,該開始構(gòu)建項(xiàng)目了
項(xiàng)目初始化
初始化文件夾
打開一個(gè)新文件夾,在命令行輸入:
vue init webpack
如果顯示vue not found,那么該去下載vue-cli,如果webpack未找到就去下載webpack
到這一步以后就ctrl + c ,退出終端
安裝依賴
退出命令行之后,輸入以下指令:
npm install chromedriver --chromedriver_cdnurl=http://cdn.npm.taobao.org/dist/chromedriver
chromedriver 是安裝必備的包,鏡像好像有問題,我們提前裝一下。
npm install
GFW不是吹的,外網(wǎng)真的很慢,大家泡杯茶慢慢等
趁著等的時(shí)候,我們來(lái)下載幾個(gè)樣式和圖片,運(yùn)行
git clone https://github.com/YexChen/douyu_assets.git
來(lái)下載assets文件,覆蓋 assets文件夾到 項(xiàng)目文件/src 中
npm i -S lib-flexible npm i -S axios npm i -S vue-axios
我們還需要lib-flexible來(lái)解決移動(dòng)端適配的問題,axios和vue-axios來(lái)方便請(qǐng)求我們的數(shù)據(jù)
引入安裝的包
大家可以進(jìn)入到src目錄下,這里簡(jiǎn)要介紹下各個(gè)文件的功能
assets 放靜態(tài)內(nèi)容的地方,但是支持預(yù)編譯 components 放組件的地方,當(dāng)然也可以別具一格隨便創(chuàng)個(gè)文件夾代替之 router/index.js router文件夾是放路由的地方,index.js是我們的根路由 app.vue vue-cli幫我們生成好的一個(gè)組件(根組件),沒什么好稀奇的 main.js webpack的入口文件,聚合vue應(yīng)用里面的東西
我們來(lái)修改main.js,參照下圖:
紅線區(qū)域我們引入了移動(dòng)適配的lib-flexible,和font-awesome,style公共樣式
接下來(lái),我們來(lái)引入axios和vue-axios,請(qǐng)看下圖:
這里我們引入了vue-axios和axios,并通過vue.use來(lái)進(jìn)行綁定
跑起項(xiàng)目
準(zhǔn)備工作已經(jīng)做完了,接下來(lái)可以跑起項(xiàng)目了:
npm run dev
根據(jù)命令行的提示打開網(wǎng)頁(yè)即可看到效果:
好的,我們的項(xiàng)目初始化就到這里了。
配置映射和測(cè)試斗魚API
配置映射
來(lái)到根目錄下的 config/index.js 這里是配置開發(fā),構(gòu)建,及路由映射的地方
如圖修改proxyTable中內(nèi)容,這里解釋一下幾個(gè)參數(shù):
target : 目標(biāo)地址,
changeOrigin : 是否跨域,
pathRewrite : 鍵值對(duì)中用值替換鍵的值,其中^是正則中表示開始的符號(hào)
隨手請(qǐng)求一個(gè)API
進(jìn)入src/App.vue,如下修改文件:
created是我們的生命鉤子函數(shù),vue實(shí)例在created階段會(huì)執(zhí)行里面的代碼。
this.$http相當(dāng)于this.axios,$http的具體實(shí)現(xiàn)可以去node_modules里面看,很簡(jiǎn)單的
重啟webpack服務(wù),看下效果
ctrl+c
npm run dev
看到以上效果的話,證明數(shù)據(jù)請(qǐng)求成功了。
搭建首頁(yè)應(yīng)用
思維導(dǎo)圖解析
我們要寫的應(yīng)用較為復(fù)雜,寫vue的項(xiàng)目就是這樣,需要清晰的思想,不然很容易崩潰,最后重來(lái)
好,接下來(lái)為大家講解一下我們的組件:
Root是根組件,一切的源(廢話)
App,應(yīng)用組件,對(duì)應(yīng)src/App.vue
Side-menu :側(cè)邊欄,因?yàn)檩^為容易且不需要改變單頁(yè)路由來(lái)顯示不同內(nèi)容,所以直接放在app組件里邊
router-view : 這是vue-router的子路由顯示面板,通過src/router/index.js來(lái)控制
home : 主頁(yè)視圖文件
public : 公用組件,亦可在其他頁(yè)面使用,降低工作量
AppHeader : 應(yīng)用頭部組件
Loading : 加載中的組件,就一張gif
側(cè)邊欄SideMenu組件
在src/components目錄中新建一個(gè)文件,名為SideMenu.vue,修改內(nèi)容為:
<template lang="html"> <div class="side-menu" @click = "hideSide"> <ul> <router-link v-for = "(item,index) in list" :to="item.url" :key = "index"> {{item.title}} <i class = "icon-chevron-right"></i> </router-link> </ul> </div> </template> <script> export default { data(){ return { list : [ {title : "首頁(yè)",url : "/"}, {title : "全部分類",url : "/category"} ] } }, methods : { hideSide(){ this.$emit("hide") } } } </script> <style lang="css"> .side-menu { background: rgba(10,10,10,.3); height: 100%; position: fixed; width: 100%; top: 0; padding-top: 44px; z-index: 11; } .side-menu ul { width: 70%; background: #282828; height: 100%; border-top: 1px solid #222; } .side-menu ul li { height: 50px; border-bottom: 1px dotted #333; font-size: 14px; line-height: 50px; padding: 0 30px 0 20px; color: #9a9a9a; } .side-menu ul li i { float: right; line-height: 50px; } </style>
這里解釋一下文件里面的內(nèi)容:
文件分為三大塊
template
script
style
這些內(nèi)容通過script中node的export方法推出去
其中template渲染了幾個(gè)router-link,用來(lái)跳轉(zhuǎn)路由
script定義了data和method
style寫了樣式
然后打開src/App.vue,修改里面的內(nèi)容,追加下圖內(nèi)容:
好的,我們的SideMenu組件就注冊(cè)完成了。
搭建router-view內(nèi)容
好的,我們接下來(lái)做router-view的內(nèi)容
bus-中央總線
在做之前,我們需要了解一個(gè)新的概念-bus,又稱中央總線
好的,又是之前那張思維導(dǎo)圖,不過是不是多出了三臺(tái)車呢?
沒錯(cuò),這就是我們的bus。
當(dāng)appheader想加載側(cè)邊欄時(shí),是不能穿越徒步穿越山和大海的,老司機(jī)還是要開車的是不是
這個(gè)時(shí)候我們坐公交就行了,告訴app,把我給拉出來(lái)
當(dāng)然,side-menu和app之間相距不遠(yuǎn),父子組件是可以直接綁定的
在src目錄下創(chuàng)建bus.js,內(nèi)容為
這是我們的bus,說白了就是一個(gè)對(duì)象,只不過借用了vue的消息管道,大家也可以自己寫個(gè)管道
制造home主頁(yè)路由
在src目錄下創(chuàng)建pages目錄,這個(gè)目錄我們用來(lái)存放router-vue的內(nèi)容
然后我們?cè)趕rc/pages/下創(chuàng)建一個(gè)home.vue組件,用來(lái)做home的內(nèi)容,寫下以下內(nèi)容:
<template lang="html"> <div class="mr-root"> <app-header> <p class = "title">斗魚TV</p> </app-header> <loading v-if="showLoading"></loading> </div> </template> <script> import Public from "../public" export default { mixins : [ Public ], data(){ return { showLoading : true } } } </script> <style lang="css" scoped> </style>
解釋一下,這里使用了app-header和loading組件,由Public導(dǎo)入(等會(huì)寫)。
mixins是一個(gè)混合物,能夠自動(dòng)把模組分析,加載到當(dāng)前實(shí)例中。
data中 showLoading和v-if配合使用,用來(lái)關(guān)閉loading效果
如果不清楚的話可以看下思維導(dǎo)圖
public公用模組
public是一個(gè)模組集合,我們?cè)陂_發(fā)的時(shí)候可能不同頁(yè)面要使用相同的組件,這時(shí)就需要public打包處理了。
在src中新建public.js,內(nèi)容如下:
import AppHeader from './components/AppHeader' import Loading from './components/Loading' export default{ components: { AppHeader, Loading } }
上文我們導(dǎo)入了AppHeader和Loading模塊,并設(shè)置了默認(rèn)導(dǎo)出
好,那么我們來(lái)寫兩個(gè)子模組,
AppHeader
在components中新建一個(gè)文件AppHeader.vue,代碼如下
<template lang="html"> <header> <i class = "icon-reorder" @click = "showSlide"></i> <slot></slot> <i class = "icon-user"></i> </header> </template> <script> import bus from "../bus" export default { methods : { showSlide(){ bus.$emit('showSide') } } } </script> <style lang="css" scoped> header { height: 44px; background: #333; position: fixed; left: 0; right: 0; top: 0; z-index: 100; padding: 0 15px; color: #fff; line-height: 44px; font-size: 16px; } header i { color: #999; } .title { margin-left: 15px; display: inline-block; } .icon-user { float: right; line-height: 44px; } </style>
定義了基本的頭部,給加載更多綁定了一個(gè)事件,通過bus進(jìn)行傳遞,由app.vue來(lái)實(shí)現(xiàn)
Loading組件
src/components/里面新建一個(gè)Loading.vue,代碼如下:
<style lang="css"> .loading { height: 100%; position: fixed; z-index: 10; width: 100%; background: #062734; opacity: .4; } .loading img { width: 100%; height: auto; position: absolute; top: calc(50% - 140px); } </style>
就添加了一張gif圖而已,非常簡(jiǎn)單的
bus事件的處理
好的,既然我們的appheader已經(jīng)發(fā)車了,那么應(yīng)該在app.vue根路由里面開個(gè)公交車站,來(lái)接收巴士:
修改App.vue:
<template> <div id="app"> <transition name = "side"> <side-menu v-show = "show" @hide = "hideSide"></side-menu> </transition> <router-view/> </div> </template> <script> import SideMenu from "./components/SideMenu" import bus from "./bus" export default { name: 'app', components : { SideMenu }, created(){ this.$http.get(`/douyuapi/RoomApi/live?offset=1&limit=20`).then(res=>{ console.log(res.data.data); }) }, data(){ return { show : false } }, mounted () { bus.$on("showSide",this.side) }, methods : { side(){ this.show = !this.show }, hideSide(){ this.show = false } } } </script> <style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
修改路由
修改根路由/src/router/index.js為:
import Vue from 'vue' import Router from 'vue-router' import Home from '@/pages/Home' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'Home', component: Home } ] })
增加HomeItem
好的,我們有了以上功能以后呢,還需要在斗魚主頁(yè)中增加聊天室列表,在components目錄中新建文件HomeItem.vue
<template lang="html"> <div class="mr-item"> <router-link :to="'/room/'+room.room_id"> <img :src="room.room_src" alt=""> <div class="room-info"> <span class = "nickname">{{room.nickname}}</span> <span class = "count"> <i class = "icon-group"></i> {{room.online || number}} </span> </div> <div class="room-title"> <i class = "icon-desktop"></i> {{room.room_name || message}} </div> </router-link> </div> </template> <script> export default { props : ["room"] } </script> <style lang="css" scoped> .mr-item { margin-top: 10px; float: left; width: 4.4rem; margin-right: .3rem; position: relative; } .mr-item img { width: 100%; height: 2.6rem; border-radius: 5px; } .room-info { position: absolute; bottom: 33px; color: #fff; padding: 0 5px; left: 0; right: 0; overflow: hidden; background: rgba(10,10,10,.5); line-height: 24px; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; } .room-info .count { float: right; } .room-title { line-height: 30px; } </style>
home.vue中加載homeitem
我們需要在Home.vue中加載HomeItem,修改home.vue為
<template lang="html"> <div class="mr-root"> <app-header> <p class = "title">斗魚TV</p> </app-header> <loading v-if="showLoading"></loading> <home-item v-for = "(room,index) in roomList" :room = "room" :key = "index"> </home-item> <p v-if = "error">加載失敗,請(qǐng)稍后再試...</p> <div class="clear"></div> <div class="load-more"> <span @click = "loadMore">點(diǎn)擊加載更多</span> </div> </div> </template> <script> import Public from "../public" import HomeItem from "../components/HomeItem" export default { mixins : [ Public ], data(){ return { showLoading : true, error : false, roomList : [], page : 0 } }, components : { HomeItem }, created(){ this.getInfo(this.page) }, methods : { getInfo(page){ this.$http.get(`/douyuapi/RoomApi/live?offset=1&limit=20`).then(res=>{ this.error = false this.roomList = this.roomList.concat(res.data.data) setTimeout(()=>{ this.showLoading = false },1000) }) .catch(err=>{ this.error = true this.showLoading = false }) }, loadMore(){ this.page++ this.getInfo(this.page) } } } </script> <style lang="css"> .mr-content { padding: 44px 0 0 .3rem; overflow: hidden; } .load-more { margin: 10px; text-align: center; } .load-more span { display: inline-block; line-height: 30px; padding: 0 20px; border-radius: 10px; border: 1px solid #000; } </style>
現(xiàn)在看下頁(yè)面,是不是已經(jīng)出來(lái)了呢?
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。