版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
摘要知識(shí)貯藏在謙虛的大海中。在物質(zhì)越來越充實(shí)的年代,知識(shí)方面的匱乏反而越來越突出。因此,網(wǎng)上慕課或是網(wǎng)上書籍應(yīng)運(yùn)而生。在國外,“微課程”概念最早是由美國戴維首創(chuàng)的。而在微課的持續(xù)發(fā)展過程中,國外對(duì)于微課程的研究拓展于不同的各個(gè)方面。在國內(nèi),由于流媒體的發(fā)展,微課程成為了一個(gè)里程碑級(jí)的產(chǎn)物。在這個(gè)產(chǎn)品中,用戶可以在網(wǎng)上選擇自己感興趣或是想要了解的課程,隨時(shí)隨地聽課學(xué)習(xí)。軟件分為兩個(gè)主頁面,商城頁面以及用戶信息頁面。商城頁面為專欄、課程的列表,具備搜索功能;用戶信息頁面為用戶個(gè)人信息的展示。在搭建工程之前,首先要捋清楚該產(chǎn)品的整體框架、各個(gè)模塊之間的關(guān)系以及繪制出所需的后臺(tái)數(shù)據(jù)庫、整理各個(gè)變量之間的關(guān)系等。本書首先介紹了H5網(wǎng)絡(luò)課程的發(fā)展前景以及現(xiàn)狀,其次分析了開發(fā)該平臺(tái)所需要用到的技術(shù),如react.js、websocket、typescript等,其中react.js為本次開發(fā)的主技術(shù)棧。接著是各個(gè)頁面、模塊的單獨(dú)介紹,首先是樣式(截圖展示),而后將頁面內(nèi)較為重要的模塊單獨(dú)拎出來講解實(shí)現(xiàn)的主要技術(shù)以及步驟。為了方面展示,在本產(chǎn)品中特意將錄像源以及展示源安置在同一個(gè)頁面內(nèi)以便觀察現(xiàn)象。直播實(shí)現(xiàn)所需要的技術(shù)websocket是本書的一個(gè)重點(diǎn),它需要客戶端以及服務(wù)器端兩邊的配合,websocket可以認(rèn)為是http協(xié)議的升級(jí)版本,兩者沒有必要的聯(lián)系。最后即是在前端頁面開發(fā)過程中所遇到的、容易遇到的問題,如頁面兼容性、頁面性能等,本書也進(jìn)行了詳細(xì)的總結(jié)。關(guān)鍵詞:網(wǎng)絡(luò)課程,websocket,react.js,前端
AbstractKnowledgeisstoredintheseaofmodesty.Intheeraofmaterialenrichment,thelackofknowledgehasbecomemoreandmoreprominent.Consequently,onlinecourseworkoronlinebooksbebornattherightmoment.Inforeigncountries,theconceptof"micro-curriculum"wasfirstinventedbyDavidoftheUnitedStates.Inthecourseofthesustaineddevelopmentofmicro-coursesforeignresearchonmicro-curriculumhasexpandedtodifferentaspects.InChina,duetothedevelopmentofstreamingmedia,micro-curriculumhasbecomealandmarkproduct.Inthisproduct,userscanchoosecoursestheyareinterestedinorwanttoknowonline,andlistentothemanytimeandanywhere.Thesoftwareisdividedintotwomainpages,mallpagesanduserinformationpages.Themallpageisalistofcolumnsandcourseswithsearchfunction,andtheuserinformationpageisadisplayoftheuser'spersonalinformation.Beforebuildingtheproject,firstofall,weneedtounderstandtheoverallframeworkoftheproduct,therelationshipbetweenthevariousmodules,anddrawtherequiredbackgrounddatabase,sortingouttherelationshipbetweenthevariousvariables,andsoon.ThisbookfirstintroducesthedevelopmentprospectsandcurrentsituationofH5networkcourse.Secondly,itanalysesthetechnologiesneededtodeveloptheplatform,suchasreact.js,websocket,typescriptandsoon.Amongthem,react.JSisthemaintechnologystackforthisdevelopment.Nextistheindividualintroductionofeachpageandmodule,firstisthestyle(screenshotdisplay),andthenthemoreimportantmoduleinthepageiscarriedoutseparatelytoexplainthemaintechnologyandstepsofimplementation.Foraspectdisplay,thevideosourceandthedisplaysourcearespeciallyplacedinthesamepageinordertoobservethephenomenon.Websocketisoneofthekeytechnologiesinthisbook.Itneedsthecooperationofbothclientandserver.websocketcanberegardedasanupgradedversionofHTTPprotocol.Thereisnonecessaryconnectionbetweenthetwo.Finally,thisbookalsogivesadetailedsummaryoftheproblemsencounteredinthefront-endpagedevelopmentprocess,suchaspagecompatibility,pageperformanceandsoon.Keywords:webcourse,websocket,react.js,front-end
目錄TOC\o"1-3"\h\u1緒論 緒論1.1網(wǎng)絡(luò)微課平臺(tái)的意義對(duì)于愛好學(xué)習(xí)、想要時(shí)時(shí)對(duì)知識(shí)充充電的人來說,只有課下一個(gè)學(xué)習(xí)形式是很不夠的,不僅路途遙遠(yuǎn)而且時(shí)間上有的可能也安排不過來。所以在網(wǎng)絡(luò)異常發(fā)達(dá)的今天,我們應(yīng)該充分利用網(wǎng)絡(luò)的優(yōu)勢(shì),讓學(xué)習(xí)、讀書變得更加容易。近年來,網(wǎng)上慕課的興起相信很多學(xué)校的學(xué)生以及老師都有所了解,由此基礎(chǔ)上,很多企業(yè)都爭相效仿開發(fā)出一系列微課app,如樂兒思、千聊、荔枝微課等等。在這些平臺(tái)上,人們可以根據(jù)自己的意愿選擇想要聽什么課、不想要聽什么課。不僅如此,這些軟件還有一個(gè)特點(diǎn)就是“三人行,人人皆可為師”。只要你有可以跟眾多網(wǎng)友分享的經(jīng)驗(yàn)或是知識(shí),都可以自己單獨(dú)開一門課程上傳到平臺(tái)上,如果平臺(tái)判定你的課程是有價(jià)值的、值得傳播的還會(huì)幫你包裝、推廣出去。由此可看出,微課這一類app是近幾年的大熱,而在這個(gè)“求賢若渴”的時(shí)代,抓住群眾的心理,通過一些渠道或是活動(dòng)營銷方法把一些有價(jià)值的課程推銷出去是一個(gè)很好的商機(jī)。1.2微課平臺(tái)的現(xiàn)狀《國家中長期教育改革和發(fā)展規(guī)劃綱要(2010-2020年)》和《教育信息化十年發(fā)展規(guī)劃(2011-2020年)》兩個(gè)文件都明確指出:要將教育信息化納入國家信息化發(fā)展整體戰(zhàn)略,要充分發(fā)揮現(xiàn)代信息技術(shù)優(yōu)勢(shì),注重信息技術(shù)和教育的全面深度融合。這為微課提供了政策支持。以下為目前幾個(gè)微課平臺(tái)的簡略介紹:(1)荔枝微課:荔枝微課是一個(gè)大眾皆可用的知識(shí)、生活常識(shí)等互相交流的平臺(tái)。在荔枝微課里,每個(gè)人都可以創(chuàng)建課程并分享你所想要告訴聽眾的知識(shí),同樣也可以點(diǎn)開課程入口聽課學(xué)習(xí)。平臺(tái)支持零門檻開課,支持微信公眾號(hào)、APP和電腦多種方式聽課開課,擁有語音、圖片、PPT、視頻、音頻等多種講課模式。該平臺(tái)開課豐富多樣,包含自我成長、情感關(guān)系、職場提升、投資理財(cái)、育兒教育等各個(gè)方面[2]。(2)千聊:千聊由騰訊眾創(chuàng)空間孵化,是國內(nèi)領(lǐng)先的在線知識(shí)社區(qū),是一個(gè)專注于知識(shí)分享的平臺(tái),通過直播的形式讓您直接找到各個(gè)領(lǐng)域的專家、老師、達(dá)人[3]。在該平臺(tái)上,用戶們可以進(jìn)行在線互動(dòng)、交流,互相討論學(xué)術(shù)或是觀點(diǎn)。當(dāng)然,也可以對(duì)自己感興趣的課程進(jìn)行購買,隨時(shí)回聽回看、重溫課程,鞏固知識(shí)。1.3微課平臺(tái)應(yīng)用前景展望在網(wǎng)絡(luò)不斷發(fā)展的這個(gè)時(shí)代,微課平臺(tái)將與虎牙直播、微博、facebook等這一類平臺(tái)一樣,具有十分廣闊的應(yīng)用前景。對(duì)于教師來說,這是一個(gè)很大的教學(xué)方式上的改革,突破了一直以來傳統(tǒng)的、受限的聽課、授課形式,可以隨時(shí)隨地聽課、授課,使得課程更加具備針對(duì)性以及時(shí)效性,是傳統(tǒng)課堂的一個(gè)資源拓展和重要補(bǔ)充。雖說網(wǎng)絡(luò)授課形式無法取代傳統(tǒng)授課形式,但是這兩種授課形式在當(dāng)今時(shí)代是相輔相成的,目前也已有許多學(xué)校以及教師運(yùn)用網(wǎng)絡(luò)課程來輔助教學(xué)。網(wǎng)絡(luò)課程不僅可以補(bǔ)充課堂上的各種知識(shí),也可以補(bǔ)充課外的知識(shí),讓學(xué)生不再是只會(huì)單純的學(xué)習(xí)語數(shù)英的“書呆子”,而是在生活上也能夠?qū)W會(huì)做個(gè)“聰明人”。相信在不久后,網(wǎng)絡(luò)授課的形式將會(huì)越來越受歡迎,應(yīng)用也將會(huì)越廣泛。1.4本章小結(jié)本章主要對(duì)微課平臺(tái)類軟件的意義進(jìn)行了一番詳細(xì)討論,對(duì)微課平臺(tái)的發(fā)展現(xiàn)狀以及應(yīng)用前景做了基本的介紹。下一章將對(duì)如何構(gòu)建微課平臺(tái)的大致架構(gòu)設(shè)計(jì)思路以及模塊做詳細(xì)的解說。
2設(shè)計(jì)思路和相關(guān)技術(shù)介紹2.1設(shè)計(jì)思路以及模塊在該網(wǎng)絡(luò)微課平臺(tái)中,主要將其分為兩個(gè)部分:課程展示頁面(tab:商城)以及用戶信息頁面(tab:我的)。“商城”頁面里面主要內(nèi)容就是課程的列表展示,拓展一個(gè)搜索課程功能;“我的”頁面里面主要是包含用戶信息、管理列表,外加用于營銷的收益展示。如下圖所示:商城商城搜索功能列表展示用戶信息我的收益展示管理列表圖2.1本設(shè)計(jì)的各模塊分布代碼結(jié)構(gòu)設(shè)計(jì)如下:appappmodelImagesContextConfigContainersComponentStylesUtil圖2.2代碼結(jié)構(gòu)圖各模塊釋義:Component:復(fù)用組件代碼;Containers:各頁面代碼;Config:配置文件代碼;Context:上下文代碼;Images:本地圖片文件夾;Model:接口模板代碼;Util:各接口代碼;Styles:各樣式表代碼2.2相關(guān)技術(shù)介紹在本次設(shè)計(jì)中,主要使用的開發(fā)工具是vscode,輔助工具是photoshop、git、chrome瀏覽器;主要使用的腳本語言/框架為Html5、Css3、React.js、Typescript。下面主要介紹一下編程工具Vscode、作圖工具Photoshop、React.js以及Typescript。VscodeVscode全名叫VisualStudioCode,是由美國微軟公司開發(fā)的一個(gè)運(yùn)行于MacOSX、Windows和Linux之上的,針對(duì)于編寫現(xiàn)代Web和云應(yīng)用的跨平臺(tái)源代碼編輯器[4]。該編輯器聚合了任何一款現(xiàn)代編輯器所應(yīng)該具備的特性,包括語法高亮,熱鍵綁定,括號(hào)匹配以及代碼片段收集,同時(shí)也具備對(duì)Git的開箱即用的支持。該編輯器也能夠使用webstorm、sublime等軟件替代,這些編程軟件都是經(jīng)過本人實(shí)踐過認(rèn)為較好用的軟件。PhotoshopPhotoshop是由Adobe公司開發(fā)的一款圖片編輯軟件,也是為今較多人用且較好用的一款軟件。從功能上看,它具備圖像編輯、圖像合成、特效制作等,還可以縮小、放大、去除圖像的斑點(diǎn)等操作,在圖片制作、廣告攝影、網(wǎng)頁設(shè)計(jì)上面都有它的身影。Photoshop軟件可以把幾張很普通的圖片和設(shè)計(jì)者的思路、想法聯(lián)系在一起,操作簡便易懂,使設(shè)計(jì)、創(chuàng)作者能將更多的時(shí)間放在構(gòu)思畫面上去。(3)React.jsMVC框架是模型(model)-視圖(view)-控制器(controller)的縮寫。MVC分層這種層次分明的結(jié)構(gòu)對(duì)管理一些較為復(fù)雜的應(yīng)用程序有很好的幫助,它具有耦合性低、重用性高、生命周期成本低、可維護(hù)性高等優(yōu)點(diǎn)。React.js是由Facebook公司研發(fā)的一個(gè)用于構(gòu)建組件化UI的庫,由于它的性能出眾、代碼邏輯簡單,漸漸的越來越受程序員們的關(guān)注與喜愛。它介紹了JavascriptXML和JSX的使用,是Javascript的語法拓展。在使用React框架時(shí),可以充分利用React的官網(wǎng),里面有詳細(xì)的使用教程供開發(fā)者們查閱學(xué)習(xí)。(4)TypescriptTypescript是由微軟開發(fā)的開源的編程語言,它是Javascript的一個(gè)超集,而且本質(zhì)上向這個(gè)語言添加了可選的靜態(tài)類型和基于類的面向?qū)ο缶幊獭?.3數(shù)據(jù)庫圖表設(shè)計(jì)在開發(fā)中,難免會(huì)遇到有前端與后臺(tái)之間數(shù)據(jù)的交互,這個(gè)時(shí)候,就需要后臺(tái)的數(shù)據(jù)庫的支持。下面是在該需求中所需要的兩個(gè)主要的數(shù)據(jù)庫,在用戶信息頁面中,主要是用戶各個(gè)信息的圖表:圖2.3用戶信息表接下來是商城頁面中所需要的課程各方面信息的圖表:圖2.4課程信息表當(dāng)前端頁面需要用到這些信息或者更新這些信息的時(shí)候,就會(huì)用axios去訪問后臺(tái)接口,返回的res.data.data就是前端所需要的數(shù)據(jù)列表。2.4論文結(jié)構(gòu)本文主要將所需要闡述的內(nèi)容分為七章來展示,分別為以下:(1)緒論:主要對(duì)微課平臺(tái)類軟件的意義進(jìn)行了一番詳細(xì)討論,對(duì)微課平臺(tái)的發(fā)展現(xiàn)狀以及應(yīng)用前景做了基本的介紹;(2)設(shè)計(jì)思路和相關(guān)技術(shù)介紹:主要介紹了該網(wǎng)絡(luò)微課平臺(tái)的設(shè)計(jì)思路以及所需要用到的各個(gè)相關(guān)軟件,如:vscode、photoshop等,著重介紹了這兩款軟件的功能、用途以及兩項(xiàng)主要的編程技術(shù)點(diǎn):React.js、Typescript,并且將兩個(gè)主要的數(shù)據(jù)庫設(shè)計(jì)以及論文結(jié)構(gòu)設(shè)計(jì)在文中加以說明;(3)React組件化:主要講述了react的生命周期函數(shù)以及react最重要的部分——組件之間的通信方式;(4)課程展示:主要介紹了商城展示頁面、點(diǎn)擊相應(yīng)課程所進(jìn)入的專欄頁面和搜索功能的頁面樣式以及相應(yīng)代碼。在本章所介紹的各個(gè)頁面中,主要是前端排版、樣式的工作量以及搜索功能方面的邏輯代碼的實(shí)現(xiàn);(5)直播實(shí)現(xiàn):主要介紹了websocket協(xié)議以及如何利用該協(xié)議分別在客戶端、服務(wù)端實(shí)現(xiàn)直播功能;(6)用戶信息頁面:主要展示了用戶信息頁面的各個(gè)模塊,大部分都是頁面樣式方面的工作;(7)問題總結(jié):主要介紹了一些在前端開發(fā)方面需要注意的兼容性以及性能的影響,并且記錄了幾個(gè)在開發(fā)過程中所遇見的bug。2.5本章小結(jié)本章主要介紹了該網(wǎng)絡(luò)微課平臺(tái)的設(shè)計(jì)思路以及所需要用到的各個(gè)相關(guān)軟件,如:vscode、photoshop等,著重介紹了這兩款軟件的功能、用途以及兩項(xiàng)主要的編程技術(shù)點(diǎn):React.js、Typescript,并且將兩個(gè)主要的數(shù)據(jù)庫設(shè)計(jì)以及論文結(jié)構(gòu)設(shè)計(jì)在文中加以說明。
3React組件化將一個(gè)完整模塊的代碼拆分為組件之后,不可避免的就會(huì)遇到一些組件與組件之間需要數(shù)據(jù)傳遞的問題,這就是組件之間的通信。組件之間的通信又分為兄弟組件通信(同個(gè)父組件)、子組件向父組件通信、父組件向子組件通信等。兄弟組件之間的通信其實(shí)就是子組件向父組件傳值、父組件向子組件傳值這兩個(gè)過程的結(jié)合。接下來將一一介紹。3.1生命周期函數(shù)在介紹各個(gè)組件之間傳值的過程之前,先來介紹以下react的生命周期函數(shù)。React生命周期分為三種狀態(tài):初始頁面結(jié)構(gòu)組建以及渲染(mount)、更新(update)、卸載(unmount)。初始化時(shí)常用的由render()、componentWillMount()、componentDidMount(),更新時(shí)常用的有componentWillReceiveProps(nextProps)、componentDidUpdate(),銷毀時(shí)常用的有componentWillUnmount()。render()render即為組建渲染,主要步驟是創(chuàng)建虛擬dom、進(jìn)行diff算法、更新dom樹。react這類框架的特點(diǎn)是能夠?qū)崿F(xiàn)數(shù)據(jù)改變視圖,即代碼中利用state狀態(tài)機(jī)更新數(shù)據(jù)后,react會(huì)自動(dòng)啟用diff算法,當(dāng)計(jì)算結(jié)果與state更新前不一樣時(shí),自動(dòng)更新dom樹。componentWillMount()該函數(shù)只在組件初始化時(shí)調(diào)用一次,此后都不再調(diào)用,此時(shí)可以修改ponentDidMount()該函數(shù)在組件渲染之后調(diào)用。componentWillReceiveProps(nextProps)該函數(shù)在組件初始化時(shí)不調(diào)用,但是在組件更新時(shí),接收到新的props時(shí)調(diào)用。componentDidUpdate()該函數(shù)在組件初始化時(shí)不調(diào)用,但是在接下來的組件每次更新完畢之后調(diào)用,此時(shí)可以獲取dom節(jié)點(diǎn)。componentWillUnmount()該函數(shù)在組件將要卸載時(shí)調(diào)用,在這之前如果前面有設(shè)置一些事件監(jiān)聽或者定時(shí)器的話,需要將之清除。3.2父組件向子組件傳值不同于vue.js,react.js的數(shù)據(jù)流動(dòng)是單向的,父子組件之間的通信是通過props傳遞所需要的信息。在父組件中,假如要調(diào)用子組件,并將狀態(tài)傳遞給子組件,可以這樣寫:<ChildifShow={this.state.ifShow}/>如此,在子組件時(shí)想要獲取父組件中的ifShow可以這樣寫:{ps.ifShow&&<div>是否顯示</div>}利用與運(yùn)算符或者三元運(yùn)算符能夠靈活地控制在react中組件或者部分模塊的渲染與否。此時(shí),如果父組件中ifShow為true,在子組件中就會(huì)渲染出“是否顯示”幾個(gè)字,相反的,若父組件中ifShow為false,在子組件中就不會(huì)顯示。3.3子組件向父組件傳值若是子組件要向父組件傳遞數(shù)據(jù),則主要是通過回調(diào)函數(shù)來實(shí)現(xiàn)。在子組件中:<div>我是子組件<buttononClick={ps.hideComponent}>隱藏子組件</button></div>在父組件中:<div><buttononClick={this.showComponent}>顯示子組件</button>{this.state.isShow?<ChildhideComponent={this.hideComponent}/>:null }</div>其中,showComponent與hideComponent函數(shù)定義如下:showComponent=()=>{this.setState({isShow:true,});}hideConponent=()=>{this.setState({isShow:false,});}此時(shí),點(diǎn)擊子組件內(nèi)的button就能通過回調(diào)函數(shù)使父組件內(nèi)的isShow值改變,從而控制子組件的渲染與否。3.4子組件與子組件之間的通信子組件與子組件之間的通信又分為跨級(jí)組件通信(不同父組件)及兄弟組件通信(同一個(gè)父組件)。兄弟之間傳遞數(shù)據(jù)是通過相同的父級(jí)組件作為“媒介”來實(shí)現(xiàn),而跨級(jí)組件之間的數(shù)據(jù)傳遞普遍是使用context。Context即上下文,屬于react的高級(jí)API。它是一個(gè)當(dāng)開發(fā)者不想一級(jí)一級(jí)地傳遞props以及state來傳遞數(shù)據(jù)時(shí),可以提供跨層級(jí)組件數(shù)據(jù)傳遞功能的對(duì)象。3.5本章小結(jié)本章主要講述了react的生命周期函數(shù)以及react最重要的部分——組件之間的通信方式。
4課程展示4.1商城頁面在商城頁面中,主要包含搜索欄、海報(bào)部分、推薦課程部分、浮窗部分,點(diǎn)擊即可進(jìn)入相應(yīng)的課程或是活動(dòng)頁面進(jìn)行聽課、購買等操作。由于主頁的推薦課程經(jīng)常變動(dòng),所以相應(yīng)的文本或是圖片均為后臺(tái)配置,可減少后期頁面改動(dòng)時(shí)前端的工作量。樣式如下圖所示:圖4.1商城頁面樣式4.2搜索功能在眾多的課程里面,如何讓用戶能夠快速定位到自己感興趣的課程呢?在這個(gè)時(shí)候,搜索功能是必不可少的。搜索的實(shí)現(xiàn)主要思路就是在課程數(shù)據(jù)庫中利用相似查找、關(guān)鍵字查找等方法,將名字符合搜索條件的課程陳列下來,供用戶選擇。如此一來,能夠減少很多用戶查找的時(shí)間以及精力,使得用戶體驗(yàn)感更佳。搜索頁面的樣式如下:圖4.2搜索頁面眾所周知,百度搜索引擎是通過GET請(qǐng)求實(shí)現(xiàn)搜索功能的,最淺顯的表現(xiàn)就在于在頁面url上“佩戴”搜索參數(shù)。搜索框中根據(jù)用戶輸入的關(guān)鍵字,發(fā)起請(qǐng)求時(shí)請(qǐng)求路徑為當(dāng)前頁面路徑‘/search’。該搜索功能主要利用springmvc框架以及mybatis實(shí)現(xiàn),可以對(duì)指定的關(guān)鍵字進(jìn)行搜索。MyBatis支持普通SQL查詢,存儲(chǔ)過程和高級(jí)映射??刂茖哟a如下:@GetMapping("/search")publicStringlist(@RequestParam(required=false,defaultValue="1",name="p")IntegerpageNo,@RequestParam(required=false,defaultValue="")StringproductName,Modelmodel){Map<String,Object>searchParam=newHashMap<>();searchParam.put("productName",productName);PageInfo<Lizhi>pageInfo=lizhiService.findByPageNo(pageNo,searchParam);model.addAttribute("pageInfo",pageInfo);return"search/list";}當(dāng)搜索結(jié)果過多時(shí),為了摒棄舊時(shí)“上一頁”、“下一頁”的分頁模式,我們采用監(jiān)聽頁面滾動(dòng)的方法來進(jìn)行懶加載,在react中使用觸發(fā)事件實(shí)現(xiàn)如部分代碼如下:<SearchBoxsearchReq={this.handleSearch}link={false}/>handleSearch(value:string){if(value){this.setState({liveList:[],searchStr:value,page:1,initialized:false},()=>this.getList());}}getList(){if(this.state.init){this.setState({init:false});}const{page,searchStr}=this.state;sessionStorage.setItem('searchValue',searchStr);axios.get('/search/channel',{params:{q:searchStr,page:page,per_page:20}}).then((res)=>{letlist=res.data.data;lethasMore=list.length>0;list=this.state.liveList.concat(list);this.setState({hasMore:hasMore,liveList:list,total:res.data.pages,initialized:true,page:page+1});});}4.3專欄頁面一系列課程構(gòu)成一個(gè)專欄,在商城中點(diǎn)擊某個(gè)具體課程專欄即可進(jìn)入專欄頁面。頁面內(nèi)主要包含海報(bào)部分、課程介紹部分以及課程目錄部分,如下圖所示:圖4.3專欄頁面在專欄頁面中,重點(diǎn)部分是底部的“試聽”功能。試聽時(shí)運(yùn)用的是html5新增的audio標(biāo)簽,主要技術(shù)難點(diǎn)在于播放進(jìn)度條的樣式以及拖動(dòng)控制播放進(jìn)度功能的實(shí)現(xiàn)。由于主要是手機(jī)端展示的頁面,所以拖動(dòng)事件的監(jiān)聽主要是依賴手機(jī)端的觸摸事件,由ontouchstart、ontouchmove、ontouchend一類,而拖動(dòng)進(jìn)度條的具體長度依賴于clientX、offsetX等。點(diǎn)擊“試聽”按鈕之后,試聽列表以及播放進(jìn)度條樣式如下圖所示:圖4.4試聽列表界面試聽部分代碼展示見附錄。4.4本章小結(jié)本章中,主要介紹了商城展示頁面、點(diǎn)擊相應(yīng)課程所進(jìn)入的專欄頁面和搜索功能的頁面樣式以及相應(yīng)代碼。在本章所介紹的各個(gè)頁面中,主要是前端排版、樣式的工作量以及搜索功能方面的邏輯代碼的實(shí)現(xiàn)。在下一章中,將介紹最主要的直播功能實(shí)現(xiàn)所需要的技術(shù)。
5直播實(shí)現(xiàn)5.1websocket技術(shù)目前為止,輪詢是實(shí)現(xiàn)實(shí)時(shí)通信的最常用的方法,而實(shí)時(shí)推送,毋庸置疑也會(huì)用到輪詢。輪詢是在固定的時(shí)間間隔內(nèi),客戶端向服務(wù)器請(qǐng)求數(shù)據(jù),然后由服務(wù)器將數(shù)據(jù)返回給客戶端展示。一開始主流的是使用AJAX輪詢的方式來進(jìn)行通信,但是這種輪詢方式有一定的延時(shí),還會(huì)對(duì)服務(wù)器造成一定的負(fù)載。直到2011年,websocket才被標(biāo)準(zhǔn)化。直播即推送,H5頁面中能夠?qū)崿F(xiàn)直播的技術(shù)有很多,目前web上比較主流的方案是使用HLS和RTMP,在這里介紹的是一個(gè)較為簡便的利用websocket協(xié)議實(shí)現(xiàn)直播的方法。WebSocket是一種在單個(gè)TCP連接上進(jìn)行全雙工通信的協(xié)議[5],它使得服務(wù)器與客戶端之間的通信從繁瑣的三次握手、四次握手演變成一次長連接即可保持通信的狀態(tài),允許服務(wù)器主動(dòng)向客戶端推送數(shù)據(jù)。圖5.1建立握手時(shí)序圖但是websocket有一個(gè)限制即在不支持websocket的設(shè)備上是無法使用的。Websocket在服務(wù)器端的實(shí)現(xiàn)非常豐富,可以使用node.js、c++、java、python等多種解決方案。5.2socket.io由于websocket原生的API用起來可能沒有那么方便,所以就有了socket.io.js這款集成的插件,它所提供的API能供開發(fā)更方便得使用。Socket.io將websocket和AJAX輪詢進(jìn)行封裝,實(shí)際是websocket的父集,實(shí)現(xiàn)了跨瀏覽器的雙向數(shù)據(jù)傳輸。它典型的應(yīng)用場所有:實(shí)時(shí)聊天應(yīng)用、文檔合并、二進(jìn)制流傳輸?shù)鹊?。客戶端和服?wù)端的socket是一個(gè)關(guān)聯(lián)的EventEmitter對(duì)象,客戶端socket發(fā)出的事件可以被服務(wù)端的socket接收,同理,服務(wù)端socket發(fā)出的事件也可以被客戶端接收?;谠摍C(jī)制,可以實(shí)現(xiàn)雙向交流。socket.io由兩部分組成,與Node.JSHTTPServer集成(或安裝)的服務(wù)器以及客戶端庫。在開發(fā)過程中,想要使用socket.io插件首先要安裝該模塊:npminstall--savesocket.io除了簡單的客戶端與服務(wù)器相互傳遞消息之外,socket.io還提供廣播功能,由于本例中沒有應(yīng)用到,故在此不詳細(xì)敘述。5.3websocket客戶端實(shí)現(xiàn)Websocket在客戶端的編程只需要使用現(xiàn)成的websocketAPI即可,首先創(chuàng)建一個(gè)websocket對(duì)象:varSocket=newWebSocket(url,[protocol]);Websocket事件(1)open:連接建立時(shí)觸發(fā),監(jiān)聽事件使用onopen屬性;(2)message:當(dāng)客戶端接收服務(wù)端數(shù)據(jù)時(shí)引發(fā)該事件,監(jiān)聽事件使用onmessage屬性;(3)error:當(dāng)通信過程中出現(xiàn)錯(cuò)誤時(shí)引發(fā)該事件,監(jiān)聽事件使用onerror屬性;(4)close:當(dāng)websocket連接關(guān)閉時(shí)引發(fā)該事件,監(jiān)聽事件使用onclose屬性。Socket.io實(shí)現(xiàn)(1)建立一個(gè)socket連接varsocket=io(“ws://localhost:3001”);(2)socket.on:監(jiān)聽服務(wù)器消息,監(jiān)聽的事件主要有message(消息傳輸)、connect(連接成功)、disconnect(斷開連接)、error(發(fā)生錯(cuò)誤)等。(3)socket.emit:向服務(wù)器發(fā)送數(shù)據(jù),格式為socket.emit(‘msg’,{data:‘string’});圖5.2socket.emit事件連接過程中,觸發(fā)的事件為:connecting->connect;失去連接過程中,觸發(fā)的事件為sh:disconnect->reconnecting->connecting->reconnect->connect。代碼展示Html代碼:<divclassName={style.start}onClick={this.begin.bind(this)}>開始錄制</div>Typescript代碼:begin(){varwsURL=`ws://${document.domain}:3001`;varsocket=io(wsURL);console.log(socket)varback=this.output.current;//返回一個(gè)用于在畫布上繪圖的環(huán)境。if(back){varbackcontext=back.getContext('2d');}varvideo=this.source.current;varsuccess=function(stream:any){//獲取視屏流,轉(zhuǎn)換為urlif(video){console.log(stream)video.srcObject=stream;}}vardraw=function(){try{if(backcontext&&video&&back){backcontext.drawImage(video,0,0,back.width,back.height);varurl=back.toDataURL("image/jpeg",0.5);socket.emit('ImgURL',url);}}catch(e){if(=="NS_ERROR_NOT_AVAILABLE"){returnsetTimeout(draw,100);}else{throwe;}}setTimeout(draw,100);}draw();navigator.getUserMedia({video:true,audio:false},success,console.log);setInterval(()=>{if(back){//Canvas的內(nèi)容轉(zhuǎn)化成dataURI并發(fā)送到服務(wù)器,0.5為和壓縮系數(shù)socket.on('receiveData',(url:any)=>{console.log(url)if(this.receive.current){this.receive.current.src=url}})}},100)}5.4websocket服務(wù)器實(shí)現(xiàn)剛剛介紹過,websocket在服務(wù)端的實(shí)現(xiàn)方法有許多,接下來簡略介紹一下各個(gè)方案的實(shí)現(xiàn)。Java使用java一般依托于servlet容器,其中Tomcat7、Jetty7及以上版本都開始支持Websocket協(xié)議。以上應(yīng)用對(duì)于WebSocket都有各自的實(shí)現(xiàn)。但是,它們都遵循RFC6455的通信標(biāo)準(zhǔn),并且JavaAPI統(tǒng)一遵循JSR356-JavaTMAPIforWebSocket規(guī)范。所以,在實(shí)際編碼中,API差異不大。Spring運(yùn)用spring框架實(shí)現(xiàn)websocket時(shí)需要搭建的環(huán)境依賴以下jar包:<dependency><groupId>org.springframework</groupId><artifactId>spring-messaging</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-websocket</artifactId></dependency>接下來就是創(chuàng)建websocket處理器以及配置websocket:(1)創(chuàng)建websocket處理器:擴(kuò)展TextWebSocketHandler或BinaryWebSocketHandler,可以將指定的某些方法重新編寫。Spring在收到WebSocket事件時(shí),會(huì)自動(dòng)調(diào)用事件對(duì)應(yīng)的方法。(2)配置websocket:配置可以使用注解或是xml兩種方式,作用是將websocket處理器添加到注冊(cè)中心。Socket.io服務(wù)端API//監(jiān)聽客戶端連接,回調(diào)函數(shù)會(huì)傳遞本次連接的socketio.on(‘connection’,function(socket));//給所有客戶端廣播消息io.sockets.emit(‘String’,data);//給指定客戶端發(fā)送消息io.sockets.socket(socketid).emit(‘String’,data);//監(jiān)聽客戶端發(fā)送的信息socket.on(‘String’,function(data));//給該socket的客戶端發(fā)送消息socket.emit(‘String’,data);代碼展示varapp=require('express')()varhttp=require('http').Server(app)vario=require('socket.io')(http)varport=3001//監(jiān)聽端口號(hào):3001app.get('/',(req,res)=>{ res.sendFile(__dirname+'/index.html')})io.on('connection',socket=>{ console.log('新用戶接入') socket.on("disconnect",()=>{ console.log('用戶斷開連接') })//監(jiān)聽客戶端發(fā)送的消息socket.on('message',data=>{ console.log('收到數(shù)據(jù):',data)io.emit('receiveData',data)})})http.listen(port,()=>{ console.log(`服務(wù)器監(jiān)聽本地端口號(hào):${port}`)})
運(yùn)行結(jié)果當(dāng)運(yùn)行后臺(tái)代碼時(shí),監(jiān)聽到用戶接入行為以及客戶端傳入的數(shù)據(jù),后臺(tái)顯示如下圖所示:圖5.3后臺(tái)數(shù)據(jù)傳輸當(dāng)用戶斷開連接時(shí),后臺(tái)顯示如下圖所示:圖5.4斷開連接顯示
連接成功后頁面如下圖所示(設(shè)置接收端比錄制端延遲一秒時(shí)間):圖5.5連接成功頁面顯示圖5.5本章小結(jié)本章主要闡述了websocket協(xié)議以及websocket如何在客戶端、服務(wù)端實(shí)現(xiàn)直播功能。Websocket協(xié)議與HTTP協(xié)議其實(shí)沒有關(guān)聯(lián),眾所周知,HTTP協(xié)議是一個(gè)無狀態(tài)協(xié)議,而websocket協(xié)議能夠使得客戶端以及服務(wù)端保持一個(gè)長連接,服務(wù)端能夠主動(dòng)、實(shí)時(shí)向客戶端推送數(shù)據(jù)。另外還拓展了websocket父集socket.io插件的使用,并且在該產(chǎn)品中,主要是使用了該插件來實(shí)現(xiàn)功能。盡管本章只介紹了websocket及相關(guān)技術(shù),但是實(shí)現(xiàn)直播的技術(shù)有很多,我們都可以分別去學(xué)習(xí)并且實(shí)踐。
6用戶信息頁面用戶信息頁面主要包含了用戶的昵稱/身份顯示、收益顯示等,收益還提供提現(xiàn)功能,由于不是主要功能,在這里不詳談。主要頁面樣式如下圖所示:圖6.1用戶信息頁面展示6.1個(gè)人信息編輯頁面該頁面主要是簡單的昵稱、微信號(hào)、電話號(hào)、頭像的修改界面。在開發(fā)過程中,該頁面與后臺(tái)數(shù)據(jù)庫之間的信息交換主要是通過axios實(shí)現(xiàn),與此同時(shí),在傳遞數(shù)據(jù)較多時(shí),為了代碼的簡便性以及方便性,就會(huì)使用FormData對(duì)象發(fā)送數(shù)據(jù)。其中頭像的更換功能的實(shí)現(xiàn)思路主要是將用于置放頭像的div的click事件與隱藏的input(type=file)標(biāo)簽的click相互綁定。當(dāng)監(jiān)聽到input標(biāo)簽的change事件時(shí),就讀取input標(biāo)簽的文件用于更換div中顯示的圖片并且在點(diǎn)擊提交按鈕的時(shí)候?qū)D片文件傳給后臺(tái)更換。該頁面樣式如下圖所示:圖6.2修改信息頁面6.2管理欄管理欄主要分為推廣管理、會(huì)員管理、學(xué)習(xí)管理,這些icon點(diǎn)開的頁面都是一些個(gè)人積分、活動(dòng)介紹的信息或是跳轉(zhuǎn)至第三方頁面。在單獨(dú)的這些頁面里面,我們可以查詢自己的積分或是團(tuán)隊(duì)收益,也可以了解到升級(jí)會(huì)員的各項(xiàng)權(quán)益?;谠摬糠侄际侵貜?fù)性的組件搭建以及樣式調(diào)試,在此就不再詳述。6.3提現(xiàn)欄提現(xiàn)欄是供用戶將自己名下的金額提現(xiàn)到支付寶的操作。提現(xiàn)頁面內(nèi)的提現(xiàn)總額是通過頁面初始化時(shí)調(diào)取接口的返回值顯示(下圖為初始用戶無可提現(xiàn)金額)。當(dāng)用戶填寫了提現(xiàn)金額以及收款方實(shí)名后,點(diǎn)擊按鈕前端會(huì)將兩個(gè)輸入框內(nèi)的數(shù)據(jù)傳遞給后臺(tái)操作。提現(xiàn)頁面樣式如下圖:圖6.3提現(xiàn)申請(qǐng)頁面6.4本章小結(jié)本章主要是展示了用戶信息頁面的各個(gè)模塊,大部分都是頁面樣式方面的工作,個(gè)別需要與后臺(tái)交互,獲取到后臺(tái)接口的信息在頁面顯示,這個(gè)時(shí)候就運(yùn)用到了axios(基于ajax封裝的方法)來獲取接口的數(shù)據(jù)來在頁面進(jìn)行實(shí)時(shí)更新。
7問題總結(jié)7.1頁面兼容性在前端編程方面,頁面兼容性方面的問題是不可避免的。最淺顯的就比如在不同的分辨率設(shè)備上頁面的顯示是否完全、頁面排布是否仍然一致,又或是在ios設(shè)備、android設(shè)備上頁面的顯示是否一致。這個(gè)時(shí)候就涉及到要將頁面設(shè)計(jì)成響應(yīng)式才可以做到兼容。7.1.1頁面顯示方面在這里就簡單闡述一下響應(yīng)式頁面的實(shí)現(xiàn)。在開發(fā)過程中主要是在css樣式方面做工作。在頁面布局上,我所用的響應(yīng)式實(shí)現(xiàn)方式主要是以下兩種:(1)使用vw、vh、em等百分比長度單位;(2)使用@media(媒體查詢):使用媒體查詢,可以針對(duì)不同大小、不同分辨率的屏幕定義不同的樣式,在刷新瀏覽器重置的過程中,頁面會(huì)自動(dòng)根據(jù)瀏覽器的寬高進(jìn)行新一輪的渲染。如下代碼所示:@media(min-width:1024px){//當(dāng)屏幕分辨率不小于1024px時(shí).cover{width:100%;height:110px;}.coverimg{width:100%;height:110px;border-radius:5px;border-bottom-right-radius:0;border-bottom-left-radius:0;}}7.1.2js事件兼容方面由于每個(gè)瀏覽器使用的內(nèi)核不同,所以js使用的事件觸發(fā)有時(shí)候也不同。特別是IE瀏覽器與其他的瀏覽器之間有一些差異是需要寫一些兼容性的代碼去解決的。舉例說在產(chǎn)生事件的源上,IE是用event.srcElement,在火狐下是用e.target。如下代碼部分所示:varevent=window.event||e;varsrcElement=event.srcElement||event.target;如此一來,獲得的srcElement就是同時(shí)在IE以及火狐瀏覽器下的事件源。7.2頁面性能不僅僅是兼容性,頁面性能也是前端工作很需要注重的一個(gè)方面。性能主要就是用戶的體驗(yàn)性,體現(xiàn)在頁面始加載時(shí)是否會(huì)白屏、頁面加載資源(圖片、音樂等)是否會(huì)卡頓等方面。能夠優(yōu)化頁面性能的方法有很多:(1)代碼規(guī)范方面,如將js代碼放在最后面防止頁面加載時(shí)阻塞、盡量不要使用css表達(dá)式等;(2)使用的圖片等資源質(zhì)量盡量不要太大;(3)將頁面的一些較大的資源緩存起來,使得下次進(jìn)入頁面的時(shí)候不需要再次請(qǐng)求該資源,能夠在頁面緩存中直接讀取數(shù)據(jù)在頁面中顯示。在緩存方面,用到的技術(shù)主要是cookie以及webstorage這兩個(gè)。而webstorage比起cookie的主要優(yōu)勢(shì)在于webstorage的存儲(chǔ)量大、存儲(chǔ)時(shí)間長以及有許多豐富易用的接口,比如setItem、getItem、removeItem一類。7.3bug記錄在開發(fā)過程中,難免會(huì)遇到許多問題,在這里,主要列舉以下幾個(gè)較為印象鮮明的bug:(1)在信息填寫頁面中,眾所周知,在手機(jī)app端,點(diǎn)擊輸入框底部是會(huì) 自動(dòng)彈出鍵盤界面的,而鍵盤界面并不屬于視窗范圍內(nèi),所以這個(gè)時(shí)候視窗 的高度是會(huì)減小的。而在開發(fā)過程中,由于沒有意識(shí)到這個(gè)問題,設(shè)置了底部按鈕fixed在頁面底部的話,就會(huì)在鍵盤彈起的時(shí)候,將底部按鈕也頂在鍵盤上方,就會(huì)使得頁面布局混亂,不夠美觀。解決辦法就是利用第一點(diǎn)闡述過的使用媒體查詢方法來使得視窗高度發(fā)生變化的時(shí)候能夠監(jiān)聽到,然后改變頁面的布局,其實(shí)也算是響應(yīng)式布局的一方面。解決代碼如下所示:Html代碼:<inputtype="text"className={style.inputBox}onChange={this.handleName}onFocus={this.hideKeyBoard}onBlur={this.showKeyBoard}/>Typescript代碼:fixBackContentEmpty(){setTimeout(()=>{window.scrollTo(0,1);},100);}showKeyBoard(){console.log('showKeyBoard');if(isPC)return;this.setState({keyboardShow:true},()=>{fixBackContentEmpty();});}hideKeyBoard(){console.log('hideKeyBoard');if(isPC)return;this.setState({keyboardShow:false});}(2)在電腦端打開直播頁面點(diǎn)擊“開始錄制”按鈕之后,啟動(dòng)攝像頭,但是在當(dāng)前頁面返回別的頁面的時(shí)候,攝像頭沒有關(guān)閉,仍然處于開啟的狀態(tài),解決方法如下://該方法在組件將要卸載時(shí)觸發(fā)componentWillUnmount(){MediaStreamTtotype.stop();}7.4本章小結(jié)本章主要介紹了一些在前端開發(fā)方面需要注意的兼容性以及性能的影響,并且記錄了幾個(gè)在開發(fā)過程中所遇見的bug,希望能給閱讀本文的讀者一些啟發(fā)。
參考文獻(xiàn)高湧.微課現(xiàn)狀分析——以南京曉莊學(xué)院為例[D].南京:南京曉莊學(xué)院, 2018.荔枝微課.百度百科[DB/OL]./item/%E8%8D%9 4%E6%9E%9D%E5%BE%AE%E8%AF%BE/22422586?fr=aladdin,2019-05-01.千聊.百度百科[DB/OL]./item/%E5%8D%83%E8% 81%8A/19739109?fr=aladdin,2019-05-01.Vscode.百度百科[DB/OL]./item/visual%20studio%20c ode/17514281,2019-05-01.Websocket.百度百科[DB/OL]./item/WebSocket/1953 845?fr=aladdin,2019-05-02.靜默虛空.Websocket詳解教程[DB/OL]./jingmoxu kong/p/7755643.html,2019-05-02.funnycoderstar.React中組件通信的幾種方式[DB/OL].https://segmentfault.c om/a/1190000012361461?utm_source=tag-newest,2019-05-02.JunChow520.Socket.io-簡書[DB/OL]./p/4e80b931 cdea,2019-05-03.PimentelV,NickersonBG.Communicatinganddisplayingreal-time dat awithwebsocket[J].IEEEInternetComputing,2012,16(4):45- 53.FetteI,MelnikovA.Thewebsocketprotocol[R].2011.
致謝本設(shè)計(jì)(論文)是在我的指導(dǎo)老師兼班主任李光平老師的親切關(guān)懷和悉心指導(dǎo)下完成的。他嚴(yán)肅的科學(xué)態(tài)度、嚴(yán)謹(jǐn)?shù)闹螌W(xué)精神、精益求精的工作作風(fēng),深深地感染和激勵(lì)著我。從題目的選擇到最終完成,老師都始終給予我細(xì)心的指導(dǎo)和不懈的支持。大學(xué)生涯最重要的兩年,我遇到了李光平老師,您治學(xué)嚴(yán)謹(jǐn),學(xué)識(shí)淵博,對(duì)每一個(gè)學(xué)生都盡心盡力的去教導(dǎo),在我們即將邁進(jìn)社會(huì)之際給予了我們非常大的幫助,為我們營造了一種良好的精神氛圍。授人以魚不如授人以漁,置身其間,耳濡目染,潛移默化,使我接受了全新的思想觀念,樹立了宏偉的學(xué)術(shù)目標(biāo),領(lǐng)會(huì)了基本的思考方式。四年的大學(xué)生涯即將畫上一個(gè)句號(hào),但對(duì)于我來說只是人生的一個(gè)逗號(hào),我將帶著四年里在大學(xué)學(xué)到的知識(shí)踏入社會(huì),開啟新的征程。感謝大學(xué)里的每一位同學(xué),謝謝你們一直以來給我的支持和鼓勵(lì),讓我的大學(xué)生活變得豐富多彩,從你們每個(gè)人的身上,我都學(xué)習(xí)了很多東西。最后,感謝陪同我走了四年的信息工程學(xué)院。特別感謝在百忙之中審閱我論文的專家教授和參加答辯的各位老師,請(qǐng)?jiān)试S我在這里向你們致以最真誠的祝福。附錄試聽功能部分代碼如下:componentDidMount(){this.fetchChannelInfo();this.fetchProductConfig();fixBackContentEmpty();}componentWillUnmount(){this.setState({initialized:false});window.removeEventListener('scroll',this.initTabScroll);}hasFreeLecture(lectures:LectureModel[]){constfreeLectureList:LectureModel[]=[];if(lectures){lectures.map((lecture)=>{if(lecture.lecture_type==='open_lecture'&&lecture.lecture_mode!=='video'){freeLectureList.push(lecture);}});}this.setState({isAnyFree:freeLectureList.length>0,freeLectureList:freeLectureList});}toggleAudioSwitch(){console.log('switch',this.state.audioSwitch);this.setState((state:State)=>({audioSwitch:!state.audioSwitch}));}toggleAudioListDisplay(){console.log('audiolist',this.state.audioListDisplay);this.setState((state:State)=>({audioListDisplay:!state.audioListDisplay}));}closeAudioList(){this.setState({audioListDisplay:false});}setChannelAudio(id:number,mode:string){this.setState({audioId:id,audioMode:mode},()=>{console.log('更新音頻',this.state.audioId,this.state.audioMode);});}fetchChannelInfo(){lettoken=getToken();axios.get(`${Config.WK_BASE_URL}/api/channel/${this.state.id}/info`,{data:{isReset:true,isCancelLoading:true},params:{token}}).then((res)=>{const{channel,lectures,role,channel_access,stats_info,share_info}=res.data.data;setDocumentTitle();letchannelInfo:ChannelModel={...channel,is_manager:role.is_manager,is_liveroom_vip:role.is_liveroom_vip,granted:channel_access.granted,popular:stats_info.popular};letlectureList:LectureModel[]=lectures;this.hasFreeLecture(lectureList);lettab=channel_access.granted?1:0;this.setState({initialized:true,channelInfo,lectureList,tab,shareInfo:share_info},()=>{window.addEventListener('scroll',this.initTabScroll);});});}fetchProductConfig(){axios.get(`/index/product_config`,{data:{isCancelLoading:true},params:{product_type:'channel',product_id:this.state.id}}).then((res)=>{const{dist_money,share_url}=res.data.data;this.setState({dist_money,share_url});});}toggleShareMask(){this.setState({showShareMask:!this.state.showShareMask});}toggleTab(tab:number){this.setState({tab});}initTabScroll(){lettabElem=document.querySelector('.'+style.normalTab);if(tabElem&&document&&document.documentElement){this.tabOffsetTop=this.tabOffsetTop>0?this.tabOffsetTop:tabElem.getBoundingClientRect().top;letscrollTop=document.body.scrollTop||document.documentElement.scrollTop;if(scrollTop>this.tabOffsetTop+20){this.setState({isToTop:true});}else{this.setState({isToTop:false});}}}setGranted(){let{channelInfo}=this.state;channelInfo.granted=true;this.setState({channelInfo});}render(){const{tab,channelInfo,shareInfo,showShareMask}=this.state;consttabCls=this.state.isToTop?classNames(style.normalTab,style.normalTabFix):style.normalTab;constshareCls=this.state.isToTop?style.shareFix:style.shareNormal;if(!this.state.initialized){return<Loadingtype="center"/>;}return(<AccountContext.Consumer>{(value)=>(<divclassName={style.page}><Shareaccount={value.account}unsetUrl={true}shareInfo={{title:shareInfo.share_title,desc:shareInfo.share_description,img:shareInfo.share_icon,type:shareInfo.share_type,url:this.state.share_url,dataU
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 系統(tǒng)容錯(cuò)設(shè)計(jì)思路
- 世界名曲解讀課程
- 求職簡歷制作指導(dǎo)模板
- 二零二五版房產(chǎn)抵押購銷與房地產(chǎn)項(xiàng)目運(yùn)營管理合同3篇
- 二零二五年度旅游產(chǎn)品居間服務(wù)合同2篇
- 二零二五年度生物降解材料研發(fā)合作協(xié)議3篇
- 二零二五版兼職研發(fā)人員技術(shù)成果保密合同3篇
- 雅安職業(yè)技術(shù)學(xué)院《Python語言》2023-2024學(xué)年第一學(xué)期期末試卷
- 二零二五版公司向個(gè)人提供藝術(shù)品購買借款合同3篇
- 二零二五年度房地產(chǎn)法律法規(guī)咨詢居間服務(wù)合同6篇
- 細(xì)胞庫建設(shè)與標(biāo)準(zhǔn)制定-洞察分析
- 2024年國家公務(wù)員錄用考試公共基礎(chǔ)知識(shí)復(fù)習(xí)題庫2500題及答案
- DB3309T 98-2023 登步黃金瓜生產(chǎn)技術(shù)規(guī)程
- DBJ41-T 108-2011 鋼絲網(wǎng)架水泥膨脹珍珠巖夾芯板隔墻應(yīng)用技術(shù)規(guī)程
- 2025年學(xué)長引領(lǐng)的讀書會(huì)定期活動(dòng)合同
- 表內(nèi)乘除法口算l練習(xí)題1200道a4打印
- 《EICC培訓(xùn)講義》課件
- 2025年四川省政府直屬事業(yè)單位招聘管理單位筆試遴選500模擬題附帶答案詳解
- 2024年物業(yè)公司服務(wù)質(zhì)量保證合同條款
- 文言文閱讀之理解實(shí)詞含義(講義)-2025年中考語文專項(xiàng)復(fù)習(xí)
- JCT587-2012 玻璃纖維纏繞增強(qiáng)熱固性樹脂耐腐蝕立式貯罐
評(píng)論
0/150
提交評(píng)論