搜索“視頻傳輸協(xié)議”,一般會搜出來RTP,RTSP,UDP等等。光看這些協(xié)議,可能有些人會覺得奇怪為什么要把udp也往上放一起,rtp不是可以基于udp?!同時,很多文章主要去講解各個協(xié)議之間的差異,而沒有從更為宏觀的角度來考慮。本文將結合OSI的分層思路,將不同協(xié)議之間的關系都梳理清楚;同時也從視頻傳輸與組網(wǎng)角度進行介紹。
再者,視頻有很多封裝格式,比如m3u8,mp4等;也有很多音視頻編碼格式,比如h264,h265等,那為何有這么多的封裝格式類型和音視頻編碼格式類型呢?一方面是解決存儲的問題;另一方面是支持不同播放器的解析;但更重要的是不同的傳輸協(xié)議可以支持的音視頻編碼格式有差異,這也是由于不同的應用場景下形成的歷史原因。
流媒體(streaming media),是指將一連串的媒體數(shù)據(jù)包從服務器端發(fā)送到客戶端,可以實現(xiàn)邊下邊播,此技術使得數(shù)據(jù)包可以像流水一樣發(fā)送。傳統(tǒng)的方式需要在使用前下載整個文件,存儲到本地后才能進行播放;而流媒體只允許下載一小部分(存在視頻關鍵幀)就能進行播放。
流媒體技術不是一種單一的技術,它將網(wǎng)絡技術、音視頻技術還有終端緩存技術等有機地結合。也就是說,在網(wǎng)絡上要實現(xiàn)流媒體技術,必須要先制作、發(fā)布、傳輸和播放等,這需要服務器端、終端以及網(wǎng)絡都要能支持。當前很多的視頻軟件或者網(wǎng)站都是用到了這種技術。歸結下來是:
1.內容的產(chǎn)生。這里是指將視頻源制作成為可以對外發(fā)布的視頻格式,以及適合在網(wǎng)絡上傳播的分辨率和碼率。這主要用到了視頻的編解碼技術??紤]的輸出參數(shù),如分辨率、碼率、音視頻編碼格式、封裝格式等都需要結合應用場景和傳輸方式統(tǒng)一考慮。
2.對外發(fā)布。這里主要是指能夠支撐服務器對外輸出視頻資源的技術,常見的有各種流媒體網(wǎng)絡傳輸協(xié)議技術及其需要服務器端支撐的技術。這里的流媒體網(wǎng)絡傳輸協(xié)議比如:
3.組網(wǎng)和傳輸。
這里的傳輸還得考慮一個概念,是服務器對外主動推數(shù)據(jù),還是等待終端到服務器端拉數(shù)據(jù),這是兩個完全相反的處理方式。對于組播或者廣播的組網(wǎng)方式,往往采用的是服務器主動對外推送數(shù)據(jù);而對于單播來說主要是終端向服務器端主動拉數(shù)據(jù)。
這里涉及到的IP組網(wǎng)方式中的傳輸類型有:廣播、單播、組播。
不管是什么類型的組網(wǎng)方式,在傳輸層就有UDP和TCP。下面也將從OSI等層面講講這些底層傳輸協(xié)議之間的關系。
4.視頻播放。這里主要是從終端側角度說,在不同操作系統(tǒng)中能夠進行播放視頻的播放器,比如vlc等,不同的播放器支持對不同類型的視頻數(shù)據(jù)進行播放。
從圖中也可以看到IP層(網(wǎng)絡層)的上層是傳輸層,通過TCP和UDP等方式進行數(shù)據(jù)包的傳輸。
(PS:下圖為網(wǎng)絡中所找https://blog.csdn.net/yaopeng_2005/article/details/7064869)
結合上圖,再補一個wiki上的互聯(lián)網(wǎng)協(xié)議套組圖,一看就更明白了。
從上面兩個圖中也可以很清楚地看到,TCP和UDP在接下去的內容有很重要的地位,這里也簡單介紹下,深度知識請自行搜索。
組播(multicast)
又稱為多點廣播或群播,或多播,主要是指將信息同時傳遞給一組目的地址。消息在每個網(wǎng)絡鏈路上只需傳遞一次,而且只有在鏈路分叉時,消息才會被復制,使用的效率是最高的。也正是因為這個原因,以前的廣電網(wǎng)絡中,針對直播多采用組播方式,流量的傳輸成本明顯降低很多。
單播:
其實是組播的一種特殊方式,即常規(guī)的點到點信息傳遞。如果所有傳輸中是以單播的方式傳遞給多個接收方,必須向每個接收者都發(fā)送一份數(shù)據(jù)副本這么多。
廣播
其實也算是組播的一種特殊方式,就是一對所有的通信方式,對每一臺主機發(fā)出的信號都進行無條件復制并轉發(fā),所有的接收點都可以收到所有信息。
注意,組播一般指的是IP組播,常與RTP等音視頻協(xié)議相結合。雖然組播的設計理念很好,但是它需要對網(wǎng)絡內部的狀態(tài)比單播要多得多。實際商用中,組播主要應用在較為簡單的、只有單個源斷的情況,如之前提到廣電網(wǎng)絡內部用到的組播方式,UDP組播。
以上是不同類型的IP組播方式,實際在采用中要結合具體情況進行調整。比如,如果非要使用廣播,但是采用的場景不合適,也有可能產(chǎn)生廣播風暴。
組播、廣播、單播也介紹了基本的概念,但是他們與視頻傳輸有什么關系呢?
文章上面也提到了,組播是從IP層面的傳輸策略,而所有的視頻傳輸協(xié)議其數(shù)據(jù)包大部分都經(jīng)過UDP和TCP,經(jīng)由IP層進行傳輸?shù)侥康牡亍R虼瞬煌腎P傳輸策略與傳輸協(xié)議進行結合,就能夠落地到具體的應用場景。
同時需要注意的是,采用組播方式可以通過設置網(wǎng)卡為混雜模式或為多播模式,具體也是根據(jù)網(wǎng)卡的特性進行差異處理。如果處理方式不當,比如設置成了廣播,可能會導致在同網(wǎng)絡下,你在播放視頻,然后其他相同網(wǎng)絡下接收端也將有相應的流量,而導致他們的對外服務網(wǎng)口的流量被占滿。
從下圖中可以看到,標紅色的就是大家經(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ù)傳輸提供了時間信息和流同步,但不保證服務質量,而是由服務質量由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)絡內部主要應用在點播場景比較多,而直播主要走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é)議。
4)HTTP
而基于HTTP協(xié)議的就更多了,如上圖。如果服務器部署了流媒體的服務,如Nginx等,就可以對外提供視頻播放服務了。
這里也需要說明,視頻的播放一般分為點播和直播,有些協(xié)議作為直播的傳輸協(xié)議反而是更好的,比如RTMP,時延就比較低,但RTMP做CDN成本相對較高。CDN支持很好的HTTP如果能支持直播,當前也有很多協(xié)議能支持通過HTTP的方式實現(xiàn)直播流媒體。
自適性流媒體(adaptive bitrate streaming,ABS)也叫碼流自適應,是流媒體服務器準備各種碼流的視頻流,所有的視頻碼流都是相同時段完全統(tǒng)一圖像的音視頻數(shù)據(jù),客戶端根據(jù)網(wǎng)絡情況和CPU使用情況等進行動態(tài)調整。
主要有MPEG-DASH、HLS、HDS、MSS等技術方案,這幾個也是上圖中最上層的流媒體傳輸協(xié)議技術。通過這些傳輸協(xié)議封裝的視頻源,可以支持有多種碼率,并支持播放器客戶端在播放時,根據(jù)帶寬情況自動調整碼率以適應用戶的最佳觀看效果——不卡頓,不重新加載等。
這里也僅僅對碼流自適應技術做了簡單介紹,由于現(xiàn)在這種技術應用相當廣泛,后面將詳細介紹這種技術。
【說明】
文章轉自,華為云社區(qū),作者Higeeon,相關版權解釋權歸原作者所有。https://bbs.huaweicloud.com/blogs/fed3df04b1e011e9b759fa163e330718
藍藍設計建立了UI設計分享群,每天會分享國內外的一些優(yōu)秀設計,如果有興趣的話,可以進入一起成長學習,請加微信ban_lanlan,報下信息,藍小助會請您入群。歡迎您加入噢~~
希望得到建議咨詢、商務合作,也請與我們聯(lián)系01063334945。
分享此文一切功德,皆悉回向給文章原作者及眾讀者. 免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯(lián)系,我們立即更正或刪除。
藍藍設計( www.yvirxh.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業(yè)提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網(wǎng)站建設 、平面設計服務、UI設計公司、界面設計公司、UI設計服務公司、數(shù)據(jù)可視化設計公司、UI交互設計公司、高端網(wǎng)站設計公司、UI咨詢、用戶體驗公司、軟件界面設計公司。
JSON(JavaScript Object Notation, JS對象簡譜)是一種輕量級的數(shù)據(jù)交換格式。它基于 ECMAScript(European Computer Manufacturers Association, 歐洲計算機協(xié)會制定的js規(guī)范)的一個子集,采用完全獨立于編程語言的文本格式來存儲和表示數(shù)據(jù)。簡潔和清晰的層次結構使得 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的說明總結如下:
- JSON是獨立于任何編程語言的數(shù)據(jù)格式
- 是一種用于存儲和傳輸數(shù)據(jù)的輕量級格式
- 語法是自描述的,便于人類閱讀和理解
- 數(shù)組(Array)用方括號 "[]" 表示
- 對象(0bject)用大括號 "{}" 表示
- 名稱 / 值 對(name/value)組合成數(shù)組和對象
- 名稱( name )置于雙引號中,值(value)有字符串、數(shù)值、布爾值、null、對象和數(shù)組
- 并列的數(shù)據(jù)之間用逗號 "," 分隔
- 名稱/值對包括字段名稱(在雙引號中),后面寫一個冒號,然后是值
需要注意的是:
JSON不支持注釋。向 JSON添加注釋無效
JSON文件的文件類型是
.json
JSON文本的
MIME
類型是application/json
json是以對象的形式存在的,直接獲取JSON數(shù)據(jù)可通過如下方法:
1. json對象.鍵名
2. json對象["鍵名"]
3. 數(shù)組對象[索引]
4. 遍歷
代碼示例:
-
//定義基本格式
-
var person = { name: "張三", age: 23, gender: true };
-
var persons = [
-
{ name: "張三", age: 23, gender: true },
-
{ name: "李四", age: 24, gender: true },
-
{ name: "王五", age: 25, gender: false },
-
];
-
-
//獲取person對象中所有的鍵和值
-
//for in 循環(huán)
-
/* for(var key in person){
-
//這樣的方式獲取不行。因為相當于 person."name"
-
//alert(key + ":" + person.key);
-
alert(key+":"+person[key]);
-
}*/
-
-
//獲取persons中的所有值
-
for (var i = 0; i < persons.length; i++) {
-
var p = persons[i];
-
for (var key in p) {
-
console.log(key + ":" + p[key]);
-
}
-
}
輸出結果為:
先在控制臺中打印一下JSON對象,看看有什么,如圖:
顯而易見,在JavaScript中JSON對象僅有兩個方法:parse和stringify。后面會詳細介紹一下這兩個方法
序列化的概念:序列化是將對象轉化為字節(jié)序列的過程。對象序列化后可以在網(wǎng)絡上傳輸,或者保存到硬盤上。
將對象序列化成json字符串: JSON.stringify(json對象);
反序列化:將json字符串反序列化為對象: JSON.parse(str)
API介紹:用來解析 JSON字符串,構造由字符串描述的 JavaScript
值或對象,傳入的字符串不符合 JSON規(guī)范會報錯
語法:
JSON.parse(str, reviver);
str
:要解析的 JSON字符串reviver
:可選的函數(shù)function(key,value)
,該函數(shù)的第一個參數(shù)和第二個參數(shù)分別代表鍵值對的鍵和值,并可以對值進行轉換(函數(shù)返回值當做處理后的value)
代碼示例:
-
// JSON.parse() 解析JSON字符串, 將JSON轉換為對象
-
let json = '{"name": ["js", "webpack"], "age": 22, "gridFriend": "ljj"}';
-
console.log(JSON.parse(json));
-
// {name: Array(2), age: 22, gridFriend: 'ljj'}
-
-
// 第二個參數(shù)是一個函數(shù),key和value代表每個key/value對
-
let result = JSON.parse(json, (key, value) => {
-
if (key == "age") {
-
return `年齡:${value}`;
-
}
-
return value;
-
});
-
console.log(result);
-
//{name: Array(2), age: '年齡:22', gridFriend: 'ljj'}
API介紹:將一個 JavaScript
對象或值轉換為 JSON字符串
如果指定了一個 replacer
函數(shù),則可以選擇性地替換值,或者指定的 replacer
是數(shù)組,則可選擇性地僅包含數(shù)組指定的屬性
語法:
JSON.stringify(value, replacer, space)
value:將要序列化成 一個 JSON 字符串的值
replacer:
- 如果該參數(shù)是一個函數(shù),則在序列化過程中,被序列化的值的每個屬性都會經(jīng)過該函數(shù)的轉換和處理
- 如果該參數(shù)是一個數(shù)組,則只有包含在這個數(shù)組中的屬性名才會被序列化到最終的 JSON 字符串中
- 如果該參數(shù)為 null 或者未提供,則對象所有的屬性都會被序列化
space:指定縮進用的空白字符串,用于美化輸出
- 如果參數(shù)是個數(shù)字,它代表有多少的空格;上限為10。該值若小于1,則意味著沒有空格
- 如果該參數(shù)為字符串(當字符串長度超過10個字母,取其前10個字母),該字符串將被作為空格
- 如果該參數(shù)沒有提供(或者為 null),將沒有空格
代碼示例:
-
let obj = {
-
name: "jsx",
-
age: 22,
-
lesson: ["html", "css", "js"],
-
};
-
let json = JSON.stringify(obj);
-
console.log(json);
-
// {"name":"jsx","age":22,"lesson":["html","css","js"]}
-
-
// 第二個參數(shù)replacer 為函數(shù)時,被序列化的值得屬性都會經(jīng)過該函數(shù)轉換處理
-
function replacer(key, value) {
-
if (typeof value === "string") {
-
return undefined;
-
}
-
return value;
-
}
-
let result = JSON.stringify(obj, replacer);
-
console.log(result);
-
// {"age":22,"lesson":[null,null,null]}
-
-
// 當replacer參數(shù)為數(shù)組,數(shù)組的值代表將被序列化成 JSON 字符串的屬性名
-
let result1 = JSON.stringify(obj, ["name", "lesson"]);
-
// 只保留 “name” 和 “l(fā)esson” 屬性值
-
console.log(result1);
-
// {"name":"jsx","lesson":["html","css","js"]}
-
-
// 第三個參數(shù)spcae,用來控制結果字符串里面的間距
-
let result2 = JSON.stringify(obj, null, 4);
-
console.log(result2);
-
/*{
-
"name": "jsx",
-
"age": 22,
-
"lesson": [
-
"html",
-
"css",
-
"js"
-
]
-
}*/
注意:如果replacer是一個函數(shù),則該函數(shù)會進行深處理,即如果鍵值對的值也是一個數(shù)組,則也會執(zhí)行該函數(shù)
- 轉換值如果有
toJSON()
方法,該方法定義什么值將被序列化- 非數(shù)組對象的屬性不能保證以特定的順序出現(xiàn)在序列化后的字符串中
- 布爾值、數(shù)字、字符串的包裝對象在序列化過程中會自動轉換成對應的原始值,undefined、任意的函數(shù)以及 symbol 值,在序列化過程中會被忽略(出現(xiàn)在非數(shù)組對象的屬性值中時)或者被轉換成 null(出現(xiàn)在數(shù)組中時)。函數(shù)、undefined 被單獨轉換時,會返回 undefined,如JSON.stringify(function(){}) or JSON.stringify(undefined)
- 對包含循環(huán)引用的對象(對象之間相互引用,形成無限循環(huán))執(zhí)行此方法,會拋出錯誤
- 所有以 symbol 為屬性鍵的屬性都會被完全忽略掉,即便 replacer 參數(shù)中強制指定包含了它們
- Date 日期調用了 toJSON() 將其轉換為了 string 字符串(同Date.toISOString()),因此會被當做字符串處理
- NaN 和 Infinity 格式的數(shù)值及 null 都會被當做 null
- 其他類型的對象,包括 Map/Set/WeakMap/WeakSet,僅會序列化可枚舉的屬性
藍藍設計建立了UI設計分享群,每天會分享國內外的一些優(yōu)秀設計,如果有興趣的話,可以進入一起成長學習,請加微信ban_lanlan,報下信息,藍小助會請您入群。歡迎您加入噢~~
希望得到建議咨詢、商務合作,也請與我們聯(lián)系01063334945。
分享此文一切功德,皆悉回向給文章原作者及眾讀者. 免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯(lián)系,我們立即更正或刪除。
藍藍設計( www.yvirxh.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業(yè)提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網(wǎng)站建設 、平面設計服務、UI設計公司、界面設計公司、UI設計服務公司、數(shù)據(jù)可視化設計公司、UI交互設計公司、高端網(wǎng)站設計公司、UI咨詢、用戶體驗公司、軟件界面設計公司。
1.get請求一般是去取獲取數(shù)據(jù)(其實也可以提交,但常見的是獲取數(shù)據(jù));
post請求一般是去提交數(shù)據(jù)。
2.get因為參數(shù)會放在url中,所以隱私性,安全性較差,請求的數(shù)據(jù)長度是有限制的,
不同的瀏覽器和服務器不同,一般限制在 2~8K 之間,更加常見的是 1k 以內;
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設計分享群,每天會分享國內外的一些優(yōu)秀設計,如果有興趣的話,可以進入一起成長學習,請加微信ban_lanlan,報下信息,藍小助會請您入群。歡迎您加入噢~~
希望得到建議咨詢、商務合作,也請與我們聯(lián)系01063334945。
分享此文一切功德,皆悉回向給文章原作者及眾讀者. 免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯(lián)系,我們立即更正或刪除。
藍藍設計( www.yvirxh.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業(yè)提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網(wǎng)站建設 、平面設計服務、UI設計公司、界面設計公司、UI設計服務公司、數(shù)據(jù)可視化設計公司、UI交互設計公司、高端網(wǎng)站設計公司、UI咨詢、用戶體驗公司、軟件界面設計公司。
rpx是響應式px
rpx是一種根據(jù)屏幕寬度自適應的動態(tài)單位。以750寬的屏幕為基準,750rpx正好是屏幕的寬度。屏幕變寬,rpx實際顯示效果會等比放大,但在App端和h5端,屏幕寬度達到960px時,默認將按照375px的屏幕寬度進行計算。在開發(fā)移動端項目時選擇rpx作為尺寸單位。
uni-app在App端,H5端和小程序都支持rpx,并且可以配置不同屏幕寬度的計算方式。
頁面元素在uni-app的寬度計算公式如下:
750 * 元素在設計稿中的寬度 / 設計稿基準寬度
舉例說明:
但是要注意的是
拓展:在設置文件mainfest.json里開啟px轉rpx(默認關閉),所有的px可一鍵轉換為rpx
“transformPx”:false
rpx直接支持動態(tài)綁定
<view class="test" :style="{width:winWidth + 'rpx;'}"></view>
vue項目中,前端與后臺進行數(shù)據(jù)請求或者提交的時候,如果后臺沒有設置跨域,前端本地調試代碼的時候就會報“No 'Access-Control-Allow-Origin' header is present on the requested resource.” 這種跨域錯誤。
要想本地正常的調試,解決的辦法有三個:
一、后臺更改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設計分享群,每天會分享國內外的一些優(yōu)秀設計,如果有興趣的話,可以進入一起成長學習,請加微信ban_lanlan,報下信息,藍小助會請您入群。歡迎您加入噢~~
希望得到建議咨詢、商務合作,也請與我們聯(lián)系01063334945。
分享此文一切功德,皆悉回向給文章原作者及眾讀者. 免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯(lián)系,我們立即更正或刪除。
藍藍設計( www.yvirxh.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業(yè)提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網(wǎng)站建設 、平面設計服務、UI設計公司、界面設計公司、UI設計服務公司、數(shù)據(jù)可視化設計公司、UI交互設計公司、高端網(wǎng)站設計公司、UI咨詢、用戶體驗公司、軟件界面設計公司。
我使用命令 npm run dev 啟動項目 報了下面的錯。
'webpack-dev-server' 不是內部或外部命令,也不是可運行的程序
> webpack-dev-server --inline --progress --config build/webpack.dev.conf.js
'webpack-dev-server' 不是內部或外部命令,也不是可運行的程序
或批處理文件。
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 命令
這樣我就可以成功運行項目了。
1.區(qū)別:vuex存儲在內存,localstorage(本地存儲)則以文件的方式存儲在本地,永久保存(不主動刪除,則一直存在);sessionstorage( 會話存儲 ) ,臨時保存。localStorage和sessionStorage只能存儲字符串類型,對于復雜的對象可以使用ECMAScript提供的JSON對象的stringify和parse來處理
2.應用場景:vuex用于組件之間的傳值,localstorage,sessionstorage則主要用于不同頁面之間的傳值。
3.永久性:當刷新頁面(這里的刷新頁面指的是 --> F5刷新,屬于清除內存了)時vuex存儲的值會丟失,sessionstorage頁面關閉后就清除掉了,localstorage不會。
注:大家可能覺得用localstorage可以代替vuex, 對于不變的數(shù)據(jù)確實可以,但是當兩個組件共用一個數(shù)據(jù)源(對象或數(shù)組)時,如果其中一個組件改變了該數(shù)據(jù)源,希望另一個組件響應該變化時,localstorage,sessionstorage無法做到,原因就是區(qū)別1。
vuex是存儲在頁面上的變量,說到底還是個Object,刷新頁面就清空了。而storage是存儲在瀏覽器的,和頁面就無關了,刷新頁面也不會清空
分享此文一切功德,皆悉回向給文章原作者及眾讀者.
免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯(lián)系,我們立即更正或刪除。
藍藍設計( www.yvirxh.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業(yè)提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網(wǎng)站建設 、平面設計服務、UI設計公司、界面設計公司、UI設計服務公司、數(shù)據(jù)可視化設計公司、UI交互設計公司、高端網(wǎng)站設計公司、UI咨詢、用戶體驗公司、軟件界面設計公司
我們經(jīng)常會將Word轉換成PDF,下面給大家介紹一種很不錯的Word轉PDF格式的方式。
打開瀏覽器搜索speedpdf找到并打開在線轉換工具首頁,選擇主頁上的Word轉PDF進入轉換(也可以點擊上方所有工具字樣,選擇Word轉PDF進入)。
將需要轉換的Word文檔添加上傳后,點擊進度條后面的轉換按鈕,就可以開始轉換了,等待轉換完成后點擊下載箭頭即可。
如果轉換前有登錄賬戶,還可以通過點擊登錄頭像處,選擇賬戶,在轉換記錄中查看轉換狀態(tài)和下載轉換后的文檔。
分享此文一切功德,皆悉回向給文章原作者及眾讀者.
免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯(lián)系,我們立即更正或刪除。
藍藍設計( www.yvirxh.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業(yè)提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網(wǎng)站建設 、平面設計服務、UI設計公司、界面設計公司、UI設計服務公司、數(shù)據(jù)可視化設計公司、UI交互設計公司、高端網(wǎng)站設計公司、UI咨詢、用戶體驗公司、軟件界面設計公司
目錄
確保我們在vue中實現(xiàn)頁面跳轉到我們所想的頁面
可以看到當我們點擊不同的組件的時候我們實現(xiàn)了路由的功能:在vue中實現(xiàn)頁面的跳轉
注意看,當我點擊的時候上面地址欄中加載了不同的網(wǎng)頁。下面我們來學習下路由的寫法
路由書寫寫法:
在index.js中的router對象中書寫
-
const router = new VueRouter({
-
mode: 'history',//默認是hash模式
-
})
hash模式:
history模式:
兩種模式的區(qū)別:
起步 | Vue RouterVue Router3官網(wǎng)介紹: 起步 | Vue Router
- 下載與導入vue-router
- 導入組件
- 創(chuàng)建routes路由規(guī)則(路徑和頁面一一對應)
- 創(chuàng)建路由對象
- 把路由對象掛載到App.vue
- 在頁面寫路由導航router-link (生成a標簽)
- 在頁面寫路由出口router-view (生成占位盒子,用于顯示頁面內容)
下面開始我們相關文件的創(chuàng)建
1.創(chuàng)建我們的腳手架(此時沒有選擇Router):
2.準備我們的App.vue文件:
-
<template>
-
<div>
-
<!-- 頂部導航欄 -->
-
<div class="footer_wrap">
-
<a href="#/find">發(fā)現(xiàn)音樂</a>
-
<a href="#/my">我的音樂</a>
-
<a href="#/friend">朋友</a>
-
</div>
-
<!-- 下面內容 -->
-
<div class="top"></div>
-
</div>
-
</template>
-
-
<script>
-
export default {
-
methods: {}
-
}
-
</script>
-
-
<style scoped>
-
body,
-
html {
-
margin: 0;
-
padding: 0;
-
}
-
.footer_wrap {
-
position: fixed;
-
left: 0;
-
top: 0;
-
display: flex;
-
width: 100%;
-
text-align: center;
-
background-color: #333;
-
color: #ccc;
-
}
-
.footer_wrap a,
-
span {
-
cursor: pointer;
-
flex: 1;
-
text-decoration: none;
-
padding: 20px 0;
-
line-height: 20px;
-
background-color: #333;
-
color: #ccc;
-
border: 1px solid black;
-
}
-
.footer_wrap a:hover,
-
span:hover {
-
background-color: #555;
-
}
-
-
.top {
-
padding-top: 62px;
-
}
-
-
.footer_wrap .router-link-active {
-
background-color: #000;
-
}
-
</style>
3.在src下面新建views文件夾并創(chuàng)建我們需要的.vue文件
3.1 find.vue
-
<template>
-
<div>
-
<div class="nav_main">
-
<router-link to="/Ranking">排行</router-link>
-
<router-link to="/Recommend">推薦</router-link>
-
<router-link to="/SongList">歌單</router-link>
-
</div>
-
-
<div style="1px solid red;">
-
<router-view></router-view>
-
</div>
-
</div>
-
</template>
-
-
<script>
-
export default {
-
name: 'find',
-
}
-
</script>
-
-
<style scoped>
-
.nav_main {
-
background-color: red;
-
color: white;
-
padding: 10px 0;
-
}
-
.nav_main a {
-
text-align: center;
-
text-decoration: none;
-
color: white;
-
font-size: 12px;
-
margin: 7px 17px 0;
-
padding: 0px 15px 2px 15px;
-
height: 20px;
-
display: inline-block;
-
line-height: 20px;
-
border-radius: 20px;
-
}
-
.nav_main a:hover {
-
background-color: brown;
-
}
-
.nav_main .router-link-active{
-
background-color: brown;
-
}
-
</style>
3.2 my.vue
-
<template>
-
<div>
-
<img src="../assets/my.png" alt="" width="100%">
-
</div>
-
</template>
-
-
<script>
-
export default {
-
name: 'my',
-
};
-
</script>
-
-
<style scoped>
-
-
</style>
3.3 friend.vue
-
<template>
-
<div>
-
<ul>
-
<li>這是當前頁面 query 接收到的參數(shù):
-
<span>姓名:{{ $route.query.name }}</span> --
-
<span>年齡:{{$route.query.age}}</span>
-
</li>
-
<li>這是當前頁面 params 接收到的參數(shù):
-
<!-- <span>姓名:{{ $route.params.name }}</span> --
-
<span>年齡:{{ $route.params.age }}</span> -->
-
</li>
-
</ul>
-
</div>
-
</template>
-
-
<script>
-
export default {
-
name: 'friend',
-
};
-
</script>
-
-
<style scoped>
-
-
</style>
3.4 notfound.vue
-
<template>
-
<div class="box">
-
<h1>這是一個 404 頁面</h1>
-
<img src="../assets/404.png" alt="">
-
</div>
-
</template>
-
-
<script>
-
export default {
-
name: 'notfound',
-
data() {
-
return {
-
-
};
-
},
-
-
};
-
</script>
-
-
<style scoped>
-
.box {
-
display: flex;
-
flex-direction: column;
-
justify-content: center;
-
align-items: center;
-
}
-
</style>
4.準備圖片素材(所有素材可私信博主獲?。?
5.所有準備工作做完現(xiàn)在開始我們的文件配置
1.下載與導入vue-router
npm i vue-router@3.6.5
導入vue-router (在main.js中)
-
//main.js中導入
-
// 0.導入路由
-
import VueRouter from 'vue-router'
-
// 使用vue的插件,都需要調用Vue.use()
-
Vue.use(VueRouter)
2.導入組件
@符號代表 /src 文件夾的絕對路徑,在腳手架中文件比較多的時候,使用這個@符號會更加的方便
在main.js中導入
-
// 導入組件
-
import find from '@/views/find.vue'
-
import friend from '@/views/friend.vue'
-
import my from '@/views/my.vue'
-
import notfound from '@/views/notfound.vue'
3.創(chuàng)建路由規(guī)則
路由規(guī)則作用: 設置 url 和 組件 對應的規(guī)則
在main.js中寫入
-
// 路由規(guī)則
-
const routes = [
-
{ path: '/find', component: find },
-
{ path: '/friend', name: 'friend', component: friend },
-
{ path: '/my', component: my },
-
{ path: '/notfound', component: notfound },
-
]
4.創(chuàng)建路由對象
路由對象: 幫你管理這些路由規(guī)則
在main.js中寫入
-
// 創(chuàng)建路由對象
-
const router = new VueRouter({
-
routes// (縮寫) 相當于 routes: routes
-
})
5.掛載路由到根組件
掛載到根組件作用:讓你的整個應用都有路由功能
在main.js中寫入
-
// 掛載路由到根組件
-
new Vue({
-
router,
-
render: h => h(App)
-
}).$mount('#app')
6.在頁面寫路由導航router-link
作用與a標簽一樣實現(xiàn)跳轉,好處:當點擊鏈接的時候自帶一個專屬類名
在App.vue中我們將傳統(tǒng)的a標簽進行替換:
替換a標簽原因:便于我們做專屬效果
我們選中點擊的超鏈接做觸發(fā)效果:
7在頁面寫路由出口router-view
占位盒子,用于渲染路由匹配到的組件
(<router-view> : 是vue內置的一個組件,會自動替換成路由匹配的組件 )
好了一個最最最基本的路由就被我們制作完成啦!下面我們來看看效果:
上述的操作有些許麻煩,下面我們來使用我們開發(fā)中常用的自動配置方法
創(chuàng)建腳手架方式與手動配置類似,唯一不同是此處必須選擇Router
對比手動模式:
此刻:腳手架已經(jīng)幫我們創(chuàng)建好了Router路由不需要我們下載與導入vue-router了
只需要寫:
- 導入組件
- 配置路由規(guī)則
- 路由導航
- 路由出口
并且為了進一步的封裝我們的配置信息,我們的配置代碼將寫在router/index.js下,不再是全部寫在main.js下。
1.導入組件(index.js中)
-
import find from '@/views/find.vue'
-
import friend from '@/views/friend.vue'
-
import my from '@/views/my.vue'
-
import notfound from '@/views/notfound.vue'
2.配置路由規(guī)則(index.js中)
-
{ path: '/find', component: find },
-
{ path: '/friend', name: 'friend', component: friend },
-
{ path: '/my', component: my },
-
{ path: '/notfound', component: notfound }
3.路由導航(直接cv我們之前的App.vue文件)
-
<router-link to="/find">發(fā)現(xiàn)音樂</router-link>
-
<router-link to="/my">我的音樂</router-link>
-
<router-link to="/friend">朋友</router-link>
4.路由出口(App.vue中)
-
<div class="top">
-
<router-view></router-view>
-
</div>
效果查看:
自動配置省去了一些固定不變的操作,我們不需要寫繁瑣且固定的代碼,只需要寫不同的代碼。且代碼書寫的位置都給我們設置好了,我們直接遵守該規(guī)范書寫代碼即可
路由重定向官方文檔:重定向和別名 | Vue Router
重定向應用場景
: 頁面輸入根路徑/ , 自動跳轉到首頁
注意點
: 重定向只是修改路徑, 還需要單獨去設置路由匹配規(guī)則
重定向命令:
-
{
-
path: '/',
-
/*
-
(1)重定向只是修改頁面路徑。 輸入 / 會重定向到 /路徑
-
(2)只有component才會讓vue去尋找路由匹配頁面。所以設置了重定向,還需要單獨設置匹配規(guī)則
-
*/
-
redirect: "路徑"
-
},
1. 就拿我們剛才創(chuàng)建的舉例:
實現(xiàn)效果:當我在瀏覽器中打開的時候我沒有輸入任何路徑,vue自動幫我們跳轉到了 my.vue這個頁面組件
2.也可以利用重定向來設置當我們路徑錯誤提示404頁面:
實現(xiàn)效果:當我任意輸入沒有匹配的路徑,自動幫我們跳轉到了notfound.vue這個組件
實現(xiàn)頁面中存在第二級的跳轉
寫法(拿我們上述的案例實操,需要素材可私信博主喔):
①在index.js中引入
-
// 導入二級路由
-
import Ranking from '@/views/second/Ranking.vue'
-
import Recommend from '@/views/second/Recommend.vue'
-
import SongList from '@/views/second/SongList.vue'
②在需要引用的組件中使用:
-
//格式:
-
{
-
path: '路徑', component: 組件名, children: [
-
//此處填寫二級路由的路徑信息
-
]
-
}
-
{
-
path: '/find', component: find, children: [
-
{path:'/',redirect:'/SongList'},
-
{ path: '/Ranking', component: Ranking },
-
{ path: '/Recommend', component: Recommend },
-
{ path: '/SongList', component: SongList }
-
]
-
}
③寫路由導航與出口
查看效果:
可以看到:當我們點擊一級路由之后,我們還可以點擊二級路由到我們的專屬頁面中
有兩種跳轉傳參方式:
- 聲明式導航
- 編程式導航
①query寫法:
在路徑中加參數(shù)信息即可
<router-link to="/路徑?參數(shù)名=參數(shù)值&參數(shù)名=參數(shù)值</router-link>
接收信息:
在觸發(fā)的組件中書寫{{ $route.query.屬性名}}接收
舉個例子:
②params寫法:
在index.jsx文件中寫:參數(shù)名。在需要傳遞的路由路徑中寫參數(shù)值
接收信息:
在觸發(fā)的組件中書寫{{ $route.params.屬性名}}接收
實現(xiàn)效果:
①query寫法:
結構:
-
this.$router.push({
-
path: '/路徑',
-
query: { 屬性名: '屬性值'}
-
})
接收信息:
在觸發(fā)的組件中書寫{{ $route.query.屬性名}}接收
舉個例子:
②params寫法
結構:
-
this.$router.push({
-
name: '我們注冊路徑的組件名',//寫path獲取不到值?。?!
-
query: { 屬性名: '屬性值'}
-
})
注意點:寫path獲取不到值,需要用name
接收信息:
在觸發(fā)的組件中書寫{{ $route.params.屬性名}}接收
分享此文一切功德,皆悉回向給文章原作者及眾讀者.
免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯(lián)系,我們立即更正或刪除。
藍藍設計( www.yvirxh.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業(yè)提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網(wǎng)站建設 、平面設計服務、UI設計公司、界面設計公司、UI設計服務公司、數(shù)據(jù)可視化設計公司、UI交互設計公司、高端網(wǎng)站設計公司、UI咨詢、用戶體驗公司、軟件界面設計公司
目錄
上部分為標題、中間為表單、底部為確定按鈕
底部背景、標題文本、右上角關閉按鈕
祝福語文本、紅包數(shù)量文本、紅包總金額、當前余額文本顯示、以及前往充值按鈕
左邊為需支付金額顯示,右邊為取消和確定按鈕
圖片寬度380px像素,高度56px像素
2)背景圖片自動填充
布局一個div,寬度為400px像素,高度為56px像素,然后再設置背景圖片樣式,由于圖片本身寬度小于div寬度,div會多出20px像素,圖片會自動填充,默認效果如下
-
<div style="width:400px;height:56px;background:url(/1674461966454.jpg);background-size: 100%;">
-
-
</div>
3)圖片百分比顯示
再給div設置背景百分比縮放顯示,效果如下
background-size: 100%;
4)文本
布局一個span標簽,顯示"添加紅包"文本,白色黑體,18號字體,加粗,左對齊,且左邊距20px像素。并設置div標簽56px像素垂直居中樣式,效果如下
5)關閉按鈕
在右上角添加一個關閉按鈕,一般可以設置一個svg標簽圖標,設置高28px,寬36px
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。這樣關閉按鈕圖標就會以它所在的父級定位,否則可能會布局錯位,比如下面錯位效果
-
<style type="text/css">
-
.title { width: 400px; height: 56px; background: url(/1674461966454.jpg); background-size: 100%; line-height: 56px;position:relative; }
-
.title-text { font-size: 18px; font-weight: bold; color: #fff; font-family: 黑體; margin-left: 20px; }
-
.close { position: absolute; top: 0px; right: 0px; width: 36px; height: 28px; }
-
</style>
-
-
<div class="title">
-
<span class="title-text">添加紅包</span>
-
<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="">
-
</div>
1)組成元素
紅色星號、文本、輸入文本框、刷新文本按鈕
2)calc函數(shù)
它屬于css3的功能,calc() 函數(shù)用于動態(tài)計算長度值。對于布局非常有作用。
需要特別注意,函數(shù)內的參數(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ù)變量保存。
并且給右邊的刷新按鈕綁定點擊事件,然后在事件內使用隨機函數(shù)進行隨機顯示
-
<script type="text/javascript">
-
$(function () {
-
-
// 祝福語
-
var labelText = ['成就一億技術人!', '節(jié)日快樂', 'Hello World', '新春大吉!', '大吉大利', 'Bug Free'];
-
$('.cl-input img').click(function () {
-
// Math.random() - 隨機函數(shù)會產(chǎn)生0~1之間的值
-
var index = parseInt(Math.random() * labelText.length);
-
var text = labelText[index];
-
$('.cl-input input').val(text);
-
});
-
});
-
</script>
-
<div class="content-label">
-
<div class="cl-text">
-
<span style="color:#f00;">*</span>
-
<span>祝福語</span>
-
</div>
-
<div class="cl-input">
-
<input placeholder="請?zhí)顚懠t包祝福語或標題" value="成就一億技術人!" />
-
<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="">
-
</div>
-
</div>
布局和祝福語一樣,刷新按鈕換成了單位文本。
這里文本框有個離開焦點事件,如果判斷沒有輸入值,那么提示”請輸入數(shù)量",并且紅包數(shù)量只能是正整數(shù),文本框也變?yōu)榧t色邊框,默認則為藍色邊框
-
<div class="content-label">
-
<div class="cl-text">
-
<span style="color:#f00;">*</span>
-
<span>紅包數(shù)量</span>
-
</div>
-
<div class="cl-input">
-
<input placeholder="請?zhí)顚懠t包數(shù)量" value="" />
-
<span>個</span>
-
</div>
-
</div>
-
$("#txtCount").blur(function () {
-
txtCount = $(this).val();
-
if (txtCount == undefined || txtCount == null || txtCount == '' || txtCount.trim() == '') {
-
$("i", $(this).parent()).show().html('請輸入數(shù)字!');
-
$(this).parent().addClass('red-border');
-
}
-
else {
-
if (txtCount <= 0) {
-
$("i", $(this).parent()).show().html('請輸入有效數(shù)字格式!');
-
$(this).parent().addClass('red-border');
-
}
-
else if (!isNaN(txtCount)) {
-
$("i", $(this).parent()).hide();
-
$(this).parent().removeClass('red-border');
-
}
-
else {
-
-
}
-
}
-
});
布局和前面一樣,這就是前端布局的魅力,有很多可以重用的東西
-
<div class="content-label">
-
<div class="cl-text">
-
<span style="color:#f00;">*</span>
-
<span>紅包總金額</span>
-
</div>
-
<div class="cl-input">
-
<input placeholder="請?zhí)顚懠t包總金額" value="" />
-
<span>元</span>
-
</div>
-
</div>
這里的布局和前面稍微多點東西,布局差不多。
這里只做讀取展示用,也可以用input輸入文本框,設置默認只讀即可
-
<div class="content-label">
-
<div class="cl-text">
-
<span style="color:#f00;">*</span>
-
<span>余額支付</span>
-
</div>
-
<div class="cl-input">
-
<label>當前余額:<b>51.25</b> 元</label>
-
<span class="span">前往充值 > </span>
-
</div>
-
</div>
當點擊文本框時,先判斷是否已經(jīng)提示無效信息,也就是已經(jīng)有紅色邊框,有則不顯示藍色邊框,沒有則顯示藍色邊框。當離開文本框焦點,那么則移除藍色邊框
-
// 文本框點擊事件
-
$('.cl-input input').click(function () {
-
var className = $(this).parent().attr('class');
-
if (className.indexOf('red-border') < 0) {
-
$(this).parent().addClass('blue-border');
-
}
-
}).blur(function () {
-
$(this).parent().removeClass('blue-border');
-
});
1)支付額文本
這里布局左定位,金額數(shù)字加紅色字體
2)取消和確認按鈕
取消按鈕鼠標移動上去邊框變深,直接使用css的hover屬性即可完成。
確認按鈕的效果使用同樣的方式
3)布局效果
4)布局代碼
-
<!--按鈕-->
-
<div class="button">
-
<div class="price">
-
<span>需支付:</span>
-
<span id="priceSpan" style="font-size:20px;color:#f00;">0.00</span>
-
<span>元</span>
-
</div>
-
<div class="btn">
-
<div class="btnCancel">
-
<span>取消</span>
-
</div>
-
<div class="btnOk not-allowed">
-
<span>確定</span>
-
</div>
-
</div>
-
</div>
5)交互代碼
-
// 紅包個數(shù)
-
var txtCount = 0;
-
var txtPrice = 0;
-
$("#txtCount").keyup(function () {
-
txtCount = $(this).val();
-
$("#priceSpan").html(txtCount * txtPrice);
-
});
-
-
// 紅包總金額
-
$("#txtPrice").keyup(function () {
-
txtPrice = $(this).val();
-
$("#priceSpan").html(txtPrice);
-
});
紅包數(shù)量和紅包金額那里還有幾個交互和邏輯判斷,有興趣的小伙伴可以自己實現(xiàn)下,有疑問的可咨詢了解
完整代碼可以查看gitCode:小5聊 / Csdn Red Bag Html · GitCode
calc()函數(shù) | 可用于高寬度精準布局,更加合理布局 |
position和relative | 相對和絕對定位,同樣有助于合理定位和布局 |
Math.random() | 隨機函數(shù),隨機產(chǎn)生0~1的值 |
keyup() | 鍵盤彈上事件 |
click() | 元素點擊事件 |
blur() | 離開焦點事件 |
總結:前端布局,要玩出花樣和效果,還是需要點藝術天賦??傊τ腥さ?,剛入門可能會覺得比較難,當你熟練之后,還是挺有趣的!
分享此文一切功德,皆悉回向給文章原作者及眾讀者.
免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯(lián)系,我們立即更正或刪除。
藍藍設計( www.yvirxh.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業(yè)提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網(wǎng)站建設 、平面設計服務、UI設計公司、界面設計公司、UI設計服務公司、數(shù)據(jù)可視化設計公司、UI交互設計公司、高端網(wǎng)站設計公司、UI咨詢、用戶體驗公司、軟件界面設計公司
藍藍設計的小編 http://www.yvirxh.cn