首頁

視頻的傳輸方式【轉(zhuǎn)】

前端達人

概述

搜索“視頻傳輸協(xié)議”,一般會搜出來RTP,RTSP,UDP等等。光看這些協(xié)議,可能有些人會覺得奇怪為什么要把udp也往上放一起,rtp不是可以基于udp?!同時,很多文章主要去講解各個協(xié)議之間的差異,而沒有從更為宏觀的角度來考慮。本文將結(jié)合OSI的分層思路,將不同協(xié)議之間的關系都梳理清楚;同時也從視頻傳輸與組網(wǎng)角度進行介紹。
再者,視頻有很多封裝格式,比如m3u8,mp4等;也有很多音視頻編碼格式,比如h264,h265等,那為何有這么多的封裝格式類型和音視頻編碼格式類型呢?一方面是解決存儲的問題;另一方面是支持不同播放器的解析;但更重要的是不同的傳輸協(xié)議可以支持的音視頻編碼格式有差異,這也是由于不同的應用場景下形成的歷史原因。

1.流媒體

流媒體(streaming media),是指將一連串的媒體數(shù)據(jù)包從服務器端發(fā)送到客戶端,可以實現(xiàn)邊下邊播,此技術使得數(shù)據(jù)包可以像流水一樣發(fā)送。傳統(tǒng)的方式需要在使用前下載整個文件,存儲到本地后才能進行播放;而流媒體只允許下載一小部分(存在視頻關鍵幀)就能進行播放。

流媒體技術不是一種單一的技術,它將網(wǎng)絡技術、音視頻技術還有終端緩存技術等有機地結(jié)合。也就是說,在網(wǎng)絡上要實現(xiàn)流媒體技術,必須要先制作、發(fā)布、傳輸和播放等,這需要服務器端、終端以及網(wǎng)絡都要能支持。當前很多的視頻軟件或者網(wǎng)站都是用到了這種技術。歸結(jié)下來是:

  • 1.內(nèi)容的產(chǎn)生。這里是指將視頻源制作成為可以對外發(fā)布的視頻格式,以及適合在網(wǎng)絡上傳播的分辨率和碼率。這主要用到了視頻的編解碼技術??紤]的輸出參數(shù),如分辨率、碼率、音視頻編碼格式、封裝格式等都需要結(jié)合應用場景和傳輸方式統(tǒng)一考慮。

  • 2.對外發(fā)布。這里主要是指能夠支撐服務器對外輸出視頻資源的技術,常見的有各種流媒體網(wǎng)絡傳輸協(xié)議技術及其需要服務器端支撐的技術。這里的流媒體網(wǎng)絡傳輸協(xié)議比如:

    • HLS
      服務端支持Adobe Flash media server,Nginx,vlc等等。
    • DASH
      服務器端支持Nginx等
    • RTMP
    • Adobe Flash 服務器,Nginx-rtmp
  • 3.組網(wǎng)和傳輸。
    這里的傳輸還得考慮一個概念,是服務器對外主動推數(shù)據(jù),還是等待終端到服務器端拉數(shù)據(jù),這是兩個完全相反的處理方式。對于組播或者廣播的組網(wǎng)方式,往往采用的是服務器主動對外推送數(shù)據(jù);而對于單播來說主要是終端向服務器端主動拉數(shù)據(jù)。

    這里涉及到的IP組網(wǎng)方式中的傳輸類型有:廣播、單播、組播。

    不管是什么類型的組網(wǎng)方式,在傳輸層就有UDP和TCP。下面也將從OSI等層面講講這些底層傳輸協(xié)議之間的關系。

  • 4.視頻播放。這里主要是從終端側(cè)角度說,在不同操作系統(tǒng)中能夠進行播放視頻的播放器,比如vlc等,不同的播放器支持對不同類型的視頻數(shù)據(jù)進行播放。

2.TCP/IP、OSI與視頻傳輸協(xié)議之間的關系

從圖中也可以看到IP層(網(wǎng)絡層)的上層是傳輸層,通過TCP和UDP等方式進行數(shù)據(jù)包的傳輸。
(PS:下圖為網(wǎng)絡中所找https://blog.csdn.net/yaopeng_2005/article/details/7064869)
在這里插入圖片描述
結(jié)合上圖,再補一個wiki上的互聯(lián)網(wǎng)協(xié)議套組圖,一看就更明白了。
在這里插入圖片描述
從上面兩個圖中也可以很清楚地看到,TCP和UDP在接下去的內(nèi)容有很重要的地位,這里也簡單介紹下,深度知識請自行搜索。

  • 1)TCP(Transmission Control Protocol)傳輸控制協(xié)議
    是一種面向連接的、可靠的、基于字節(jié)流的傳輸層協(xié)議。也就是說,它在收發(fā)數(shù)據(jù)之前,必須先和對方建立可靠的連接。有興趣地可以了解TCP的三次握手過程。當TCP檢測到數(shù)據(jù)包丟失時,它將限制其數(shù)據(jù)速率使用率,因此也說TCP是靠譜的,但是對于實時類型的業(yè)務,可能不那么適合。
  • 2)UDP(User Datagram Protocol)用戶數(shù)據(jù)報協(xié)議
    是一種簡單的面向數(shù)據(jù)報的通信協(xié)議。UDP只提供數(shù)據(jù)的不可靠傳遞,它將數(shù)據(jù)發(fā)送出去后,就不保留備份,它僅僅在IP數(shù)據(jù)報的頭部加入了復用和數(shù)據(jù)校驗字段。由于不需要多長校驗,UDP的速度比TCP快,但是有數(shù)據(jù)丟失風險,因此比較適用于實時性要求高的場景,比如實時語音或視頻通話。廣電網(wǎng)絡場景中,以前多用UDP進行傳輸,而且是組播或廣播的方式,這結(jié)合組網(wǎng)能夠?qū)⒘髁砍杀据^大地控制下來。
  • 3)IP層(Internet Protocol)
    IP是網(wǎng)絡層的主要協(xié)議,將根據(jù)源主機和目的主機的地址進行數(shù)據(jù)傳輸。定義了尋址方法和數(shù)據(jù)報的封裝結(jié)構。其最為復雜的就是尋址和路由了。尋址就是將IP地址分配給各個終端節(jié)點,并如何進行劃分和組網(wǎng)。而路由主要是內(nèi)部和外部網(wǎng)關協(xié)議,決定了怎么發(fā)送IP數(shù)據(jù)包。下面提到的組播和廣播等,其實主要是針對IP多播來說的。
  • 4)在不同層之間的數(shù)據(jù)的術語稱呼
    數(shù)據(jù)在TCP層稱為流(Stream),數(shù)據(jù)分組稱為分段(Segment)
    數(shù)據(jù)在IP層稱為Datagram,數(shù)據(jù)分組稱為分片(Fragment)
    在UDP中,分組稱為Message

3.組播、單播和廣播

  • 組播(multicast)
    又稱為多點廣播或群播,或多播,主要是指將信息同時傳遞給一組目的地址。消息在每個網(wǎng)絡鏈路上只需傳遞一次,而且只有在鏈路分叉時,消息才會被復制,使用的效率是最高的。也正是因為這個原因,以前的廣電網(wǎng)絡中,針對直播多采用組播方式,流量的傳輸成本明顯降低很多。

  • 單播:
    其實是組播的一種特殊方式,即常規(guī)的點到點信息傳遞。如果所有傳輸中是以單播的方式傳遞給多個接收方,必須向每個接收者都發(fā)送一份數(shù)據(jù)副本這么多。

  • 廣播
    其實也算是組播的一種特殊方式,就是一對所有的通信方式,對每一臺主機發(fā)出的信號都進行無條件復制并轉(zhuǎn)發(fā),所有的接收點都可以收到所有信息。

注意,組播一般指的是IP組播,常與RTP等音視頻協(xié)議相結(jié)合。雖然組播的設計理念很好,但是它需要對網(wǎng)絡內(nèi)部的狀態(tài)比單播要多得多。實際商用中,組播主要應用在較為簡單的、只有單個源斷的情況,如之前提到廣電網(wǎng)絡內(nèi)部用到的組播方式,UDP組播。

以上是不同類型的IP組播方式,實際在采用中要結(jié)合具體情況進行調(diào)整。比如,如果非要使用廣播,但是采用的場景不合適,也有可能產(chǎn)生廣播風暴。

組播、廣播、單播也介紹了基本的概念,但是他們與視頻傳輸有什么關系呢?

文章上面也提到了,組播是從IP層面的傳輸策略,而所有的視頻傳輸協(xié)議其數(shù)據(jù)包大部分都經(jīng)過UDP和TCP,經(jīng)由IP層進行傳輸?shù)侥康牡?。因此不同的IP傳輸策略與傳輸協(xié)議進行結(jié)合,就能夠落地到具體的應用場景。

同時需要注意的是,采用組播方式可以通過設置網(wǎng)卡為混雜模式或為多播模式,具體也是根據(jù)網(wǎng)卡的特性進行差異處理。如果處理方式不當,比如設置成了廣播,可能會導致在同網(wǎng)絡下,你在播放視頻,然后其他相同網(wǎng)絡下接收端也將有相應的流量,而導致他們的對外服務網(wǎng)口的流量被占滿。

4.視頻傳輸協(xié)議

從下圖中可以看到,標紅色的就是大家經(jīng)常說的視頻傳輸協(xié)議。但是從圖中可以看到他們其實是有基于的關系,比如HLS都是基于HTTP進行傳輸,而HTTP在傳輸層都是依賴tcp數(shù)據(jù)包,再經(jīng)由ip層進行分發(fā)。
在這里插入圖片描述

  • 1)UDP

    • 基于UDP傳輸?shù)囊曨l數(shù)據(jù),比如udp://238.123.45.1:3001,在網(wǎng)絡可達的情況下,即可進行播放??梢圆捎胿lc等播放器進行播放。

    • UDP視頻數(shù)據(jù)傳輸可以采用單播,組播或廣播的方式,具體采用哪種方式根據(jù)具體的組網(wǎng)情況進行控制。

    • 上面也有提到過,廣電網(wǎng)絡中多采用組播的方式進行直播數(shù)據(jù)傳輸,這也是得益于廣電網(wǎng)絡的專網(wǎng)特性以及視頻源輸出可以控制到單一等特性。

    • UDP的組播大部分是采用MPEG TS流,廣電網(wǎng)絡中很多視頻,其視頻編碼格式也大部分是mepg2

  • 2)RTP
    整個RTP協(xié)議包括RTP數(shù)據(jù)協(xié)議和RTP控制協(xié)議(RTCP)。此外,這里也將經(jīng)常一起提的RTSP介紹下。

    • RTP(實時傳輸協(xié)議,Real-time Transport Protocol),是一種網(wǎng)絡傳輸協(xié)議

    • RTP協(xié)議說明了傳遞音頻和視頻的標準數(shù)據(jù)包的格式。最早是作為多播協(xié)議的,后來主要應用在單播中。RTP是創(chuàng)建在UDP協(xié)議之上的,主要應用于流媒體、視頻會議等系統(tǒng)業(yè)務上。

    • RTP為端到端的數(shù)據(jù)傳輸提供了時間信息和流同步,但不保證服務質(zhì)量,而是由服務質(zhì)量由RTCP。
      在RTP的數(shù)據(jù)包封裝中,包含了時間戳、標記位、同步源標識等信息。

    • RTP從上層接收到流媒體的數(shù)據(jù)(如H264),封裝成RTP數(shù)據(jù)包,并將其發(fā)往UDP端口中的偶數(shù)端口。

    • RTCP(實時傳輸控制協(xié)議,Real-time Transport Control Protocol或RTP Control Protocol)

    • RTP的姐妹協(xié)議。RTP使用的是偶數(shù)UDP端口,RTCP采用的是RTP下一個端口,也就是下一個奇數(shù)的端口。RTCP也是基于UDP進行傳輸?shù)摹?

    • RTCP本身不做數(shù)據(jù)傳輸,主要與RTP協(xié)作,將視頻媒體數(shù)據(jù)打包和發(fā)送,并定期在流媒體會話參與者之間傳輸控制數(shù)據(jù),并為RTP提供QoS反饋,簡單點說是主要保證音視頻的同步。

    • RTCP接收到控制信息后,封裝為RTCP控制包,并發(fā)往RTP端口下一個偶數(shù)端口。

    • RTSP(實時流協(xié)議,Real Time Streaming Protocol)
      RTSP是一種網(wǎng)絡應用協(xié)議,主要來創(chuàng)建和控制流媒體服務器與終端之間的會話??刂祁惖恼埱笾饕逿CP協(xié)議。

    • 通過RTSP對流媒體數(shù)據(jù)進行控制和播放,比如進行播放、暫停、快進等操作,它定義了具體的控制消息、操作方法和狀態(tài)碼等。

    • 與RTP、RTCP配合,在廣電網(wǎng)絡內(nèi)部主要應用在點播場景比較多,而直播主要走UDP組播。在互聯(lián)網(wǎng)場景下,也有用于直播和點播的,但是相對來說使用較少。

    • 請求的url為:rtsp://testdomain/test.mp4/streamid=0

    • 需要服務器端和客戶端都能夠支持RTSP的控制。一般客戶端采用vlc即可,而服務器端采用Darwin Streaming Server,ffmpeg等建立流媒體服務。

  • 3)RTMP(實時消息協(xié)議,Real-Time Messaging Protocol)
    包括RTMP、RTMPT等一系列的協(xié)議,Adobe為flash播放器和服務器之間音視頻數(shù)據(jù)傳輸?shù)膮f(xié)議。

    • RTMP
      1)主要基于TCP協(xié)議進行數(shù)據(jù)包傳輸,默認使用1935端口。
      2)服務器端采用Nginx,支持rtmp模塊的即可支持對外rtmp視頻數(shù)據(jù)服務。
      3)支持rtmp模塊,可以支持直播rtmp輸出,也能夠支持hls訪問。
      4)RTMP支持mp4,flv等封裝格式的視頻對外輸出
    • RTMPS
      通過SSL加密的RTMP協(xié)議
    • RTMPE
      RTMPE是一個加密版本的RTMP,和RTMPS不同的是RTMPE不采用SSL加密,RTMPE加密快于SSL,并且不需要認證管理
    • RTMPT
      采用HTTP封裝以穿透防火墻,通常用80和443端口。
    • RTMFP
      使用UDP進行數(shù)據(jù)傳輸

4)HTTP
而基于HTTP協(xié)議的就更多了,如上圖。如果服務器部署了流媒體的服務,如Nginx等,就可以對外提供視頻播放服務了。

這里也需要說明,視頻的播放一般分為點播和直播,有些協(xié)議作為直播的傳輸協(xié)議反而是更好的,比如RTMP,時延就比較低,但RTMP做CDN成本相對較高。CDN支持很好的HTTP如果能支持直播,當前也有很多協(xié)議能支持通過HTTP的方式實現(xiàn)直播流媒體。

5.自適應流媒體

自適性流媒體(adaptive bitrate streaming,ABS)也叫碼流自適應,是流媒體服務器準備各種碼流的視頻流,所有的視頻碼流都是相同時段完全統(tǒng)一圖像的音視頻數(shù)據(jù),客戶端根據(jù)網(wǎng)絡情況和CPU使用情況等進行動態(tài)調(diào)整。

主要有MPEG-DASH、HLS、HDS、MSS等技術方案,這幾個也是上圖中最上層的流媒體傳輸協(xié)議技術。通過這些傳輸協(xié)議封裝的視頻源,可以支持有多種碼率,并支持播放器客戶端在播放時,根據(jù)帶寬情況自動調(diào)整碼率以適應用戶的最佳觀看效果——不卡頓,不重新加載等。

  • 1) DASH(MPEG-DASH)
    MPEG-DASH是基于HTTP的自適應碼流方案中唯一國際標準,它采用TCP傳輸協(xié)議。
  • 2)HLS
    Apple提出的,將.m3u8作為索引文件,分片格式為ts,支持直播和時移。
  • 3)HDS
    采用支持RTMP和HTTP協(xié)議,HTTP協(xié)議類似于HLS,也可以叫漸進式下載。
  • 4)MSS
    是微軟提出的,文件切片格式為mp4,索引文件為ism、ismc,也支持直播和時移。

這里也僅僅對碼流自適應技術做了簡單介紹,由于現(xiàn)在這種技術應用相當廣泛,后面將詳細介紹這種技術。

【說明】
文章轉(zhuǎn)自,華為云社區(qū),作者Higeeon,相關版權解釋權歸原作者所有。https://bbs.huaweicloud.com/blogs/fed3df04b1e011e9b759fa163e330718





藍藍設計建立了UI設計分享群,每天會分享國內(nèi)外的一些優(yōu)秀設計,如果有興趣的話,可以進入一起成長學習,請加微信ban_lanlan,報下信息,藍小助會請您入群。歡迎您加入噢~~

希望得到建議咨詢、商務合作,也請與我們聯(lián)系01063334945。 



分享此文一切功德,皆悉回向給文章原作者及眾讀者. 免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們?nèi)〉寐?lián)系,我們立即更正或刪除。 



藍藍設計sillybuy.com )是一家專注而深入的界面設計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網(wǎng)站建設 、平面設計服務UI設計公司、界面設計公司、UI設計服務公司、數(shù)據(jù)可視化設計公司、UI交互設計公司、高端網(wǎng)站設計公司、UI咨詢、用戶體驗公司、軟件界面設計公司。

JavaScript核心技術之JSON詳解

前端達人

JSON是什么?

JSON(JavaScript Object Notation, JS對象簡譜)是一種輕量級的數(shù)據(jù)交換格式。它基于 ECMAScript(European Computer Manufacturers Association, 歐洲計算機協(xié)會制定的js規(guī)范)的一個子集,采用完全獨立于編程語言的文本格式來存儲和表示數(shù)據(jù)。簡潔和清晰的層次結(jié)構使得 JSON 成為理想的數(shù)據(jù)交換語言。 易于人閱讀和編寫,同時也易于機器解析和生成,并有效地提升網(wǎng)絡傳輸效率。 

JSON源自于JavaScript,是一種輕量級(Light-Meight)、基于文本的(Text-Based)、可讀的(Human-Readable)格式。

在現(xiàn)在的開發(fā)中,能夠進行數(shù)據(jù)交換格式的,包括兩個JSON   XML。

JSON是存儲和交換文本信息的語法,類似 XML,JSON比 XML更小、更快,更易解析。

 那么,簡而言之,對JSON的說明總結(jié)如下:

  • JSON是獨立于任何編程語言的數(shù)據(jù)格式
  • 是一種用于存儲和傳輸數(shù)據(jù)的輕量級格式
  • 語法是自描述的,便于人類閱讀和理解

JSON語法

基本語法:

  • 數(shù)組(Array)用方括號 "[]" 表示
  • 對象(0bject)用大括號 "{}" 表示
  • 名稱 / 值 對(name/value)組合成數(shù)組和對象
  • 名稱( name )置于雙引號中,值(value)有字符串、數(shù)值、布爾值、null、對象和數(shù)組
  • 并列的數(shù)據(jù)之間用逗號 "," 分隔
  • 名稱/值對包括字段名稱(在雙引號中),后面寫一個冒號,然后是值

需要注意的是:

JSON不支持注釋。向 JSON添加注釋無效

JSON文件的文件類型是 .json

JSON文本的 MIME 類型是 application/json

獲取JSON數(shù)據(jù)

 json是以對象的形式存在的,直接獲取JSON數(shù)據(jù)可通過如下方法:

1. json對象.鍵名

2. json對象["鍵名"]

3. 數(shù)組對象[索引]

4. 遍歷 

代碼示例:


  1. //定義基本格式
  2. var person = { name: "張三", age: 23, gender: true };
  3. var persons = [
  4. { name: "張三", age: 23, gender: true },
  5. { name: "李四", age: 24, gender: true },
  6. { name: "王五", age: 25, gender: false },
  7. ];
  8. //獲取person對象中所有的鍵和值
  9. //for in 循環(huán)
  10. /* for(var key in person){
  11. //這樣的方式獲取不行。因為相當于 person."name"
  12. //alert(key + ":" + person.key);
  13. alert(key+":"+person[key]);
  14. }*/
  15. //獲取persons中的所有值
  16. for (var i = 0; i < persons.length; i++) {
  17. var p = persons[i];
  18. for (var key in p) {
  19. console.log(key + ":" + p[key]);
  20. }
  21. }

 輸出結(jié)果為:

 JSON 解析與序列化(在JavaScript中)

先在控制臺中打印一下JSON對象,看看有什么,如圖:

 顯而易見,在JavaScript中JSON對象僅有兩個方法:parse和stringify。后面會詳細介紹一下這兩個方法

序列化的概念:序列化是將對象轉(zhuǎn)化為字節(jié)序列的過程。對象序列化后可以在網(wǎng)絡上傳輸,或者保存到硬盤上。

將對象序列化成json字符串: JSON.stringify(json對象);

反序列化:將json字符串反序列化為對象:   JSON.parse(str)

JSON.parse

API介紹:用來解析 JSON字符串,構造由字符串描述的 JavaScript 值或?qū)ο螅瑐魅氲淖址环?nbsp;JSON規(guī)范會報錯

語法:

JSON.parse(str, reviver);
  • str:要解析的 JSON字符串
  • reviver:可選的函數(shù) function(key,value),該函數(shù)的第一個參數(shù)和第二個參數(shù)分別代表鍵值對的鍵和值,并可以對值進行轉(zhuǎn)換(函數(shù)返回值當做處理后的value)

代碼示例:


  1. // JSON.parse() 解析JSON字符串, 將JSON轉(zhuǎn)換為對象
  2. let json = '{"name": ["js", "webpack"], "age": 22, "gridFriend": "ljj"}';
  3. console.log(JSON.parse(json));
  4. // {name: Array(2), age: 22, gridFriend: 'ljj'}
  5. // 第二個參數(shù)是一個函數(shù),key和value代表每個key/value對
  6. let result = JSON.parse(json, (key, value) => {
  7. if (key == "age") {
  8. return `年齡:${value}`;
  9. }
  10. return value;
  11. });
  12. console.log(result);
  13. //{name: Array(2), age: '年齡:22', gridFriend: 'ljj'}

 JSON.stringify

API介紹:將一個 JavaScript 對象或值轉(zhuǎn)換為 JSON字符串

如果指定了一個 replacer 函數(shù),則可以選擇性地替換值,或者指定的 replacer 是數(shù)組,則可選擇性地僅包含數(shù)組指定的屬性

語法:

JSON.stringify(value, replacer, space)

value:將要序列化成 一個 JSON 字符串的值

replacer:

  • 如果該參數(shù)是一個函數(shù),則在序列化過程中,被序列化的值的每個屬性都會經(jīng)過該函數(shù)的轉(zhuǎn)換和處理
  • 如果該參數(shù)是一個數(shù)組,則只有包含在這個數(shù)組中的屬性名才會被序列化到最終的 JSON 字符串中
  • 如果該參數(shù)為 null 或者未提供,則對象所有的屬性都會被序列化

space:指定縮進用的空白字符串,用于美化輸出

  • 如果參數(shù)是個數(shù)字,它代表有多少的空格;上限為10。該值若小于1,則意味著沒有空格
  • 如果該參數(shù)為字符串(當字符串長度超過10個字母,取其前10個字母),該字符串將被作為空格
  • 如果該參數(shù)沒有提供(或者為 null),將沒有空格

代碼示例:


  1. let obj = {
  2. name: "jsx",
  3. age: 22,
  4. lesson: ["html", "css", "js"],
  5. };
  6. let json = JSON.stringify(obj);
  7. console.log(json);
  8. // {"name":"jsx","age":22,"lesson":["html","css","js"]}
  9. // 第二個參數(shù)replacer 為函數(shù)時,被序列化的值得屬性都會經(jīng)過該函數(shù)轉(zhuǎn)換處理
  10. function replacer(key, value) {
  11. if (typeof value === "string") {
  12. return undefined;
  13. }
  14. return value;
  15. }
  16. let result = JSON.stringify(obj, replacer);
  17. console.log(result);
  18. // {"age":22,"lesson":[null,null,null]}
  19. // 當replacer參數(shù)為數(shù)組,數(shù)組的值代表將被序列化成 JSON 字符串的屬性名
  20. let result1 = JSON.stringify(obj, ["name", "lesson"]);
  21. // 只保留 “name” 和 “l(fā)esson” 屬性值
  22. console.log(result1);
  23. // {"name":"jsx","lesson":["html","css","js"]}
  24. // 第三個參數(shù)spcae,用來控制結(jié)果字符串里面的間距
  25. let result2 = JSON.stringify(obj, null, 4);
  26. console.log(result2);
  27. /*{
  28. "name": "jsx",
  29. "age": 22,
  30. "lesson": [
  31. "html",
  32. "css",
  33. "js"
  34. ]
  35. }*/

 注意:如果replacer是一個函數(shù),則該函數(shù)會進行深處理,即如果鍵值對的值也是一個數(shù)組,則也會執(zhí)行該函數(shù)

JSON.stringify()原理

  • 轉(zhuǎn)換值如果有 toJSON() 方法,該方法定義什么值將被序列化
  • 非數(shù)組對象的屬性不能保證以特定的順序出現(xiàn)在序列化后的字符串中
  • 布爾值、數(shù)字、字符串的包裝對象在序列化過程中會自動轉(zhuǎn)換成對應的原始值,undefined、任意的函數(shù)以及 symbol 值,在序列化過程中會被忽略(出現(xiàn)在非數(shù)組對象的屬性值中時)或者被轉(zhuǎn)換成 null(出現(xiàn)在數(shù)組中時)。函數(shù)、undefined 被單獨轉(zhuǎn)換時,會返回 undefined,如JSON.stringify(function(){}) or JSON.stringify(undefined)
  • 對包含循環(huán)引用的對象(對象之間相互引用,形成無限循環(huán))執(zhí)行此方法,會拋出錯誤
  • 所有以 symbol 為屬性鍵的屬性都會被完全忽略掉,即便 replacer 參數(shù)中強制指定包含了它們
  • Date 日期調(diào)用了 toJSON() 將其轉(zhuǎn)換為了 string 字符串(同Date.toISOString()),因此會被當做字符串處理
  • NaN 和 Infinity 格式的數(shù)值及 null 都會被當做 null
  • 其他類型的對象,包括 Map/Set/WeakMap/WeakSet,僅會序列化可枚舉的屬性


藍藍設計建立了UI設計分享群,每天會分享國內(nèi)外的一些優(yōu)秀設計,如果有興趣的話,可以進入一起成長學習,請加微信ban_lanlan,報下信息,藍小助會請您入群。歡迎您加入噢~~
希望得到建議咨詢、商務合作,也請與我們聯(lián)系01063334945。 

分享此文一切功德,皆悉回向給文章原作者及眾讀者. 免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們?nèi)〉寐?lián)系,我們立即更正或刪除。 

藍藍設計sillybuy.com )是一家專注而深入的界面設計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網(wǎng)站建設 、平面設計服務、UI設計公司、界面設計公司、UI設計服務公司、數(shù)據(jù)可視化設計公司、UI交互設計公司、高端網(wǎng)站設計公司、UI咨詢、用戶體驗公司、軟件界面設計公司。

get請求和post請求的區(qū)別(全面講解)

前端達人

1.get請求一般是去取獲取數(shù)據(jù)(其實也可以提交,但常見的是獲取數(shù)據(jù));
post請求一般是去提交數(shù)據(jù)。

2.get因為參數(shù)會放在url中,所以隱私性,安全性較差,請求的數(shù)據(jù)長度是有限制的,
不同的瀏覽器和服務器不同,一般限制在 2~8K 之間,更加常見的是 1k 以內(nèi);
post請求是沒有的長度限制,請求數(shù)據(jù)是放在body中;

3.get請求刷新服務器或者回退沒有影響,post請求回退時會重新提交數(shù)據(jù)請求。

4.get請求可以被緩存,post請求不會被緩存。

5.get請求會被保存在瀏覽器歷史記錄當中,post不會。get請求可以被收藏為書簽,因為參數(shù)就是url中,但post不能。它的參數(shù)不在url中。

6.get請求只能進行url編碼(appliacation-x-www-form-urlencoded),post請求支持多種(multipart/form-data等)。

深入理解
1…GET 和 POST都是http請求方式, 底層都是 TCP/IP協(xié)議;通常GET 產(chǎn)生一個 TCP 數(shù)據(jù)包;POST 產(chǎn)生兩個 TCP 數(shù)據(jù)包(但firefox是發(fā)送一個數(shù)據(jù)包),

2.對于 GET 方式的請求,瀏覽器會把 http header 和 data 一并發(fā)送出去,服務器響應 200
(返回數(shù)據(jù))表示成功;

而對于 POST,瀏覽器先發(fā)送 header,服務器響應 100, 瀏覽器再繼續(xù)發(fā)送 data,服
務器響應 200 (返回數(shù)據(jù))。





藍藍設計建立了UI設計分享群,每天會分享國內(nèi)外的一些優(yōu)秀設計,如果有興趣的話,可以進入一起成長學習,請加微信ban_lanlan,報下信息,藍小助會請您入群。歡迎您加入噢~~

希望得到建議咨詢、商務合作,也請與我們聯(lián)系01063334945。 



分享此文一切功德,皆悉回向給文章原作者及眾讀者. 免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們?nèi)〉寐?lián)系,我們立即更正或刪除。 



藍藍設計sillybuy.com )是一家專注而深入的界面設計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網(wǎng)站建設 、平面設計服務、UI設計公司、界面設計公司、UI設計服務公司、數(shù)據(jù)可視化設計公司、UI交互設計公司、高端網(wǎng)站設計公司、UI咨詢、用戶體驗公司、軟件界面設計公司。

【uni-app】響應式單位rpx

前端達人

單位

rpx是響應式px
rpx是一種根據(jù)屏幕寬度自適應的動態(tài)單位。以750寬的屏幕為基準,750rpx正好是屏幕的寬度。屏幕變寬,rpx實際顯示效果會等比放大,但在App端和h5端,屏幕寬度達到960px時,默認將按照375px的屏幕寬度進行計算。在開發(fā)移動端項目時選擇rpx作為尺寸單位。
uni-app在App端,H5端和小程序都支持rpx,并且可以配置不同屏幕寬度的計算方式。

頁面元素在uni-app的寬度計算公式如下:
750 * 元素在設計稿中的寬度 / 設計稿基準寬度

舉例說明:

  1. 若設計稿寬度為750px,元素A在設計稿上的寬度為100rpx, 那么元素A在uni-app中的寬度應該設計為750 * 100/750,即100rpx
  2. 若設計稿寬度為640px,元素A在設計稿上的寬度為100rpx, 那么元素A在uni-app中的寬度應該設計為750 * 100/640,即117rpx
  3. 若設計稿寬度為375px,元素A在設計稿上的寬度為200rpx, 那么元素A在uni-app中的寬度應該設計為750 * 200/375,即117rpx

但是要注意的是

  1. 不要對響應式單位依賴太嚴重了,比如組件高度或字體大小也使用rpx。只有當你需要某元素的單位要根據(jù)屏幕寬度大小變化時,才需要rpx這類動態(tài)寬度單位。
  2. 一般情況下高度和字體大小是不應該根據(jù)屏幕寬度變化的,除非你的字體大小想根據(jù)屏幕寬度變化。
  3. rpx不支持動態(tài)橫豎屏切換計算,使用rpx建議鎖定屏幕方向

拓展:在設置文件mainfest.json里開啟px轉(zhuǎn)rpx(默認關閉),所有的px可一鍵轉(zhuǎn)換為rpx

“transformPx”:false  
        
  • 1

rpx直接支持動態(tài)綁定

<view class="test" :style="{width:winWidth + 'rpx;'}"></view> 
        
 
        
  • 1


藍藍設計建立了UI設計分享群,每天會分享國內(nèi)外的一些優(yōu)秀設計,如果有興趣的話,可以進入一起成長學習,請加微信ban_lanlan,報下信息,藍小助會請您入群。歡迎您加入噢~~
希望得到建議咨詢、商務合作,也請與我們聯(lián)系01063334945。 

分享此文一切功德,皆悉回向給文章原作者及眾讀者. 免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們?nèi)〉寐?lián)系,我們立即更正或刪除。 

藍藍設計sillybuy.com )是一家專注而深入的界面設計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網(wǎng)站建設 、平面設計服務UI設計公司、界面設計公司、UI設計服務公司、數(shù)據(jù)可視化設計公司、UI交互設計公司、高端網(wǎng)站設計公司、UI咨詢、用戶體驗公司、軟件界面設計公司。

Vue跨域解決方法

前端達人

vue項目中,前端與后臺進行數(shù)據(jù)請求或者提交的時候,如果后臺沒有設置跨域,前端本地調(diào)試代碼的時候就會報“No 'Access-Control-Allow-Origin' header is present on the requested resource.” 這種跨域錯誤。

要想本地正常的調(diào)試,解決的辦法有三個

一、后臺更改header

header('Access-Control-Allow-Origin:*');//允許所有來源訪問
header('Access-Control-Allow-Method:POST,GET');//允許訪問的方式

這樣就可以跨域請求數(shù)據(jù)了

二、使用JQuery提供的jsonp (注:vue中引入jquery,自行百度)

methods: {
getData () {
var self = this
$.ajax({
url: 'http://f.apiplus.cn/bj11x5.json',
type: 'GET',
dataType: 'JSONP',
success: function (res) {
self.data = res.data.slice(0, 3)
self.opencode = res.data[0].opencode.split(',')
}
})
}
}

通過這種方法也可以解決跨域的問題。

三、使用http-proxy-middleware 代理解決(項目使用vue-cli腳手架搭建)

例如請求的url:“/business/remind/user”
1、打開vue.config.js.js,在proxy中添寫如下代碼:

// 運行配置
devServer: {
port: '9527', //代理端口
open: false, //項目啟動時是否自動打開瀏覽器,我這里設置為false,不打開,true表示打開
proxy: {
'/api': {
target: process.env.VUE_APP_HTTP_URL,
changeOrigin: true, //是否跨域
pathRewrite: { //重寫路徑
'^/api': '/' // 或 者 'http://localhost:8080/api'
}
// 既然我們設置了代理,則所有請求url都已寫成/api/xxx/xxx,那請求如何知道我們到底請求的是哪個服務器的數(shù)據(jù)呢
// 因此這里的意義在于, 以 /api開頭的url請求,代理都會知道實際上應該請求那里,
// ‘我是服務器/api’,后面的/api根據(jù)實際請求地址決定,即我的請求url:/api/test/test,被代理后請求的則是
// https://我是服務器/api/test/test
}
}
},

附帶vue.config.js下的代碼

const chalk = require('chalk')
const path = require('path');
function resolve (dir) {
return path.join(__dirname, dir)

}
module.exports = {
// 沒有書寫outputDir屬性 默認'dist' 對應dev.assetsSubDirectory
outputDir: 'dist',
// https://vuejs.org/v2/guide/installation.html#Runtime-Compiler-vs-Runtime-only
// compiler: false,
//在vue-cli.3.3版本后 baseUrl被廢除了,因此這邊要寫成 publicPath ( 資源地址 )
publicPath: process.env.NODE_ENV === 'production' ? process.env.VUE_APP_PUBLICPATH : '/' ,
// css相關配置
css: {
// 是否使用css分離插件 ExtractTextPlugin
extract: true,
// 開啟 CSS source maps?
sourceMap: false,
// css預設器配置項
loaderOptions: {}
// 啟用 CSS modules for all css / pre-processor files.
// modules: false
},
// 運行配置
devServer: {
port: '8222', //代理端口
open: false, //項目啟動時是否自動打開瀏覽器,我這里設置為false,不打開,true表示打開
proxy: {
'/api': {
target: process.env.VUE_APP_HTTP_URL,
changeOrigin: true, //是否跨域
pathRewrite: { //重寫路徑
'^/api': '/' // 或 者 'http://localhost:8080/api'
}
// 既然我們設置了代理,則所有請求url都已寫成/api/xxx/xxx,那請求如何知道我們到底請求的是哪個服務器的數(shù)據(jù)呢
// 因此這里的意義在于, 以 /api開頭的url請求,代理都會知道實際上應該請求那里,
// ‘我是服務器/api’,后面的/api根據(jù)實際請求地址決定,即我的請求url:/api/test/test,被代理后請求的則是
// https://我是服務器/api/test/test
}
}
},
chainWebpack: config => {
// 提示輸出的哪個地址
console.log(chalk.blueBright('\n\n running ' + process.env.VUE_APP_PROJ_NAME + ' : ') +
chalk.yellowBright(process.env.VUE_APP_HTTP_URL + ' please wait... \n'));
// 判斷不同環(huán)境 做相應處理
if(process.env.NODE_ENV === 'production') {
// 測試生產(chǎn)環(huán)境, 不壓縮js代碼
if (process.env.VUE_APP_TITLE === 'alpha') {
config.optimization.minimize(false)
}
}
//set第一個參數(shù):設置的別名,第二個參數(shù):設置的路徑
config.resolve.alias
.set('@',resolve('./src'))
.set('components',resolve('./src/components'))
.set('assets',resolve('./src/assets'))
.set('views',resolve('./src/views'))
.set('network',resolve('./src/network'))
//注意 store 和 router 沒必要配置

config.plugin('html')
.tap(args => {
args[0].title = '公募綜合業(yè)務平臺'
return args
})
}
}





藍藍設計建立了UI設計分享群,每天會分享國內(nèi)外的一些優(yōu)秀設計,如果有興趣的話,可以進入一起成長學習,請加微信ban_lanlan,報下信息,藍小助會請您入群。歡迎您加入噢~~

希望得到建議咨詢、商務合作,也請與我們聯(lián)系01063334945。 



分享此文一切功德,皆悉回向給文章原作者及眾讀者. 免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們?nèi)〉寐?lián)系,我們立即更正或刪除。 



藍藍設計sillybuy.com )是一家專注而深入的界面設計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網(wǎng)站建設 平面設計服務、UI設計公司、界面設計公司、UI設計服務公司、數(shù)據(jù)可視化設計公司、UI交互設計公司、高端網(wǎng)站設計公司、UI咨詢、用戶體驗公司、軟件界面設計公司。

vue 項目啟動失敗 ‘webpack-dev-server‘ 不是內(nèi)部或外部命令,也不是可運行的程序

前端達人

報錯描述

我使用命令 npm run dev 啟動項目 報了下面的錯。

 'webpack-dev-server' 不是內(nèi)部或外部命令,也不是可運行的程序

> webpack-dev-server --inline --progress --config build/webpack.dev.conf.js

'webpack-dev-server' 不是內(nèi)部或外部命令,也不是可運行的程序
或批處理文件。
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! vue@1.0.0 dev: `webpack-dev-server --inline --progress --config build/webpack.dev.conf.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the vue@1.0.0 dev script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?

npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\lara\AppData\Roaming\npm-cache\_logs\2018-06-12T09_40_42_892Z-debug.log

 什么環(huán)境都是好的,剛使用npm run dev 啟動了一個前端項目都是好的,但是現(xiàn)在這個項目就不行了。

解決步驟:

        第一步:

        刪除項目的node_modules文件夾(當前運行的項目中沒有node_modules 文件夾的直接運行第二步)

        第二步:

        在項目目錄里運行 npm install  命令


 

         第三步:

        在項目目錄里運行npm run build 命令

 

         第四步:

        在項目目錄里運行npm run dev 命令

這樣我就可以成功運行項目了。 


藍藍設計建立了UI設計分享群,每天會分享國內(nèi)外的一些優(yōu)秀設計,如果有興趣的話,可以進入一起成長學習,請加微信ban_lanlan,報下信息,藍小助會請您入群。歡迎您加入噢~~
希望得到建議咨詢、商務合作,也請與我們聯(lián)系01063334945。 

分享此文一切功德,皆悉回向給文章原作者及眾讀者. 免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們?nèi)〉寐?lián)系,我們立即更正或刪除。 

藍藍設計sillybuy.com )是一家專注而深入的界面設計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網(wǎng)站建設 、平面設計服務、UI設計公司、界面設計公司、UI設計服務公司、數(shù)據(jù)可視化設計公司、UI交互設計公司、高端網(wǎng)站設計公司、UI咨詢、用戶體驗公司、軟件界面設計公司。

vuex存儲與本地儲存(localstorage、sessionstorage)的區(qū)別

前端達人

1.區(qū)別:vuex存儲在內(nèi)存,localstorage(本地存儲)則以文件的方式存儲在本地,永久保存(不主動刪除,則一直存在);sessionstorage( 會話存儲 ) ,臨時保存。localStorage和sessionStorage只能存儲字符串類型,對于復雜的對象可以使用ECMAScript提供的JSON對象的stringify和parse來處理

2.應用場景:vuex用于組件之間的傳值,localstorage,sessionstorage則主要用于不同頁面之間的傳值。

3.永久性:當刷新頁面(這里的刷新頁面指的是 --> F5刷新,屬于清除內(nèi)存了)時vuex存儲的值會丟失,sessionstorage頁面關閉后就清除掉了,localstorage不會。

注:大家可能覺得用localstorage可以代替vuex, 對于不變的數(shù)據(jù)確實可以,但是當兩個組件共用一個數(shù)據(jù)源(對象或數(shù)組)時,如果其中一個組件改變了該數(shù)據(jù)源,希望另一個組件響應該變化時,localstorage,sessionstorage無法做到,原因就是區(qū)別1。





vuex是存儲在頁面上的變量,說到底還是個Object,刷新頁面就清空了。而storage是存儲在瀏覽器的,和頁面就無關了,刷新頁面也不會清空




藍藍設計建立了UI設計分享群,每天會分享國內(nèi)外的一些優(yōu)秀設計,如果有興趣的話,可以進入一起成長學習,請加藍小助,微信號:ben_lanlan,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯(lián)系01063334945。


分享此文一切功德,皆悉回向給文章原作者及眾讀者.
免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們?nèi)〉寐?lián)系,我們立即更正或刪除。


藍藍設計sillybuy.com )是一家專注而深入的界面設計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網(wǎng)站建設 、平面設計服務UI設計公司、界面設計公司、UI設計服務公司、數(shù)據(jù)可視化設計公司、UI交互設計公司、高端網(wǎng)站設計公司、UI咨詢、用戶體驗公司、軟件界面設計公司

如何在線Word轉(zhuǎn)成PDF格式

前端達人

我們經(jīng)常會將Word轉(zhuǎn)換成PDF,下面給大家介紹一種很不錯的Word轉(zhuǎn)PDF格式的方式。

打開瀏覽器搜索speedpdf找到并打開在線轉(zhuǎn)換工具首頁,選擇主頁上的Word轉(zhuǎn)PDF進入轉(zhuǎn)換(也可以點擊上方所有工具字樣,選擇Word轉(zhuǎn)PDF進入)。

將需要轉(zhuǎn)換的Word文檔添加上傳后,點擊進度條后面的轉(zhuǎn)換按鈕,就可以開始轉(zhuǎn)換了,等待轉(zhuǎn)換完成后點擊下載箭頭即可。

如果轉(zhuǎn)換前有登錄賬戶,還可以通過點擊登錄頭像處,選擇賬戶,在轉(zhuǎn)換記錄中查看轉(zhuǎn)換狀態(tài)和下載轉(zhuǎn)換后的文檔。




藍藍設計建立了UI設計分享群,每天會分享國內(nèi)外的一些優(yōu)秀設計,如果有興趣的話,可以進入一起成長學習,請加藍小助,微信號:ben_lanlan,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯(lián)系01063334945。


分享此文一切功德,皆悉回向給文章原作者及眾讀者.
免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們?nèi)〉寐?lián)系,我們立即更正或刪除。


藍藍設計sillybuy.com )是一家專注而深入的界面設計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網(wǎng)站建設 、平面設計服務、UI設計公司、界面設計公司、UI設計服務公司、數(shù)據(jù)可視化設計公司、UI交互設計公司、高端網(wǎng)站設計公司、UI咨詢、用戶體驗公司、軟件界面設計公司

【vue2】對路由的理解

藍藍設計的小編

目錄

 一、vue路由概念

1.概念:

2.初體驗:

二、路由基礎

1.路由模式        

2.路由寫法

總結(jié)手動自動配置區(qū)別:

三、路由重定向與二級路

1.路由重定向

2.二級路由

 四、路由跳轉(zhuǎn)傳參

1.聲明式導航:

2.編程式導航


 一、vue路由概念

1.概念:

確保我們在vue中實現(xiàn)頁面跳轉(zhuǎn)到我們所想的頁面

2.初體驗:

88f51af6257443c5aeb88fa4b47a805a.gif

 可以看到當我們點擊不同的組件的時候我們實現(xiàn)了路由的功能:在vue中實現(xiàn)頁面的跳轉(zhuǎn)

注意看,當我點擊的時候上面地址欄中加載了不同的網(wǎng)頁。下面我們來學習下路由的寫法

二、路由基礎

1.路由模式

路由兩種模式

路由書寫寫法:

在index.js中的router對象中書寫


  1. const router = new VueRouter({
  2. mode: 'history',//默認是hash模式
  3. })

hash模式:

路由例如: http://localhost:8080/#/home

history模式:

路由例如: http://localhost:8080/home


兩種模式的區(qū)別:

  1. 外觀:hash的url有個#符號,history沒有,history外觀更好看。
  2. 刷新:hash刷新會加載到地址欄對應的頁面,history刷新瀏覽器會重新發(fā)起請求,如果服務端沒有匹配當前的url,就會出現(xiàn)404頁面。
  3. history模式以后上線需要服務器端支持, 否則找的是文件夾

 2.路由寫法

 起步 | Vue RouterVue Router3官網(wǎng)介紹: 起步 | Vue Router

①手動配置(較少使用)

  1. 下載與導入vue-router
  2. 導入組件
  3. 創(chuàng)建routes路由規(guī)則(路徑和頁面一一對應)
  4. 創(chuàng)建路由對象
  5. 把路由對象掛載到App.vue
  6. 在頁面寫路由導航router-link (生成a標簽)
  7. 在頁面寫路由出口router-view (生成占位盒子,用于顯示頁面內(nèi)容)

下面開始我們相關文件的創(chuàng)建

1.創(chuàng)建我們的腳手架(此時沒有選擇Router):

1d386e264033404e9d2e678b516ac38f.png

 2.準備我們的App.vue文件:


  1. <template>
  2. <div>
  3. <!-- 頂部導航欄 -->
  4. <div class="footer_wrap">
  5. <a href="#/find">發(fā)現(xiàn)音樂</a>
  6. <a href="#/my">我的音樂</a>
  7. <a href="#/friend">朋友</a>
  8. </div>
  9. <!-- 下面內(nèi)容 -->
  10. <div class="top"></div>
  11. </div>
  12. </template>
  13. <script>
  14. export default {
  15. methods: {}
  16. }
  17. </script>
  18. <style scoped>
  19. body,
  20. html {
  21. margin: 0;
  22. padding: 0;
  23. }
  24. .footer_wrap {
  25. position: fixed;
  26. left: 0;
  27. top: 0;
  28. display: flex;
  29. width: 100%;
  30. text-align: center;
  31. background-color: #333;
  32. color: #ccc;
  33. }
  34. .footer_wrap a,
  35. span {
  36. cursor: pointer;
  37. flex: 1;
  38. text-decoration: none;
  39. padding: 20px 0;
  40. line-height: 20px;
  41. background-color: #333;
  42. color: #ccc;
  43. border: 1px solid black;
  44. }
  45. .footer_wrap a:hover,
  46. span:hover {
  47. background-color: #555;
  48. }
  49. .top {
  50. padding-top: 62px;
  51. }
  52. .footer_wrap .router-link-active {
  53. background-color: #000;
  54. }
  55. </style>

3.在src下面新建views文件夾并創(chuàng)建我們需要的.vue文件

88e582b6196e48c0a1c697bfc26d9869.png

3.1 find.vue


  1. <template>
  2. <div>
  3. <div class="nav_main">
  4. <router-link to="/Ranking">排行</router-link>
  5. <router-link to="/Recommend">推薦</router-link>
  6. <router-link to="/SongList">歌單</router-link>
  7. </div>
  8. <div style="1px solid red;">
  9. <router-view></router-view>
  10. </div>
  11. </div>
  12. </template>
  13. <script>
  14. export default {
  15. name: 'find',
  16. }
  17. </script>
  18. <style scoped>
  19. .nav_main {
  20. background-color: red;
  21. color: white;
  22. padding: 10px 0;
  23. }
  24. .nav_main a {
  25. text-align: center;
  26. text-decoration: none;
  27. color: white;
  28. font-size: 12px;
  29. margin: 7px 17px 0;
  30. padding: 0px 15px 2px 15px;
  31. height: 20px;
  32. display: inline-block;
  33. line-height: 20px;
  34. border-radius: 20px;
  35. }
  36. .nav_main a:hover {
  37. background-color: brown;
  38. }
  39. .nav_main .router-link-active{
  40. background-color: brown;
  41. }
  42. </style>

 3.2 my.vue


  1. <template>
  2. <div>
  3. <img src="../assets/my.png" alt="" width="100%">
  4. </div>
  5. </template>
  6. <script>
  7. export default {
  8. name: 'my',
  9. };
  10. </script>
  11. <style scoped>
  12. </style>

3.3 friend.vue


  1. <template>
  2. <div>
  3. <ul>
  4. <li>這是當前頁面 query 接收到的參數(shù):
  5. <span>姓名:{{ $route.query.name }}</span> --
  6. <span>年齡:{{$route.query.age}}</span>
  7. </li>
  8. <li>這是當前頁面 params 接收到的參數(shù):
  9. <!-- <span>姓名:{{ $route.params.name }}</span> --
  10. <span>年齡:{{ $route.params.age }}</span> -->
  11. </li>
  12. </ul>
  13. </div>
  14. </template>
  15. <script>
  16. export default {
  17. name: 'friend',
  18. };
  19. </script>
  20. <style scoped>
  21. </style>

3.4 notfound.vue


  1. <template>
  2. <div class="box">
  3. <h1>這是一個 404 頁面</h1>
  4. <img src="../assets/404.png" alt="">
  5. </div>
  6. </template>
  7. <script>
  8. export default {
  9. name: 'notfound',
  10. data() {
  11. return {
  12. };
  13. },
  14. };
  15. </script>
  16. <style scoped>
  17. .box {
  18. display: flex;
  19. flex-direction: column;
  20. justify-content: center;
  21. align-items: center;
  22. }
  23. </style>

 4.準備圖片素材(所有素材可私信博主獲?。?

3febf3f9755241a3b8bafccedb0f646e.gif

 5.所有準備工作做完現(xiàn)在開始我們的文件配置

 1.下載與導入vue-router

  • npm i vue-router@3.6.5

  • 導入vue-router (在main.js中)


  1. //main.js中導入
  2. // 0.導入路由
  3. import VueRouter from 'vue-router'
  4. // 使用vue的插件,都需要調(diào)用Vue.use()
  5. Vue.use(VueRouter)

2.導入組件

@符號代表 /src 文件夾的絕對路徑,在腳手架中文件比較多的時候,使用這個@符號會更加的方便

 在main.js中導入


  1. // 導入組件
  2. import find from '@/views/find.vue'
  3. import friend from '@/views/friend.vue'
  4. import my from '@/views/my.vue'
  5. import notfound from '@/views/notfound.vue'

3.創(chuàng)建路由規(guī)則

路由規(guī)則作用: 設置 url 和 組件 對應的規(guī)則

 在main.js中寫入


  1. // 路由規(guī)則
  2. const routes = [
  3. { path: '/find', component: find },
  4. { path: '/friend', name: 'friend', component: friend },
  5. { path: '/my', component: my },
  6. { path: '/notfound', component: notfound },
  7. ]

4.創(chuàng)建路由對象

路由對象: 幫你管理這些路由規(guī)則

 在main.js中寫入


  1. // 創(chuàng)建路由對象
  2. const router = new VueRouter({
  3. routes// (縮寫) 相當于 routes: routes
  4. })

 5.掛載路由到根組件

掛載到根組件作用:讓你的整個應用都有路由功能

 在main.js中寫入


  1. // 掛載路由到根組件
  2. new Vue({
  3. router,
  4. render: h => h(App)
  5. }).$mount('#app')

6.在頁面寫路由導航router-link

作用與a標簽一樣實現(xiàn)跳轉(zhuǎn),好處:當點擊鏈接的時候自帶一個專屬類名 

在App.vue中我們將傳統(tǒng)的a標簽進行替換:

4970109a68ec4481b7b4ce6d015fb05e.png

替換a標簽原因:便于我們做專屬效果 

 我們選中點擊的超鏈接做觸發(fā)效果:

457bf5ab19d14e1196aae8ebe7fbb272.png

 7在頁面寫路由出口router-view

占位盒子,用于渲染路由匹配到的組件

(<router-view> : 是vue內(nèi)置的一個組件,會自動替換成路由匹配的組件 )

0487e6a9e90f47259742157cc9bf927f.png

好了一個最最最基本的路由就被我們制作完成啦!下面我們來看看效果:

b90436a4b4b043e0972a686ec5d6c7b9.gif

上述的操作有些許麻煩,下面我們來使用我們開發(fā)中常用的自動配置方法

②自動配置(推薦使用)

創(chuàng)建腳手架方式與手動配置類似,唯一不同是此處必須選擇Router

8da9a6240ba34b7d8231d7e3d1329023.png

對比手動模式:

b4e1986802914f9682f82f40bd819859.png

 此刻:腳手架已經(jīng)幫我們創(chuàng)建好了Router路由不需要我們下載與導入vue-router了

只需要寫:

  1. 導入組件
  2. 配置路由規(guī)則
  3. 路由導航
  4. 路由出口

并且為了進一步的封裝我們的配置信息,我們的配置代碼將寫在router/index.js下,不再是全部寫在main.js下。

1.導入組件(index.js中)


  1. import find from '@/views/find.vue'
  2. import friend from '@/views/friend.vue'
  3. import my from '@/views/my.vue'
  4. import notfound from '@/views/notfound.vue'

2.配置路由規(guī)則(index.js中)


  1. { path: '/find', component: find },
  2. { path: '/friend', name: 'friend', component: friend },
  3. { path: '/my', component: my },
  4. { path: '/notfound', component: notfound }

 3.路由導航(直接cv我們之前的App.vue文件)


  1.       <router-link to="/find">發(fā)現(xiàn)音樂</router-link>
  2.       <router-link to="/my">我的音樂</router-link>
  3.       <router-link to="/friend">朋友</router-link>

 4.路由出口(App.vue中


  1. <div class="top">
  2. <router-view></router-view>
  3. </div>

效果查看:

a0b3530b690c4a9ca6249c14b002d6b0.gif


總結(jié)手動自動配置區(qū)別:

自動配置省去了一些固定不變的操作,我們不需要寫繁瑣且固定的代碼,只需要寫不同的代碼。且代碼書寫的位置都給我們設置好了,我們直接遵守該規(guī)范書寫代碼即可


三、路由重定向與二級路由

1.路由重定向

路由重定向官方文檔:重定向和別名 | Vue Router

  • 重定向應用場景: 頁面輸入根路徑/ , 自動跳轉(zhuǎn)到首頁

  • 注意點 : 重定向只是修改路徑, 還需要單獨去設置路由匹配規(guī)則

重定向命令:


  1. {
  2. path: '/',
  3. /*
  4. (1)重定向只是修改頁面路徑。 輸入 / 會重定向到 /路徑
  5. (2)只有component才會讓vue去尋找路由匹配頁面。所以設置了重定向,還需要單獨設置匹配規(guī)則
  6. */
  7. redirect: "路徑"
  8. },

1. 就拿我們剛才創(chuàng)建的舉例:

bef58f0f03f0422bad9ff7ff552333ca.png

 實現(xiàn)效果:當我在瀏覽器中打開的時候我沒有輸入任何路徑,vue自動幫我們跳轉(zhuǎn)到了 my.vue這個頁面組件

fc6d192e015f4d028f6d8e601a9ab2a1.png

 2.也可以利用重定向來設置當我們路徑錯誤提示404頁面:

ec7212bfaf874c898e43147ff21dcb43.png

實現(xiàn)效果:當我任意輸入沒有匹配的路徑,自動幫我們跳轉(zhuǎn)到了notfound.vue這個組件

4544b2c521bc475998d8f3220f43f714.gif

2.二級路由

實現(xiàn)頁面中存在第二級的跳轉(zhuǎn)

寫法(拿我們上述的案例實操,需要素材可私信博主喔):

①在index.js中引入


  1. // 導入二級路由
  2. import Ranking from '@/views/second/Ranking.vue'
  3. import Recommend from '@/views/second/Recommend.vue'
  4. import SongList from '@/views/second/SongList.vue'

②在需要引用的組件中使用:


  1. //格式:
  2. {
  3. path: '路徑', component: 組件名, children: [
  4. //此處填寫二級路由的路徑信息
  5. ]
  6. }

  1. {
  2. path: '/find', component: find, children: [
  3. {path:'/',redirect:'/SongList'},
  4. { path: '/Ranking', component: Ranking },
  5. { path: '/Recommend', component: Recommend },
  6. { path: '/SongList', component: SongList }
  7. ]
  8. }

③寫路由導航與出口

bde6628a95f54fb2b73ef7ea54cb05f3.png

 查看效果:

fae7f2b60cab46599c9d7a4b142de98a.gif

 可以看到:當我們點擊一級路由之后,我們還可以點擊二級路由到我們的專屬頁面中


 四、路由跳轉(zhuǎn)傳參

有兩種跳轉(zhuǎn)傳參方式:

  • 聲明式導航
  • 編程式導航

1.聲明式導航:

①query寫法:

在路徑中加參數(shù)信息即可

      <router-link to="/路徑?參數(shù)名=參數(shù)值&參數(shù)名=參數(shù)值</router-link>

接收信息:

在觸發(fā)的組件中書寫{{ $route.query.屬性名}}接收

 舉個例子:

026595d1cedd4c02ab86a4f99188edd8.png

②params寫法:

在index.jsx文件中寫:參數(shù)名。在需要傳遞的路由路徑中寫參數(shù)值

47aaff039df84bc990dd7f3f2ad9b74b.png

接收信息:

在觸發(fā)的組件中書寫{{ $route.params.屬性名}}接收

 6da470911546454488c229af441d7d78.png

 實現(xiàn)效果:

c2acf124d4cf44fb96dbc98e71d804c1.png


2.編程式導航

①query寫法:

結(jié)構:


  1. this.$router.push({
  2. path: '/路徑',
  3. query: { 屬性名: '屬性值'}
  4. })

接收信息:

在觸發(fā)的組件中書寫{{ $route.query.屬性名}}接收

舉個例子:

c55bce2fbbaf4910812fa99a15ef760b.png

 ②params寫法

結(jié)構:


  1. this.$router.push({
  2. name: '我們注冊路徑的組件名',//寫path獲取不到值?。。?/span>
  3. query: { 屬性名: '屬性值'}
  4. })

 注意點:寫path獲取不到值,需要用name

接收信息:

在觸發(fā)的組件中書寫{{ $route.params.屬性名}}接收

5fa2f0cd7c87446aadd377efaabe0784.png



藍藍設計建立了UI設計分享群,每天會分享國內(nèi)外的一些優(yōu)秀設計,如果有興趣的話,可以進入一起成長學習,請加藍小助,微信號:ben_lanlan,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯(lián)系01063334945。


分享此文一切功德,皆悉回向給文章原作者及眾讀者.
免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們?nèi)〉寐?lián)系,我們立即更正或刪除。


藍藍設計sillybuy.com )是一家專注而深入的界面設計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網(wǎng)站建設 平面設計服務、UI設計公司、界面設計公司、UI設計服務公司、數(shù)據(jù)可視化設計公司、UI交互設計公司、高端網(wǎng)站設計公司、UI咨詢、用戶體驗公司、軟件界面設計公司

【前端】參考C站動態(tài)發(fā)紅包界面,高度還原布局和交互

前端達人

目錄

1、界面效果

2、界面分析

2.1、整體結(jié)構

2.2、標題

2.3、表單

2.4、按鈕

3、代碼實現(xiàn)

3.1、標題區(qū)域布局

3.2、表單區(qū)域

3.2.1、祝福語

3.2.2、紅包數(shù)量

3.2.3、紅包總金額

3.2.4、余額支付

3.3、確認按鈕區(qū)域

4、完整代碼

5、基礎知識點


1、界面效果

  • 完成效果

  • C站發(fā)紅包界面 

2、界面分析

2.1、整體結(jié)構

上部分為標題、中間為表單、底部為確定按鈕

2.2、標題

底部背景、標題文本、右上角關閉按鈕

2.3、表單

祝福語文本、紅包數(shù)量文本、紅包總金額、當前余額文本顯示、以及前往充值按鈕

2.4、按鈕

左邊為需支付金額顯示,右邊為取消和確定按鈕

3、代碼實現(xiàn)

3.1、標題區(qū)域布局

1)背景圖片

圖片寬度380px像素,高度56px像素

2)背景圖片自動填充

布局一個div,寬度為400px像素,高度為56px像素,然后再設置背景圖片樣式,由于圖片本身寬度小于div寬度,div會多出20px像素,圖片會自動填充,默認效果如下


  1. <div style="width:400px;height:56px;background:url(/1674461966454.jpg);background-size: 100%;">
  2. </div>

 

 3)圖片百分比顯示

再給div設置背景百分比縮放顯示,效果如下

background-size: 100%;

 4)文本

布局一個span標簽,顯示"添加紅包"文本,白色黑體,18號字體,加粗,左對齊,且左邊距20px像素。并設置div標簽56px像素垂直居中樣式,效果如下

5)關閉按鈕

在右上角添加一個關閉按鈕,一般可以設置一個svg標簽圖標,設置高28px,寬36px

  • base64編碼圖標
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAAA4CAYAAABez76GAAAAAXNSR0IArs4c6QAAAtVJREFUeF7tm2FO3DAQhR+0BVZt2QIFujfrQXqMHqQ3W4kflRYJrZBArV6EUTa7jj0ee0yILUUIZcb2fJnMsx3tEYAfAI4x3/YPwDOARwAPAJ76KI4AfAdwMl8+e5ET0j0AggMBXQBYNEA7BJhNfwmJgL6+XI3RLgFm0oaAmD3Motb2CdwREOsP61Br+wQeCIgKRiVrbZ/AEwGxzV3qfcnRFWm2JvUeRA5Qk/oAoCb1AUBN6gOAmtQHADWpDwBqUh8BqEn9AUhO5nmrSX0AkLnULxaL7gFtt9vu7EXatP4x4/UzyFTqGdx6vf7NSa5Wq19SSFr/GDi06QMyk3oX3HK5/MlJbDabPxJIWv9YOENAZlI/DFACSeMrAeNs+xlkKvUpgab4pEDp+wwBmUq9JGCJrRbKGCBzqY8JPMYmJ5QxQOZSz8mMAeB9qp0r6JJ6lQPa8BUzlfp+AD5ItKkFZ6hi/N9M6g893UOQ+nbS5UCJDDKTet/kfZBqwDmUQaZSL8mitwToCsBpjvSU9jGFV4wxnQP4Ig1Oaz+VIt2prvWn6CnJPAGZFuqYRWCMjTaDff7DdZCzM9lySAKX2OaE5QPEGsRaVKylBJziow3AB4iv2e3gvEg71qu/JlCNb0oAPkDdCh/A55ROQz7aAy+tf2h+/ftjgD4CuJF0JrHVHplq/WPnOgaIfVwCOIvtTGqnPXTX+sfMNwSo6uY1JoDSNiFARWtR6eBy9B8DiDbXAFiTZtdiABHKbF+1WECEVGUTWztlJYBoS1WrchRSC5QEEOdIe54Xzea3HVJAs4OUAoiQuFdjJn2qlfpW46YCcpC+lVxpW0EYG0cDyPXLDS0VLkdfb4HJzhxyBcVFJBXu3S0mcwFyxZufrplROfutmlUlAmEBJyRek/8tbAlA7om/C1AlATlQHIMLS35O4tnSpLLKAtCwhrCQExj/8vrwAo3gasxntMb9B9PXrmqWhf+yAAAAAElFTkSuQmCC
  • 錯位布局

設置相對定位position樣式,位于右上角。它所在的父級就要設置絕對定位relative。這樣關閉按鈕圖標就會以它所在的父級定位,否則可能會布局錯位,比如下面錯位效果

  •  正確布局

  • 樣式代碼

  1. <style type="text/css">
  2. .title { width: 400px; height: 56px; background: url(/1674461966454.jpg); background-size: 100%; line-height: 56px;position:relative; }
  3. .title-text { font-size: 18px; font-weight: bold; color: #fff; font-family: 黑體; margin-left: 20px; }
  4. .close { position: absolute; top: 0px; right: 0px; width: 36px; height: 28px; }
  5. </style>
  6. <div class="title">
  7. <span class="title-text">添加紅包</span>
  8. <img class="close" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAAA4CAYAAABez76GAAAAAXNSR0IArs4c6QAAAtVJREFUeF7tm2FO3DAQhR+0BVZt2QIFujfrQXqMHqQ3W4kflRYJrZBArV6EUTa7jj0ee0yILUUIZcb2fJnMsx3tEYAfAI4x3/YPwDOARwAPAJ76KI4AfAdwMl8+e5ET0j0AggMBXQBYNEA7BJhNfwmJgL6+XI3RLgFm0oaAmD3Motb2CdwREOsP61Br+wQeCIgKRiVrbZ/AEwGxzV3qfcnRFWm2JvUeRA5Qk/oAoCb1AUBN6gOAmtQHADWpDwBqUh8BqEn9AUhO5nmrSX0AkLnULxaL7gFtt9vu7EXatP4x4/UzyFTqGdx6vf7NSa5Wq19SSFr/GDi06QMyk3oX3HK5/MlJbDabPxJIWv9YOENAZlI/DFACSeMrAeNs+xlkKvUpgab4pEDp+wwBmUq9JGCJrRbKGCBzqY8JPMYmJ5QxQOZSz8mMAeB9qp0r6JJ6lQPa8BUzlfp+AD5ItKkFZ6hi/N9M6g893UOQ+nbS5UCJDDKTet/kfZBqwDmUQaZSL8mitwToCsBpjvSU9jGFV4wxnQP4Ig1Oaz+VIt2prvWn6CnJPAGZFuqYRWCMjTaDff7DdZCzM9lySAKX2OaE5QPEGsRaVKylBJziow3AB4iv2e3gvEg71qu/JlCNb0oAPkDdCh/A55ROQz7aAy+tf2h+/ftjgD4CuJF0JrHVHplq/WPnOgaIfVwCOIvtTGqnPXTX+sfMNwSo6uY1JoDSNiFARWtR6eBy9B8DiDbXAFiTZtdiABHKbF+1WECEVGUTWztlJYBoS1WrchRSC5QEEOdIe54Xzea3HVJAs4OUAoiQuFdjJn2qlfpW46YCcpC+lVxpW0EYG0cDyPXLDS0VLkdfb4HJzhxyBcVFJBXu3S0mcwFyxZufrplROfutmlUlAmEBJyRek/8tbAlA7om/C1AlATlQHIMLS35O4tnSpLLKAtCwhrCQExj/8vrwAo3gasxntMb9B9PXrmqWhf+yAAAAAElFTkSuQmCC" alt="">
  9. </div>

3.2、表單區(qū)域

3.2.1、祝福語

1)組成元素

紅色星號、文本、輸入文本框、刷新文本按鈕

2)calc函數(shù)

它屬于css3的功能,calc() 函數(shù)用于動態(tài)計算長度值。對于布局非常有作用。

需要特別注意,函數(shù)內(nèi)的參數(shù)值前后都需要保留一個空格,例如:width: calc(100% - 40px);

3)刷新小圖標

樣式設置16x16高寬度

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAA3NJREFUSEu1lX+IVFUUx7/nPpV1N1zbzNQsXFkUoZBCqH+KNhJikKid14QpsjLv3Uc/yCQpCcISot+yJZHz3qxj2xIxzozJYCCuWiREfxQZJIT9IgjKoq0l3WZ33v3GvN3ZdczdmWXr/vfePef7uefce84R/M9LGtVPFYvN+Lm0H8SVIhwi5BcFc7i1FScSiUQ4lU7DgN7e3MpyyLMAVK2YnBOoXVp37bscJAKk3i0uwvnRByFsmjQKv/KcxJGLnVJvZ69XI1hNkasAWUXCAXldxUYgAy0tTYlNmzYMXuwzBgjyu0HzzCUnMPObrKVbtnSdmyr8bDZrDQ7hAaHsJdEmIh8vv7Z5fSwWK1V9IkAQ5JeTdAEsJrAZ4BWRwbw5HV73fd/Wu6dM5tCKkdHwJMAVEHnTc+1HawCVj76+oy3DpaHPQKwG5ALA5kYBFf90unBDaMLPRaAEcrPr2l+OpW58pYL8E6B5FcAZAPMBtM8EUJHx/dwegtsF6j2t4xsnAJnMyaaR8m/fg1giFmI0shPELVhorvESiT/rpai6H6Ua5gdSypYyyxwn8XsUgd+bu4shjwH4Ubt2+4ED7y8wJmxLJu3vGhWv2vnBweMk7lSCe133/sNjAL/wFBG+CJE3PNfeNlPRmqcc5J8HzdMQ9Zznxp+tPtMANI4oeVw79uuzAfjp3DYa9kBUj+fGt49HMHE5j2kd3zsbQCqdfxLGvARRr3lufEdNikRkn3bth2YFCPL7QbMVIg97rv3WeKEV1hiGZ0Tw68JWLp2ueU0HJ6n8dO6nymtUImsrtTBZB37uC4BrxZL1OmkPNBpFJpNdMlpWAxTpEeEgQ+YAOetpe9UlhZbbCfIFERxzHftuETGNQHz/4AYCRVHqCMiVJNcILK11V1AD6OsrLB4uhaejYlOySzv27hkBRL4h2QHB17ip/UZv3brRGsBYP8nfHhoeB6hEsVs7iXfqQSYiEERDh2KSmDPvVLVJ/mvg+OnCDprwlYgucpRzrUem66hBkIsZsmZuVHwtJfc4jl287EQLgkObifIeElcDUoLgFCAfKZgPOzoWfdLZ2VmuRtbf/8GC88MX+gVcVv1HyB+Ya3mVg005MtPpbJuhehlgNwlrMlXyqaftW+ulrrpfdyZHJ/z7r9tAq1Ng7gDltNZ28j8DNCo0ld0/bOx/KATgarIAAAAASUVORK5CYII=

4)文本框默認高亮

input輸入文本框默認點擊選中會有一個高亮的效果,可以設置樣式去掉

outline:none;

5)隨機文本

設置隨機祝福語文本值,可設置js全局數(shù)組參數(shù)變量保存。

并且給右邊的刷新按鈕綁定點擊事件,然后在事件內(nèi)使用隨機函數(shù)進行隨機顯示

  • 交互代碼

  1. <script type="text/javascript">
  2. $(function () {
  3. // 祝福語
  4. var labelText = ['成就一億技術人!', '節(jié)日快樂', 'Hello World', '新春大吉!', '大吉大利', 'Bug Free'];
  5. $('.cl-input img').click(function () {
  6. // Math.random() - 隨機函數(shù)會產(chǎn)生0~1之間的值
  7. var index = parseInt(Math.random() * labelText.length);
  8. var text = labelText[index];
  9. $('.cl-input input').val(text);
  10. });
  11. });
  12. </script>
  • 效果如下

  • 布局代碼

  1. <div class="content-label">
  2. <div class="cl-text">
  3. <span style="color:#f00;">*</span>
  4. <span>祝福語</span>
  5. </div>
  6. <div class="cl-input">
  7. <input placeholder="請?zhí)顚懠t包祝福語或標題" value="成就一億技術人!" />
  8. <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAA3NJREFUSEu1lX+IVFUUx7/nPpV1N1zbzNQsXFkUoZBCqH+KNhJikKid14QpsjLv3Uc/yCQpCcISot+yJZHz3qxj2xIxzozJYCCuWiREfxQZJIT9IgjKoq0l3WZ33v3GvN3ZdczdmWXr/vfePef7uefce84R/M9LGtVPFYvN+Lm0H8SVIhwi5BcFc7i1FScSiUQ4lU7DgN7e3MpyyLMAVK2YnBOoXVp37bscJAKk3i0uwvnRByFsmjQKv/KcxJGLnVJvZ69XI1hNkasAWUXCAXldxUYgAy0tTYlNmzYMXuwzBgjyu0HzzCUnMPObrKVbtnSdmyr8bDZrDQ7hAaHsJdEmIh8vv7Z5fSwWK1V9IkAQ5JeTdAEsJrAZ4BWRwbw5HV73fd/Wu6dM5tCKkdHwJMAVEHnTc+1HawCVj76+oy3DpaHPQKwG5ALA5kYBFf90unBDaMLPRaAEcrPr2l+OpW58pYL8E6B5FcAZAPMBtM8EUJHx/dwegtsF6j2t4xsnAJnMyaaR8m/fg1giFmI0shPELVhorvESiT/rpai6H6Ua5gdSypYyyxwn8XsUgd+bu4shjwH4Ubt2+4ED7y8wJmxLJu3vGhWv2vnBweMk7lSCe133/sNjAL/wFBG+CJE3PNfeNlPRmqcc5J8HzdMQ9Zznxp+tPtMANI4oeVw79uuzAfjp3DYa9kBUj+fGt49HMHE5j2kd3zsbQCqdfxLGvARRr3lufEdNikRkn3bth2YFCPL7QbMVIg97rv3WeKEV1hiGZ0Tw68JWLp2ueU0HJ6n8dO6nymtUImsrtTBZB37uC4BrxZL1OmkPNBpFJpNdMlpWAxTpEeEgQ+YAOetpe9UlhZbbCfIFERxzHftuETGNQHz/4AYCRVHqCMiVJNcILK11V1AD6OsrLB4uhaejYlOySzv27hkBRL4h2QHB17ip/UZv3brRGsBYP8nfHhoeB6hEsVs7iXfqQSYiEERDh2KSmDPvVLVJ/mvg+OnCDprwlYgucpRzrUem66hBkIsZsmZuVHwtJfc4jl287EQLgkObifIeElcDUoLgFCAfKZgPOzoWfdLZ2VmuRtbf/8GC88MX+gVcVv1HyB+Ya3mVg005MtPpbJuhehlgNwlrMlXyqaftW+ulrrpfdyZHJ/z7r9tAq1Ng7gDltNZ28j8DNCo0ld0/bOx/KATgarIAAAAASUVORK5CYII=" alt="">
  9. </div>
  10. </div>

3.2.2、紅包數(shù)量

布局和祝福語一樣,刷新按鈕換成了單位文本。

這里文本框有個離開焦點事件,如果判斷沒有輸入值,那么提示”請輸入數(shù)量",并且紅包數(shù)量只能是正整數(shù),文本框也變?yōu)榧t色邊框,默認則為藍色邊框

  • 布局效果

  • 布局代碼

  1. <div class="content-label">
  2. <div class="cl-text">
  3. <span style="color:#f00;">*</span>
  4. <span>紅包數(shù)量</span>
  5. </div>
  6. <div class="cl-input">
  7. <input placeholder="請?zhí)顚懠t包數(shù)量" value="" />
  8. <span></span>
  9. </div>
  10. </div>
  •  交互效果

  • 交互代碼 

  1. $("#txtCount").blur(function () {
  2. txtCount = $(this).val();
  3. if (txtCount == undefined || txtCount == null || txtCount == '' || txtCount.trim() == '') {
  4. $("i", $(this).parent()).show().html('請輸入數(shù)字!');
  5. $(this).parent().addClass('red-border');
  6. }
  7. else {
  8. if (txtCount <= 0) {
  9. $("i", $(this).parent()).show().html('請輸入有效數(shù)字格式!');
  10. $(this).parent().addClass('red-border');
  11. }
  12. else if (!isNaN(txtCount)) {
  13. $("i", $(this).parent()).hide();
  14. $(this).parent().removeClass('red-border');
  15. }
  16. else {
  17. }
  18. }
  19. });

3.2.3、紅包總金額

布局和前面一樣,這就是前端布局的魅力,有很多可以重用的東西

  • 布局效果

  • 布局代碼 

  1. <div class="content-label">
  2. <div class="cl-text">
  3. <span style="color:#f00;">*</span>
  4. <span>紅包總金額</span>
  5. </div>
  6. <div class="cl-input">
  7. <input placeholder="請?zhí)顚懠t包總金額" value="" />
  8. <span></span>
  9. </div>
  10. </div>

3.2.4、余額支付

這里的布局和前面稍微多點東西,布局差不多。

這里只做讀取展示用,也可以用input輸入文本框,設置默認只讀即可

  • 布局效果

  • 布局代碼 

  1. <div class="content-label">
  2. <div class="cl-text">
  3. <span style="color:#f00;">*</span>
  4. <span>余額支付</span>
  5. </div>
  6. <div class="cl-input">
  7. <label>當前余額:<b>51.25</b></label>
  8. <span class="span">前往充值 > </span>
  9. </div>
  10. </div>

3.2.5、文本邊框交互邏輯

當點擊文本框時,先判斷是否已經(jīng)提示無效信息,也就是已經(jīng)有紅色邊框,有則不顯示藍色邊框,沒有則顯示藍色邊框。當離開文本框焦點,那么則移除藍色邊框

  • 交互效果

  • 交互代碼

  1. // 文本框點擊事件
  2. $('.cl-input input').click(function () {
  3. var className = $(this).parent().attr('class');
  4. if (className.indexOf('red-border') < 0) {
  5. $(this).parent().addClass('blue-border');
  6. }
  7. }).blur(function () {
  8. $(this).parent().removeClass('blue-border');
  9. });

3.3、確認按鈕區(qū)域

1)支付額文本

這里布局左定位,金額數(shù)字加紅色字體

2)取消和確認按鈕

取消按鈕鼠標移動上去邊框變深,直接使用css的hover屬性即可完成。

確認按鈕的效果使用同樣的方式

3)布局效果

 

 4)布局代碼


  1. <!--按鈕-->
  2. <div class="button">
  3. <div class="price">
  4. <span>需支付:</span>
  5. <span id="priceSpan" style="font-size:20px;color:#f00;">0.00</span>
  6. <span></span>
  7. </div>
  8. <div class="btn">
  9. <div class="btnCancel">
  10. <span>取消</span>
  11. </div>
  12. <div class="btnOk not-allowed">
  13. <span>確定</span>
  14. </div>
  15. </div>
  16. </div>

5)交互代碼


  1. // 紅包個數(shù)
  2. var txtCount = 0;
  3. var txtPrice = 0;
  4. $("#txtCount").keyup(function () {
  5. txtCount = $(this).val();
  6. $("#priceSpan").html(txtCount * txtPrice);
  7. });
  8. // 紅包總金額
  9. $("#txtPrice").keyup(function () {
  10. txtPrice = $(this).val();
  11. $("#priceSpan").html(txtPrice);
  12. });

4、完整代碼

紅包數(shù)量和紅包金額那里還有幾個交互和邏輯判斷,有興趣的小伙伴可以自己實現(xiàn)下,有疑問的可咨詢了解

完整代碼可以查看gitCode:小5聊 / Csdn Red Bag Html · GitCode

 

5、基礎知識點

calc()函數(shù) 可用于高寬度精準布局,更加合理布局
position和relative 相對和絕對定位,同樣有助于合理定位和布局
Math.random()        隨機函數(shù),隨機產(chǎn)生0~1的值
keyup() 鍵盤彈上事件
click() 元素點擊事件
blur() 離開焦點事件

總結(jié):前端布局,要玩出花樣和效果,還是需要點藝術天賦??傊?,挺有趣的,剛?cè)腴T可能會覺得比較難,當你熟練之后,還是挺有趣的!

藍藍設計建立了UI設計分享群,每天會分享國內(nèi)外的一些優(yōu)秀設計,如果有興趣的話,可以進入一起成長學習,請加藍小助,微信號:ben_lanlan,報下信息,藍小助會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯(lián)系01063334945。


分享此文一切功德,皆悉回向給文章原作者及眾讀者.
免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們?nèi)〉寐?lián)系,我們立即更正或刪除。


藍藍設計sillybuy.com )是一家專注而深入的界面設計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網(wǎng)站建設 、平面設計服務UI設計公司、界面設計公司、UI設計服務公司、數(shù)據(jù)可視化設計公司、UI交互設計公司、高端網(wǎng)站設計公司、UI咨詢、用戶體驗公司、軟件界面設計公司




日歷

鏈接

個人資料

藍藍設計的小編 http://sillybuy.com

存檔