首頁

停止犯下這5個JavaScript風(fēng)格錯誤,使你的代碼可讀和可維護(hù)的快速提示

seo達(dá)人

使你的代碼可讀和可維護(hù)的快速提示。


有多少次,你打開一個舊的項(xiàng)目,發(fā)現(xiàn)混亂的代碼,當(dāng)你添加一些新的東西時,很容易崩潰?我們都有過這樣的經(jīng)歷。


為了減少難以讀懂的javascript的數(shù)量,我提供了以下示例。這些都是我過去所犯過的錯誤。


對具有多個返回值的函數(shù)使用數(shù)組解構(gòu)

假設(shè)我們有一個返回多個值的函數(shù)。一種可能的實(shí)現(xiàn)是使用數(shù)組解構(gòu),如下所示:


const func = () => {

 const a = 1;

 const b = 2;

 const c = 3;

 const d = 4;

 return [a,b,c,d];

}

const [a,b,c,d] = func();

console.log(a,b,c,d); // 1,2,3,4

盡管上面的方法很好用,但確實(shí)引入了一些復(fù)雜性。


當(dāng)我們調(diào)用函數(shù)并將值分配給 a,b,c,d 時,我們需要注意返回數(shù)據(jù)的順序。這里的一個小錯誤可能會成為調(diào)試的噩夢。


此外,無法確切指定我們要從函數(shù)中獲取哪些值,如果我們只需要 c 和 d 怎么辦?


相反,我們可以使用對象解構(gòu)。


const func = () => {

 const a = 1;

 const b = 2;

 const c = 3;

 const d = 4;

 return {a,b,c,d};

}

const {c,d} = func();

現(xiàn)在,我們可以輕松地從函數(shù)中選擇所需的數(shù)據(jù),這也為我們的代碼提供了未來的保障,允許我們在不破壞東西的情況下增加額外的返回變量。


不對函數(shù)參數(shù)使用對象分解

假設(shè)我們有一個函數(shù),該函數(shù)將一個對象作為參數(shù)并對該對象的屬性執(zhí)行一些操作。一種幼稚的方法可能看起來像這樣:


// 不推薦

function getDaysRemaining(subscription) {

 const startDate = subscription.startDate;

 const endDate = subscription.endDate;

 return endDate - startDate;

}

上面的方法按預(yù)期工作,但是,我們創(chuàng)建了兩個不必要的臨時引用 startDate 和 endDate。


一種更好的實(shí)現(xiàn)是對 subscription 對象使用對象解構(gòu)來在一行中獲取 startDate 和 endDate。


// 推薦

function getDaysRemaining(subscription) {

 const { startDate, endDate } = subscription;

 return startDate - endDate;

}

我們可以更進(jìn)一步,直接對參數(shù)執(zhí)行對象析構(gòu)。


// 更好

function getDaysRemaining({ startDate, endDate }) {

 return startDate - endDate;

}

更優(yōu)雅,不是嗎?


在不使用擴(kuò)展運(yùn)算符的情況下復(fù)制數(shù)組

使用 for循環(huán)遍歷數(shù)組并將其元素復(fù)制到新數(shù)組是冗長且相當(dāng)丑陋的。


可以以簡潔明了的方式使用擴(kuò)展運(yùn)算符來達(dá)到相同的效果。


const stuff = [1,2,3];


// 不推薦

const stuffCopyBad = []

for(let i = 0; i < stuff.length; i++){

 stuffCopyBad[i] = stuff[i];

}


// 推薦

const stuffCopyGood = [...stuff];

使用var

使用 const 保證不能重新分配變量。這樣可以減少我們代碼中的錯誤,并使其更易于理解。


// 不推薦

var x = "badX";

var y = "baxY";


// 推薦

const x = "goodX";

const y = "goodX";

果你確實(shí)需要重新分配變量,請始終選擇 let 而不是 var。


這是因?yàn)?let 是塊作用域的,而 var 是函數(shù)作用域的。


塊作用域告訴我們,只能在定義它的代碼塊內(nèi)部訪問變量,嘗試訪問塊外部的變量會給我們提供ReferenceError。


for(let i = 0; i < 10; i++){

 //something

}

print(i) // ReferenceError: i is not defined

函數(shù)作用域告訴我們,只能在定義其的函數(shù)內(nèi)部訪問變量。


for(var i = 0; i < 10; i++){

 //something

}

console.log(i) // 10

let 和 const 都是塊范圍的。


不使用模板字面值

手動將字符串連接在一起相當(dāng)麻煩,而且輸入時可能會造成混淆。這是一個例子:


// 不推薦

function printStartAndEndDate({ startDate, endDate }) {

 console.log('StartDate:' + startDate + ',EndDate:' + endDate)

}

模板文字為我們提供了一種可讀且簡潔的語法,該語法支持字符串插值。


// 推薦

function printStartAndEndDate({ startDate, endDate }) {

 console.log(`StartDate: ${startDate}, EndDate: ${endDate}`)

}

模板文字也提供了嵌入新行的簡便方法,你所需要做的就是照常按鍵盤上的Enter鍵。


// 兩行打印

function printStartAndEndDate({ startDate, endDate }) {

 console.log(`StartDate: ${startDate}

 EndDate: ${endDate}`)

}

藍(lán)藍(lán)設(shè)計sillybuy.com )是一家專注而深入的界面設(shè)計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計、BS界面設(shè)計 、 cs界面設(shè)計 、 ipad界面設(shè)計 、 包裝設(shè)計 、 圖標(biāo)定制 、 用戶體驗(yàn) 、交互設(shè)計、 網(wǎng)站建設(shè) 平面設(shè)計服務(wù)

如何推進(jìn)多方合作的A/B測試項(xiàng)目?

資深UI設(shè)計者

在多方合作的項(xiàng)目中,我們需要規(guī)劃項(xiàng)目的合理落地方案,并在執(zhí)行過程中和各方有效溝通。結(jié)合近期羚瓏商家合作測試項(xiàng)目的實(shí)踐經(jīng)歷,聊聊我在項(xiàng)目中的心得體會。

項(xiàng)目背景

我們想了解京東首焦banner中,設(shè)計因素對點(diǎn)擊效果的影響情況。做這件事最大的限制在于投放數(shù)據(jù)會受多種因素影響,不僅是一個設(shè)計因素的選擇,還有比如人群、出價、品牌、類目等因素的不同,都能影響到最終的投放結(jié)果。因此,從總體樣本中取樣進(jìn)行分析的意義不大。為了解決上述問題,我們招募了一些能控制其他因素的品牌廣告主,與有能力支持投放的測試投放系統(tǒng)合作,共同完成A/B測試。

需求拆解與規(guī)劃

不難發(fā)現(xiàn)這個需求會涉及到多個項(xiàng)目角色,意味著將有復(fù)雜的推進(jìn)流程,需要提前拆解與規(guī)劃,才能保證項(xiàng)目進(jìn)度可控。

如何推進(jìn)多方合作的A/B測試項(xiàng)目?來看京東的實(shí)戰(zhàn)案例!

△ 測試項(xiàng)目流程與分工

我們可以分三步來進(jìn)行:

1. 找到項(xiàng)目關(guān)鍵步驟

關(guān)鍵步驟是將一個項(xiàng)目的推進(jìn)拆解成多個階段,找到關(guān)鍵步驟,也就知道了每個階段的主要任務(wù),可以進(jìn)一步分工來推進(jìn)項(xiàng)目。

如何找到關(guān)鍵步驟?我們可以從項(xiàng)目目標(biāo)中提取。測試項(xiàng)目的目標(biāo)是找到設(shè)計因素與投放點(diǎn)擊效果的影響關(guān)系。這個目標(biāo)里提取重要的關(guān)鍵詞為:設(shè)計因素、投放點(diǎn)擊效果、影響關(guān)系。面對這些關(guān)鍵詞我們會有疑問產(chǎn)生如「測試設(shè)計因素是什么?有哪些?」、「如何投放」、「如何判斷影響關(guān)系」,再進(jìn)行串聯(lián)梳理,得到完整步驟流程。

2. 明確角色任務(wù)與產(chǎn)出

每個階段的主要任務(wù),可以拆解分工給項(xiàng)目角色,項(xiàng)目角色也就有了各自的任務(wù),角色產(chǎn)出物則是任務(wù)執(zhí)行的結(jié)果,將直接推動項(xiàng)目進(jìn)入下一環(huán)節(jié)。所以為了順利推進(jìn)項(xiàng)目,我們需要根據(jù)項(xiàng)目實(shí)際情況評估角色任務(wù)分工是否合理,產(chǎn)出是否滿足項(xiàng)目要求。

比如在「設(shè)計測試圖片」這個步驟中,有兩個分工方案,讓廣告主或我們自己設(shè)計圖片。我們從項(xiàng)目時長、溝通成本、潛在風(fēng)險等維度進(jìn)行評估,判斷廣告主把控變量不嚴(yán)謹(jǐn)會導(dǎo)致測試數(shù)據(jù)無效,且外部合作溝通成本較高時間不夠,所以最后將設(shè)計圖片的任務(wù)分給了內(nèi)部。

3. 預(yù)判項(xiàng)目風(fēng)險

對流程規(guī)劃得越詳細(xì),在后續(xù)合作過程中越容易把控項(xiàng)目的節(jié)奏,項(xiàng)目風(fēng)險越低。

再如「設(shè)計測試圖片」這個關(guān)鍵步驟,詳細(xì)展開執(zhí)行流程會發(fā)現(xiàn)涉及到交互設(shè)計師、兩方視覺設(shè)計師、廣告主四個角色。對于項(xiàng)目執(zhí)行角色,產(chǎn)出物的質(zhì)量及按時交付尤為重要,所以重點(diǎn)把控輸出準(zhǔn)確性與完成時間。對于項(xiàng)目決策角色,也就是決策最終投放哪些圖片的廣告主,溝通配合尤為重要。所以基于規(guī)避風(fēng)險也對項(xiàng)目流程進(jìn)行了優(yōu)化,前置在項(xiàng)目之初,要求廣告主提前準(zhǔn)備交付內(nèi)容,規(guī)定交付時間及格式,以及充分溝通說明圖片設(shè)計產(chǎn)出之后不能進(jìn)行較大改動。

結(jié)論推導(dǎo)的重要前提與方法

1. 保證數(shù)據(jù)有效

測試結(jié)論來源于測試數(shù)據(jù),我們首先應(yīng)該保證回收數(shù)據(jù)的有效性。測試項(xiàng)目的關(guān)鍵指標(biāo)是點(diǎn)擊率,即點(diǎn)擊量與曝光量的比值。當(dāng)圖片本身曝光量低時,我們認(rèn)為隨著曝光量增加,點(diǎn)擊率比值波動范圍仍然較大,數(shù)據(jù)還未穩(wěn)定在某個區(qū)間段,會影響結(jié)論準(zhǔn)確性,判定為無效數(shù)據(jù)。發(fā)現(xiàn)類似這種問題,我們會和廣告主商量繼續(xù)投放,延長測試時間來增加曝光。

2. 充分測試

要想得到可靠普適的結(jié)論,需要對比多組樣本的測試結(jié)果。對于某個設(shè)計因素,我們先進(jìn)行了單一廣告主的投放數(shù)據(jù)對比,可以找到投放效果最優(yōu)和最差的設(shè)計水平。然后又將多個廣告主的結(jié)果進(jìn)行對比,會發(fā)現(xiàn)存在不一致的情況,驗(yàn)證了單組樣本結(jié)論不能作為類目結(jié)論輸出。如果多個廣告主結(jié)果一致,或呈現(xiàn)某一趨勢,則結(jié)論在該類目可以認(rèn)為較為普適。

3. 差異分析

對于多組樣本結(jié)果不一致的情況,可以從組間因素差異著手分析。

如何推進(jìn)多方合作的A/B測試項(xiàng)目?來看京東的實(shí)戰(zhàn)案例!

△ 背景設(shè)計因素測試結(jié)果

上圖是兩個廣告主分別測試背景設(shè)計因素得到的結(jié)果。第一組的投放結(jié)果為實(shí)景設(shè)計效果更好,第二組則為普通平面設(shè)計效果更好。產(chǎn)生這樣差異的原因是什么呢?我們先找出組間可能導(dǎo)致這一結(jié)果的因素,分別是顏色和產(chǎn)品。從顏色上看,是否平面+黑色效果更好呢?我們看了其他廣告主結(jié)果,否定了這一猜想。再從產(chǎn)品圖來看,兩個產(chǎn)品的識別度是不同的,我們將其他廣告主該因素測試圖按產(chǎn)品是否容易識別分組,最終得出兩組不同的結(jié)論:當(dāng)產(chǎn)品圖易識別時,背景設(shè)計對效果影響不大;當(dāng)產(chǎn)品圖不易識別時,實(shí)景圖效果更好。這也就解釋了上圖結(jié)果不一致的原因。

回顧整個項(xiàng)目,我個人認(rèn)為項(xiàng)目中最重要的工作是溝通。下面我來分別談?wù)剝?nèi)外部溝通的經(jīng)驗(yàn)。

雙贏是外部合作溝通的基石

與外部團(tuán)隊、廣告主合作推進(jìn)項(xiàng)目,需要及時有效的溝通,什么是有效的溝通呢?

1. 圍繞對方利益談配合

廣告主只看轉(zhuǎn)化結(jié)果,我們?nèi)绻徽勗O(shè)計不談轉(zhuǎn)化,廣告主是不會想要出錢參與項(xiàng)目的,那么項(xiàng)目也將停滯不前。所以在合作前,我們做了項(xiàng)目及團(tuán)隊包裝,用真實(shí)的案例讓廣告主快速理解參與項(xiàng)目所能帶來的價值,并用團(tuán)隊以往的作品、能力展示讓廣告主了解與我們合作的優(yōu)勢。廣告主越認(rèn)同項(xiàng)目價值及我們的專業(yè)度,配合度就會越高。

如何推進(jìn)多方合作的A/B測試項(xiàng)目?來看京東的實(shí)戰(zhàn)案例!

△ 招募PPT中的真實(shí)案例介紹

2. 圍繞對方目標(biāo)來「推銷」方案

在推進(jìn)項(xiàng)目這一點(diǎn)上,找到目標(biāo)一致的點(diǎn)更容易促成各方意見達(dá)成一致。

我們合作的廣告主很多會選擇外包banner設(shè)計,所以廣告主們習(xí)慣了做傳說中的「甲方爸爸」,難免會對視覺設(shè)計方案有各種主觀意見。比如,某電視廣告主不喜歡紅色圖片設(shè)計,想要藍(lán)色。對于這樣的分歧,我個人喜歡用引導(dǎo)式的溝通方法。首先,不要急于表達(dá)自己或否定對方的意見,可以以疑問句式來猜測對方的目的?!赶矚g藍(lán)色是希望用沉穩(wěn)的顏色來表現(xiàn)產(chǎn)品的高級感嗎?」,如果猜測正確,對方會因自己的需求被理解而更容易溝通,這時再繼續(xù)闡述用紅色如何表達(dá)高級感;如果猜測不正確,對方會順勢說出原因,我們再圍繞對方的目標(biāo)進(jìn)一步溝通。如果對方毫無理由「不喜歡這個設(shè)計」,而設(shè)計師并不覺得有設(shè)計問題,那么我們需要停止專業(yè)角度的溝通,從設(shè)計是否滿足當(dāng)前階段項(xiàng)目需求的角度來溝通,方案則更容易被接受。

內(nèi)部合作各盡所能發(fā)揮優(yōu)勢

內(nèi)部合作分交互、視覺、用研三種不同的崗位角色,在項(xiàng)目中都發(fā)揮著自己重要的作用。

交互擅長統(tǒng)籌與拆解問題,團(tuán)隊的內(nèi)部溝通能產(chǎn)生多種解題思路,對項(xiàng)目的推進(jìn)至關(guān)重要;在遇到如需要統(tǒng)計學(xué)分析、樣本設(shè)置等專業(yè)問題時,用研可以提供更專業(yè)的分析方法與幫助,為我們實(shí)現(xiàn)科學(xué)分析提供有力支持;視覺設(shè)計師對banner設(shè)計有豐富的經(jīng)驗(yàn),可以在各個環(huán)節(jié)中發(fā)揮優(yōu)勢。從項(xiàng)目之初就參與設(shè)計因素拆解、測試方案設(shè)置,可以補(bǔ)充視覺相關(guān)的設(shè)計因素,在優(yōu)化測試方案、風(fēng)險預(yù)期方面都可以提供重要的建議。在結(jié)論推導(dǎo)中,對圖中的因素差異敏感度高,可以根據(jù)數(shù)據(jù)提出關(guān)鍵猜想。

文章來源:優(yōu)設(shè)    作者:京東設(shè)計中心JDC

藍(lán)藍(lán)設(shè)計sillybuy.com )是一家專注而深入的界面設(shè)計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計、BS界面設(shè)計 、 cs界面設(shè)計 、 ipad界面設(shè)計 、 包裝設(shè)計 、 圖標(biāo)定制 、 用戶體驗(yàn) 、交互設(shè)計、 網(wǎng)站建設(shè) 、平面設(shè)計服務(wù)

如何為你的UI制定一套色彩系統(tǒng)?

資深UI設(shè)計者

色彩在UI設(shè)計中的作用:加深品牌印象與品牌感、引導(dǎo)用戶視覺凹增加易讀性、區(qū)分信息交互的狀態(tài)、營造氛圍傳遞熱度……

前言

不管是做 UI 設(shè)計還是畫插畫,有很多同學(xué)覺得自己是因?yàn)樘熨x不夠所以對色彩的敏感度不夠,其實(shí)不然。一個可能是大家總結(jié)的太少,從來都是憑感覺和運(yùn)氣去配色,但配色都是有講究的。

一個設(shè)計作品呈現(xiàn)到用戶面前,第一眼進(jìn)入眼簾的就是產(chǎn)品的視覺表現(xiàn),而產(chǎn)品的色彩在其中起到了舉足輕重的作用,毫無疑問色彩搭配對于設(shè)計師來說是非常重要的。那么具體到實(shí)際項(xiàng)目中該使用什么怎樣的色彩,需要怎么做呢?

用戶界面是一個設(shè)計師用理性思維解決用戶感性需求的窗口。如果對色彩的運(yùn)用不加以克制,界面可能會顯得花哨而沒有主次;但過于拘謹(jǐn)又容易使界面保守,難以激發(fā)用戶情緒,下面以Bee express項(xiàng)目的實(shí)例來理性推導(dǎo)制定一套色彩系統(tǒng)。

切勿直奔主題

做過設(shè)計的同學(xué)應(yīng)該都知道顏色模式:RGB、CMYK、Lab 等等,這里不做過多的解釋了。另外每個顏色具有一定的性格特征和表達(dá)方式,而且都會有正反兩面。雖然每種色彩都有正向性格特征,但是我們在定位主體色之前一定要知道所選擇色彩的負(fù)面特征對企業(yè)是否會帶來負(fù)面的影響,

開始之前我們需要了解在配色過程中需要避免出現(xiàn)的問題,如果你經(jīng)常出現(xiàn)下列的問題,保證你在試用期內(nèi)一次性就能拿到全部薪資,emmm……

  • 高飽和度的色彩會造成我們的視覺疲勞及視幻;
  • 灰部使用過多的配色會使界面有一種臟兮兮、霧蒙蒙的感覺,甚至心情低落;
  • 沒有規(guī)律且過多的配色。如果你不是做五彩斑斕的黑,建議6、3、1的色彩配比,輔助色不超過3種;
  • 熒光色。使用這種色彩的,建議跟色彩對視,看誰堅持的更久,除非是你贏了;
  • 太輕柔的顏色-沒有重點(diǎn)且輕飄飄的感覺;
  • 現(xiàn)在很火的新擬物化設(shè)計對于部分(沒有絕對)產(chǎn)品可能會造成信息識別性很差;
  • 不要將對抗色重疊,否則你會很浮躁。

定位品牌色

雖然設(shè)計是相通的,但是在不同的設(shè)計領(lǐng)域進(jìn)行配色時,依然會存在巨大的區(qū)別。更換品牌的主體色,都不會是因?yàn)樵O(shè)計師自己的決定,而是公司在商業(yè)策略上優(yōu)先做出了調(diào)整,然后通過品牌視覺上的變更將這個信息傳遞給消費(fèi)者。

Bee Express快遞、速遞柜業(yè)務(wù)為主,前期的主色及視覺形象以橙黃色為主,為了避免視覺跳躍性太大,以及后期IP形象(蜜蜂吉祥物)打造,本次品牌色彩升級在原有基礎(chǔ)上優(yōu)化了色調(diào),以保證后期產(chǎn)品的易用性和延展性,并利用最科學(xué)、最適用的方式推導(dǎo)出輔助色,以提升應(yīng)用視覺的豐富性和感官體驗(yàn)。

express原主色:

如何為你的UI制定一套色彩系統(tǒng)?來看這個實(shí)戰(zhàn)案例!

為了不影響原有色調(diào)前期的視覺傳播,即在原有主體色的基礎(chǔ)上調(diào)整SHB的數(shù)值,讓色彩更具視覺沖擊力,在色彩襯托(字體、圖標(biāo))更清晰。

  • H(Hue:色相)
  • S(Saturation:飽和度)
  • B(Brightness:明度)

如何為你的UI制定一套色彩系統(tǒng)?來看這個實(shí)戰(zhàn)案例!

通過調(diào)整后的主體色也能看出,明亮清晰的主體色(品牌色)也更適合在界面中的運(yùn)用,為信息傳遞、引導(dǎo)操作、品牌價值帶來更大的提升。

  • 信息傳遞:產(chǎn)品的首要目的是傳遞用戶所需要的信息,這就需要界面有清晰的層級關(guān)系,明確、舒適的閱讀體驗(yàn)。
  • 引導(dǎo)操作:清晰合理的操作引導(dǎo),讓用戶能夠準(zhǔn)確地根據(jù)引導(dǎo)進(jìn)行下一步操作。
  • 品牌價值:很多同學(xué)會忽略這一點(diǎn),導(dǎo)致產(chǎn)品的界面與品牌關(guān)聯(lián)性差,整體界面沒有品牌感。

根據(jù)主體色推理同色系

同色系為統(tǒng)一的色相,使用中可以加深品牌色的感知,可以讓界面更有層次,同時可以讓界面保持色彩上的一致性,整體感較強(qiáng),產(chǎn)生低對比度的和諧美感,給人協(xié)調(diào)統(tǒng)一的感覺。

具體是指與品牌色 H(色相)一致,通過改變 S(飽和度)與 B(明度)變化產(chǎn)生的色組。分別往淺色/深色方向按均勻數(shù)據(jù)增減,各產(chǎn)生5個坐標(biāo)值。

如何為你的UI制定一套色彩系統(tǒng)?來看這個實(shí)戰(zhàn)案例!

綜上能看出,使用同一色系即可完成一個項(xiàng)目,但是對于中大型項(xiàng)目來說實(shí)在是過于單調(diào),沒有太多的層次感,因此我們需要多色搭配為輔。多色的輔助顏色可設(shè)定不同的任務(wù)屬性和情感表達(dá),再搭配中性色黑白灰,能賦予更多的變化和層次。

提取24色-鋪墊輔助色

根據(jù)主體色 H(色相)為基礎(chǔ),不斷地遞增、遞減 15,在 0-360 之間可以得出 24 個顏色,也就是將 360° 色環(huán)分割為 24 份,(24份在360°色環(huán)上,每一個色相的角度為15°),最終得到下圖24色。

如何為你的UI制定一套色彩系統(tǒng)?來看這個實(shí)戰(zhàn)案例!

選取輔助色

輔助色需要滿足的兩個條件:

和品牌色有明顯區(qū)分:避免所選輔助色感官上給用戶視覺區(qū)別與品牌色差距不大,傳遞的調(diào)性太過一致;

不能過于突兀:根據(jù)色彩原理,互補(bǔ)色是最能與品牌色本色產(chǎn)生視覺感官對比的顏色,但可能會有些突兀。為了讓顏色的輔助起到豐富畫面的作用,而不是反而讓整個版面顯得不和諧,所以選擇互補(bǔ)色的鄰近色作為輔助色,避免直接使用互補(bǔ)色。

  • 鄰近色:色相差值 15° 以內(nèi)的顏色為鄰近色;
  • 類似色:色相差值 30° 以內(nèi)的顏色為類似色;
  • 互補(bǔ)色:色相差值 180° 的顏色為互補(bǔ)色。

基于品牌色可衍生出 3 個輔助色:一個與品牌色傳遞調(diào)性有明顯區(qū)分的類似色;兩個互補(bǔ)色的鄰近色。

如何為你的UI制定一套色彩系統(tǒng)?來看這個實(shí)戰(zhàn)案例!

類似色搭配:使用色相相近的顏色,頁面元素不會相互沖突,更加協(xié)調(diào)有質(zhì)感。

互補(bǔ)色搭配:選擇使用互補(bǔ)色,最佳搭配是一種作為主色,另一種用于強(qiáng)調(diào)。它們有著非常強(qiáng)烈的對比度,用在需要特別強(qiáng)調(diào)某個元素時會非常有效。

視覺統(tǒng)一感官校準(zhǔn)

每一種顏色都有自己的「感官明度」,也就是發(fā)光度。根據(jù)現(xiàn)有的使用場景,類似色和互補(bǔ)色大都用在同層級的信息展示上,而當(dāng)我們將最終得到的輔助色擺放在一起之后發(fā)現(xiàn),雖然我們提取出的輔助色明度色值都一致,因?yàn)轭伾旧碜詭У母泄倜鞫葘傩杂兴鶇^(qū)別,導(dǎo)致視覺上會有明顯的明暗差別。需要通過發(fā)光度來進(jìn)行最終的顏色校正。

校準(zhǔn)方式:依次在輔助色上疊加一層純黑圖層,將該純黑圖層顏色模式調(diào)整為 Hue(色相),就可以通過無彩色系下的明度色值,進(jìn)行對比,使色彩視覺感官保持一致(青色和藍(lán)色屬冷色調(diào),固需加深)。

如何為你的UI制定一套色彩系統(tǒng)?來看這個實(shí)戰(zhàn)案例!

全色系輸出

根據(jù)上面同色系的明度、純度對比規(guī)則,對所有定義的輔助色進(jìn)行明度和純度的輔助色彩輸出,最終得到輔助色色板。H(色相)一致,通過改變 S(飽和度)與 B(明度)變化產(chǎn)生色組。分別往淺色/深色方向按均勻數(shù)據(jù)增減,各產(chǎn)生5個坐標(biāo)值

如何為你的UI制定一套色彩系統(tǒng)?來看這個實(shí)戰(zhàn)案例!

刪除最左側(cè)的3種同色系,因明度過低時,顏色已經(jīng)非常接近于黑色,色相在肉眼上幾乎已經(jīng)趨于一致。最后得到基于品牌色推導(dǎo)出的全色系色階色板。

如何為你的UI制定一套色彩系統(tǒng)?來看這個實(shí)戰(zhàn)案例!

如何為你的UI制定一套色彩系統(tǒng)?來看這個實(shí)戰(zhàn)案例!

總結(jié)

配色常常從確定主色開始,根據(jù)行業(yè)類型和視覺訴求的需要,選擇一種居于支配的色彩作為主調(diào)色彩,構(gòu)成畫面的整體色彩傾向。然后選擇輔色,添加點(diǎn)綴色,最后按照色彩組合的原則完成設(shè)計中的需求。

雖然有了以上的配色方式,但一套標(biāo)準(zhǔn)的色彩系統(tǒng)還會包含中性色規(guī)范、顏色的使用規(guī)范等等。相信解決了大部分的需求,剩下的工作也難不倒大家了。畢竟以上的方式只是給大家提供了一個理性科學(xué)的方法,如果想更加優(yōu)秀,還需要進(jìn)一步深入地去學(xué)習(xí)色彩理論知識,多看優(yōu)秀的配色作品提升審美,總之要多看、多實(shí)踐和多思考。

文章來源:優(yōu)設(shè)    作者:能量眼球

藍(lán)藍(lán)設(shè)計sillybuy.com )是一家專注而深入的界面設(shè)計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計、BS界面設(shè)計 、 cs界面設(shè)計 、 ipad界面設(shè)計 、 包裝設(shè)計 、 圖標(biāo)定制 、 用戶體驗(yàn) 、交互設(shè)計、 網(wǎng)站建設(shè) 平面設(shè)計服務(wù)

你可能不需要在 JavaScript 使用 switch 語句!

seo達(dá)人

沒有 switch 就沒有復(fù)雜的代碼塊

switch很方便:給定一個表達(dá)式,我們可以檢查它是否與一堆case子句中的其他表達(dá)式匹配。 考慮以下示例:


const name = "Juliana";


switch (name) {

 case "Juliana":

   console.log("She's Juliana");

   break;

 case "Tom":

   console.log("She's not Juliana");

   break;

}

當(dāng) name 為“Juliana”時,我們將打印一條消息,并立即中斷退出該塊。 在switch函數(shù)內(nèi)部時,直接在 case 塊使用 return,就可以省略break。


當(dāng)沒有匹配項(xiàng)時,可以使用 default 選項(xiàng):


const name = "Kris";


switch (name) {

 case "Juliana":

   console.log("She's Juliana");

   break;

 case "Tom":

   console.log("She's not Juliana");

   break;

 default:

   console.log("Sorry, no match");

}

switch在 Redux reducers 中也大量使用(盡管Redux Toolkit簡化了樣板),以避免產(chǎn)生大量的if。 考慮以下示例:


const LOGIN_SUCCESS = "LOGIN_SUCCESS";

const LOGIN_FAILED = "LOGIN_FAILED";


const authState = {

 token: "",

 error: "",

};


function authReducer(state = authState, action) {

 switch (action.type) {

   case LOGIN_SUCCESS:

     return { ...state, token: action.payload };

   case LOGIN_FAILED:

     return { ...state, error: action.payload };

   default:

     return state;

 }

}

這有什么問題嗎?幾乎沒有。但是有沒有更好的選擇呢?


從 Python 獲得的啟示

來自 Telmo 的這條 Tweet引起了我的注意。 他展示了兩種“switch”風(fēng)格,其中一種非常接近Python中的模式。


Python 沒有開關(guān),它給我們一個更好的替代方法。 首先讓我們將代碼從 JavaScript 移植到Python:


LOGIN_SUCCESS = "LOGIN_SUCCESS"

LOGIN_FAILED = "LOGIN_FAILED"


auth_state = {"token": "", "error": ""}



def auth_reducer(state=auth_state, action={}):

   mapping = {

       LOGIN_SUCCESS: {**state, "token": action["payload"]},

       LOGIN_FAILED: {**state, "error": action["payload"]},

   }


   return mapping.get(action["type"], state)

在 Python 中,我們可以使用字典來模擬switch 。 dict.get() 可以用來表示 switch 的 default 語句。


當(dāng)訪問不存在的key時,Python 會觸發(fā)一個 KeyError 錯誤:


>>> my_dict = {

   "name": "John",

   "city": "Rome",

   "age": 44

   }


>>> my_dict["not_here"]


# Output: KeyError: 'not_here'

.get()方法是一種更安全方法,因?yàn)樗粫l(fā)錯誤,并且可以為不存在的key指定默認(rèn)值:


>>> my_dict = {

   "name": "John",

   "city": "Rome",

   "age": 44

   }


>>> my_dict.get("not_here", "not found")


# Output: 'not found'

因此,Pytho n中的這一行:


return mapping.get(action["type"], state)

等價于 JavaScript中的:


function authReducer(state = authState, action) {

 ...

   default:

     return state;

 ...

}

使用字典的方式替換 switch

再次思考前面的示例:


const LOGIN_SUCCESS = "LOGIN_SUCCESS";

const LOGIN_FAILED = "LOGIN_FAILED";


const authState = {

 token: "",

 error: "",

};


function authReducer(state = authState, action) {

 switch (action.type) {

   case LOGIN_SUCCESS:

     return { ...state, token: action.payload };

   case LOGIN_FAILED:

     return { ...state, error: action.payload };

   default:

     return state;

 }

}

如果不使用 switch 我們可以這樣做:


function authReducer(state = authState, action) {

 const mapping = {

   [LOGIN_SUCCESS]: { ...state, token: action.payload },

   [LOGIN_FAILED]: { ...state, error: action.payload }

 };


 return mapping[action.type] || state;

}

這里我們使用 ES6 中的計算屬性,此處,mapping的屬性是根據(jù)兩個常量即時計算的:LOGIN_SUCCESS 和 LOGIN_FAILED。

屬性對應(yīng)的值,我們這里使用的是對象解構(gòu),這里 ES9((ECMAScript 2018)) 出來的。


const mapping = {

 [LOGIN_SUCCESS]: { ...state, token: action.payload },

 [LOGIN_FAILED]: { ...state, error: action.payload }

}

你如何看待這種方法?它對 switch 來說可能還能一些限制,但對于 reducer 來說可能是一種更好的方案。


但是,此代碼的性能如何?


性能怎么樣?

switch 的性能優(yōu)于字典的寫法。我們可以使用下面的事例測試一下:


console.time("sample");

for (let i = 0; i < 2000000; i++) {

 const nextState = authReducer(authState, {

   type: LOGIN_SUCCESS,

   payload: "some_token"

 });

}

console.timeEnd("sample");

測量它們十次左右,


for t in {1..10}; do node switch.js >> switch.txt;done

for t in {1..10}; do node map.js >> map.txt;done

clipboard.png


人才們的 【三連】 就是小智不斷分享的最大動力,如果本篇博客有任何錯誤和建議,歡迎人才們留言,最后,謝謝大家的觀看。


原文:https://codeburst.io/alternat...


代碼部署后可能存在的BUG沒法實(shí)時知道,事后為了解決這些BUG,花了大量的時間進(jìn)行l(wèi)og 調(diào)試,這邊順便給大家推薦一個好用的BUG監(jiān)控工具 Fundebug。

藍(lán)藍(lán)設(shè)計sillybuy.com )是一家專注而深入的界面設(shè)計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計、BS界面設(shè)計 、 cs界面設(shè)計 、 ipad界面設(shè)計 、 包裝設(shè)計 、 圖標(biāo)定制 、 用戶體驗(yàn) 、交互設(shè)計、 網(wǎng)站建設(shè) 平面設(shè)計服務(wù)



vuex管理狀態(tài)倉庫詳解

seo達(dá)人

一.什么是Vuex?

Vuex 是一個專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式。它采用集中式存儲管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測的方式發(fā)生變化。Vuex 也集成到 Vue 的官方調(diào)試工具 devtools extension,提供了諸如零配置的 time-travel 調(diào)試、狀態(tài)快照導(dǎo)入導(dǎo)出等高級調(diào)試功能。采用了全局單例模式,將組件的共享狀態(tài)抽離出來管理,使得組件樹中每一個位置都可以獲取共享的狀態(tài)或者觸發(fā)行為。
那么什么是狀態(tài)呢?我把狀態(tài)理解為在沒有使用vuex時,在當(dāng)前組件中data內(nèi)需要共用的數(shù)據(jù)為狀態(tài)。
vuex使得狀態(tài)或行為成為了共享的狀態(tài),所共享的狀態(tài)或行為可以在各個組件中都可以訪問到,省去了子父或子子之間傳遞變量,提高了開發(fā)效率。

二.不使用vuex時與使用vuex時的差別

當(dāng)我們不使用vuex時,對于組件之間傳遞信息會較為麻煩。

不使用vuex時

父子之間傳遞信息:

App.vue文件中:

<template>
  <div id="app">
      <Fruits :fruitList="fruitList"/>
  </div>
</template> 
<script> import Goods from './components/Goods'; export default { name: 'App',
  components:{
    Fruits,
    Goods
  }, data(){
    return{ goodList:[
      {
        name:'doll',
        price:12 },
      { name:'glass',
        price:10 }
    ],
    }
  }
}
</script>
<style>
</style>

Good.vue文件中:

<template>
  <div class="hello">
      <ul>
        <li v-for="(good,index) in goodList" :key="index"> name:{{good.name}} number: {{good.number}} {{index}}
        </li>
      </ul>
  </div>
</template>

<script> export default { props:['goodList'],
}
</script>
<style>

</style>

兄弟之間傳遞信息:

首先先創(chuàng)建一個js文件作為兩兄弟之間傳輸?shù)募~扣,這里起名為msg.js

//創(chuàng)建并暴露vue import Vue from 'vue';
export default new Vue

兄弟組件Goods:

<template>
  <div>
        <button @click="deliver">點(diǎn)擊</button>
  </div>
</template>

<script> import MSG from '../msg';
export default {
  data(){ return{
      msg:'hahah' }
  },
  methods:{
    deliver() {
        MSG.$emit('showMsg',this.msg)
    }
  }

}
</script>
<style>

</style>

兄弟組件Fruits:

<template>
  <div>
      <div class="fruit">
          {{text}}
      </div>
  </div>
</template>
<script> import MSG from '../msg';
export default {
    data(){ return{
        text:'' }
    },
    created(){ this.getMsg()
    },
    methods:{
      getMsg(){
        MSG.$on('showMsg',(message)=>{ this.text = message
        })
      }
    }
}
</script>
<style>
</style>

在App組件中的代碼:
在這里插入圖片描述
點(diǎn)擊按鈕:


藍(lán)藍(lán)設(shè)計sillybuy.com )是一家專注而深入的界面設(shè)計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計、BS界面設(shè)計 、 cs界面設(shè)計 、 ipad界面設(shè)計 、 包裝設(shè)計 、 圖標(biāo)定制 、 用戶體驗(yàn) 、交互設(shè)計、 網(wǎng)站建設(shè) 、平面設(shè)計服務(wù)

Tubik Studio 是怎么為華為定制整套 UI 圖標(biāo)的?

資深UI設(shè)計者

一套 UI 界面當(dāng)中,核心的 APP 圖標(biāo)是用戶每天都要接觸、經(jīng)常使用的視覺組件和交互對象。設(shè)計圖標(biāo)的時候,要用到大家最熟悉的元素才能貼合用戶認(rèn)知,要醒目、統(tǒng)一,也要足夠「隱形」,避免喧賓奪主。今天這篇文章,來自著名的 Tubik Studio 團(tuán)隊,他們?yōu)槿A為旗下的 EMUI 10 系統(tǒng)設(shè)計了核心的圖標(biāo)系統(tǒng),來看看他們的設(shè)計過程吧。

Tubik Studio 是怎么為華為定制整套 UI 圖標(biāo)的?

我們總不會低估一個操作系統(tǒng)基礎(chǔ)圖標(biāo),對于產(chǎn)品的可用性和合意性的影響?;A(chǔ)圖標(biāo)雖然小巧,但是對于整個操作系統(tǒng)而言,總是極具影響力的,因?yàn)樗麄兪怯脩艚缑娴暮诵脑?,幫助用戶快速直觀地在系統(tǒng)中定位、瀏覽、導(dǎo)航。但是,對于設(shè)計師而言,圖標(biāo)的設(shè)計始終是挑戰(zhàn),它看起來最為簡單,但實(shí)則為最為艱難的工作。

圖標(biāo)需要,讓人一目了然,但是也要具備良好的可識別性,在傳統(tǒng)和創(chuàng)新之間達(dá)到平衡。這一次,Tubik Studio 設(shè)計團(tuán)隊將要給華為的 EMUI 10 來設(shè)計圖標(biāo),而這篇文章將會為你揭示背后的設(shè)計過程。

這次的項(xiàng)目主要是由 Sergii Valiukh 、Arthur Avakyan 和 Polina Taran 來負(fù)責(zé)。這次的設(shè)計項(xiàng)目從最初的探索構(gòu)思入手,逐漸開始繪制草圖,探索樣式,一直到最后打磨,完成設(shè)計。

Tubik Studio 是怎么為華為定制整套 UI 圖標(biāo)的?

項(xiàng)目內(nèi)容

為華為 EMUI 10 系統(tǒng)的用戶界面設(shè)計基礎(chǔ)的圖標(biāo)

客戶介紹

我們在 2019 年夏季,收到了來自華為的邀約,這次的項(xiàng)目要重新設(shè)計 EMUI 這套基于 Android 系統(tǒng)的用戶界面基礎(chǔ)圖標(biāo),這套圖標(biāo)會用來適配華為旗下的旗艦手機(jī),這些圖標(biāo)將會隨著新版的系統(tǒng)部署到這些手機(jī)產(chǎn)品當(dāng)中。我們的任務(wù),是創(chuàng)建總計 54 款符合當(dāng)下潮流趨勢的圖標(biāo),這些圖標(biāo)要能夠貼合品牌和已有用戶的偏好,并且能夠吸引新的用戶。

這個圖標(biāo)設(shè)計項(xiàng)目如今已經(jīng)在當(dāng)下的華為旗下手機(jī)產(chǎn)品中應(yīng)用且部署好了,最早使用這套圖標(biāo)的智能手機(jī)型號為 Mate 30 ,緊接其后的是 P40。

Tubik Studio 是怎么為華為定制整套 UI 圖標(biāo)的?

設(shè)計過程

在整個操作系統(tǒng)中,這些圖標(biāo)是始終位于用戶視野以內(nèi)、最基礎(chǔ)的最核心的交互元素,通常用戶每天都會同這些核心的基礎(chǔ) APP 進(jìn)行交互,有時候一天多達(dá)幾十次,因此它們應(yīng)當(dāng)具備良好的功能性,還應(yīng)該足夠美觀,給用戶帶來滿足感。同時,這套圖標(biāo)的設(shè)計,也應(yīng)當(dāng)足夠統(tǒng)一,以協(xié)調(diào)的體驗(yàn)切入到整個 EMUI 的設(shè)計系統(tǒng)當(dāng)中,貼合整體的樣式特征。

所以,我們使用了一整套圖標(biāo)網(wǎng)格系統(tǒng),應(yīng)對不同需求,在設(shè)計的過程中,這套網(wǎng)格有助于確保所有圖標(biāo)外部尺寸的一致性,也保證了內(nèi)部元素的統(tǒng)一性。

Tubik Studio 是怎么為華為定制整套 UI 圖標(biāo)的?

為了發(fā)掘全新的視角,我們決定從傳統(tǒng)的手繪圖標(biāo)開始,尋找重新塑造圖標(biāo)設(shè)計的方法。這些圖標(biāo)所涉及到的元素,早已為全球數(shù)百萬用戶所熟知,要重新設(shè)計圖標(biāo)外觀,并且還要成套且統(tǒng)一,這本身就是一個巨大的挑戰(zhàn)。

Tubik Studio 是怎么為華為定制整套 UI 圖標(biāo)的?

比如「電話」圖標(biāo)所對應(yīng)的聽筒元素、「信息」圖標(biāo)所對應(yīng)的氣泡對話框這樣的元素,是不可能完全拋棄重新創(chuàng)造的,所以我們的真正的切入點(diǎn)是在形態(tài)和色彩上尋求解決方案。

越是簡單的東西,重塑起來就越難。

在實(shí)際的設(shè)計過程中,我們嘗試了數(shù)以百計的造型變體,從完全放飛、非常規(guī)的的外部造型,到極其常規(guī),大家熟知的造型解決方案,我們都逐一試過。而在色彩上的嘗試相對會顯得更加具有實(shí)驗(yàn)性:我們嘗試使用明亮的紫羅蘭色、栗色和淺綠色來進(jìn)行混搭。

當(dāng)然,我們很清楚,這樣的實(shí)驗(yàn)性的工作是探索過程中的一小步,但是它是必須的,是創(chuàng)造新設(shè)計的種子,是尋求正確答案的必經(jīng)之路。

Tubik Studio 是怎么為華為定制整套 UI 圖標(biāo)的?

在設(shè)計過程在,有一件有趣的事情發(fā)生在設(shè)計「相機(jī)」圖標(biāo)的過程中。我們嘗試過很多不同的圖標(biāo)造型,不同的元素,不同的樣式,但是其中始終有一個細(xì)節(jié)是不變的,那就是右上角的小紅點(diǎn)。這是為了暗示用戶,華為的攝像頭模組來自徠卡,這個紅色的小點(diǎn)就是向其致敬的標(biāo)識。

Tubik Studio 是怎么為華為定制整套 UI 圖標(biāo)的?

而下面的概念設(shè)計,則是強(qiáng)化了圖標(biāo)之間的幾何輪廓的差異,從而提升圖標(biāo)在智能手機(jī)屏幕上的對比度和識別度。

Tubik Studio 是怎么為華為定制整套 UI 圖標(biāo)的?

下一步,我們基于幾何圖形外觀差異性,設(shè)計了多種造型不同但同樣優(yōu)雅的圖標(biāo)。在基于這種風(fēng)格概念進(jìn)行延伸的過程中,我們會優(yōu)先考慮圓形的元素。而「天氣」圖標(biāo)明顯既不適合圓形也不適合方形來呈現(xiàn),所以我們使用的是云和太陽兩種元素的組合。「錢包」圖標(biāo)使用的是矩形,然后搭配卡片的組合。盡管造型整體上是相對自由的,但是所有的圖標(biāo)都是遵循圖標(biāo)網(wǎng)格,并且在視覺權(quán)重上盡可能統(tǒng)一。

Tubik Studio 是怎么為華為定制整套 UI 圖標(biāo)的?

在色彩和樣式上,我們則更加傾向于漸變。沒有色彩漸變,純扁平的圖標(biāo)顯得過于幼稚和「古早」,沒有足夠的品質(zhì)感,所以,我們在新的圖標(biāo)設(shè)計上,開始加入漸變色彩,提升質(zhì)感。

Tubik Studio 是怎么為華為定制整套 UI 圖標(biāo)的?

不過,在最終版本當(dāng)中,我們還是保留了圖標(biāo)外部的圓角矩形的外輪廓,然后將圖標(biāo)元素的內(nèi)徑進(jìn)行了適當(dāng)?shù)乜s減,漸變和核心的簡約幾何特征依然是整套設(shè)計的最高優(yōu)先級。

Tubik Studio 是怎么為華為定制整套 UI 圖標(biāo)的?

這套設(shè)計方案展現(xiàn)了在整套 UI 界面中,圖標(biāo)這個小元素的設(shè)計上所需要投入的精力和潛在的難度。想要圖標(biāo)足夠協(xié)調(diào)、美觀、易用還要貼合品牌特征、還要區(qū)別于以往,是一件相當(dāng)不容易的事情。

Tubik Studio 是怎么為華為定制整套 UI 圖標(biāo)的?

細(xì)節(jié)里藏著魔鬼,任何細(xì)小的元素、線條輪廓、色彩的變化都可能會在屏幕上放大、被感知到。

文章來源:優(yōu)設(shè)    作者:Tubik Studio

藍(lán)藍(lán)設(shè)計sillybuy.com )是一家專注而深入的界面設(shè)計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計、BS界面設(shè)計 、 cs界面設(shè)計 、 ipad界面設(shè)計 、 包裝設(shè)計 、 圖標(biāo)定制 、 用戶體驗(yàn) 、交互設(shè)計、 網(wǎng)站建設(shè) 、平面設(shè)計服務(wù)

中央氣象臺近十年設(shè)計精品集

前端達(dá)人

今天整理網(wǎng)站類作品,看到給中央氣象臺近十年設(shè)計的諸多網(wǎng)頁和系統(tǒng)。這幾天每天關(guān)注鄱陽湖洪水狀況,2018年改版時,有一版的設(shè)計方案,我設(shè)計了洪水到來時的專題,圖片視頻,動畫提醒居民注意事項(xiàng)。同事們也花了許多精力時間做了大量工作。

作為公民,我們在用我們擅長的設(shè)計去服務(wù)社會,在這個過程中形成自己的積淀。這是不可用金錢來衡量的價值。

微信圖片_20200721174610.png


微信圖片_20200721174606.jpg


微信圖片_20200721174603.png

微信圖片_20200721174559.png

微信圖片_20200721174555.png

微信圖片_20200721174551.png

微信圖片_20200721174547.png

微信圖片_20200721174543.png

微信圖片_20200721174539.png

微信圖片_20200721174614.png







作者:藍(lán)藍(lán)

  藍(lán)藍(lán)設(shè)計sillybuy.com )是一家專注而深入的界面設(shè)計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計、BS界面設(shè)計 、 cs界面設(shè)計 、 ipad界面設(shè)計 、 包裝設(shè)計 、 圖標(biāo)定制 、 用戶體驗(yàn) 、交互設(shè)計、 網(wǎng)站建設(shè) 、平面設(shè)計服務(wù)

2020-2021 設(shè)計趨勢ISUX報告 · 用戶體驗(yàn)篇

ui設(shè)計分享達(dá)人

It is ultra experience



ISUX Design Trend Report

前言

——————————

身為用戶體驗(yàn)設(shè)計師,無時無刻不被世界上的新事物沖刷著認(rèn)知——互聯(lián)網(wǎng)紅利下降帶來變化莫測的商業(yè)動向、循著摩爾定律野蠻生長日新月異的新技術(shù)、各類亞文化群體催生出多元復(fù)雜的圈層文化、腦洞口味越來越獨(dú)特的年輕人,甚至眼下席卷全球的黑天鵝事件......


任何一個新事物的悄悄冒頭,都有可能在未知的將來影響著用戶體驗(yàn)設(shè)計師。我們能做的是,在起初感受到微微震幅時,便沿著震感逐步尋找源頭,并思考未來的發(fā)展走向。趕在變化降臨前先擁抱變化。


本文通過研究近一兩年科技、社會文化以及自身用戶體驗(yàn)領(lǐng)域的變化,從用戶體驗(yàn)領(lǐng)域關(guān)鍵的用戶、媒介(設(shè)備與應(yīng)用)、交互行為、信息與場景的五個角度出發(fā),探索用戶體驗(yàn)設(shè)計未來的趨勢,希望能帶來啟發(fā)。


隨著人工時代到來,過去機(jī)械的單向交互方式逐漸被打破,機(jī)器漸漸演化成了會主動“觀察”真實(shí)場景,“感受”用戶情感,預(yù)判用戶意圖并自動完成任務(wù)的貼心小棉襖。機(jī)器如何為人們提供更智能便捷的服務(wù),未來還有非常大的想象空間。 





隨著人工時代到來,過去機(jī)械的單向交互方式逐漸被打破,機(jī)器漸漸演化成了會主動“觀察”真實(shí)場景,“感受”用戶情感,預(yù)判用戶意圖并自動完成任務(wù)的貼心小棉襖。機(jī)器如何為人們提供更智能便捷的服務(wù),未來還有非常大的想象空間。



1-1

——————————

基于真實(shí)場景推理用戶意圖

隨著AI技術(shù)的發(fā)展,智能設(shè)備可以越來越無縫地將數(shù)字世界和物理世界嫁接起來,主動感知用戶所處情境并智能提供相應(yīng)服務(wù)。


在2019的 Google I/O 大會上,Google Lens 展示的AR點(diǎn)菜功能可以智能識別用戶掃描的菜單并將美食網(wǎng)站上的相關(guān)推薦直接呈現(xiàn)在屏幕上。


當(dāng)用 Google Lens 識別到小票信息時,可快速提取小票上的金額,且可自動彈起計算器快速幫助用戶計算人均消費(fèi),節(jié)省人工計算的時間成本。


隨著信息入口從數(shù)字空間延伸到周圍的物理空間中,未來萬物皆可為用戶體驗(yàn)的媒介,設(shè)計師未來在設(shè)計的時候需要注意:


尋找適合的打通真實(shí)世界的切入點(diǎn):在陌生語言、信息復(fù)雜或者難以處理等苛刻的環(huán)境下,充分發(fā)揮智能設(shè)備對信息智能讀取、批量識別與翻譯等強(qiáng)大能力,幫助用戶完成任務(wù);


將用戶旅程的上下游串聯(lián):根據(jù)生活常識和經(jīng)驗(yàn)預(yù)判用戶行為目的,前置推薦服務(wù);


更加系統(tǒng)細(xì)心地考量干擾因素:真實(shí)場景是動態(tài)變化的,需要更全方位考慮光線的強(qiáng)弱、多源的噪音、實(shí)體的可視性、人員和事件的打斷等因素。



1-2

——————————

任務(wù)自動化,簡化用戶旅程


為了完成一項(xiàng)任務(wù),用戶往往需要借助多個應(yīng)用來回切換配合,使用起來瑣碎麻煩。如今應(yīng)用越做越強(qiáng)大也越復(fù)雜,過去僅僅解決單一場景的解決方案不再適應(yīng)于用戶對于完成任務(wù)的訴求。


Google Assistant 的新能力 Duplex on the web 可以通過自動跨應(yīng)用任務(wù)處理來簡化用戶旅程。只需要用戶發(fā)出語音指令“預(yù)定一輛去某地的車”,助手便可自動跨郵件、日歷、付款等應(yīng)用調(diào)取信息、自動根據(jù)使用習(xí)慣做選擇,并自動填寫信息,而用戶全程需要的只是在關(guān)鍵節(jié)點(diǎn)輕敲“確認(rèn)”即可。


2019年隨著 iOS 13 的更新,“快捷指令”推出了“自動化”能力,用戶通過“if...then...”語法便可為自己的App設(shè)計一套程序,實(shí)現(xiàn)如:“當(dāng)我回到公司時提醒我打卡”、“每天早上10點(diǎn)給我的女朋友發(fā)送一條表白短信”等能力,將不相關(guān)的場景動作串聯(lián)字一起自動化執(zhí)行,大大節(jié)省人工操作成本。


提升使用效率是用戶體驗(yàn)設(shè)計孜孜不倦努力的方向之一。在利用新技術(shù)進(jìn)一步簡化用戶旅程時,設(shè)計師可以充分利用以下因素:


借助語音輸入:比起界面觸控操作,語音交互的直達(dá)性可以“穿透”復(fù)雜界面,讓設(shè)備第一時間明確用戶目標(biāo);


基于用戶行為形成習(xí)慣記憶:對用戶長期重復(fù)的行為做分析處理,構(gòu)建用戶習(xí)慣模型并主動提供服務(wù);


適當(dāng)考慮專家級用戶:隨著部分用戶的智能設(shè)備使用水平越來越高,可以考慮為專家用戶提供自定義操作腳本,滿足其自身的獨(dú)特需求。



1-3

——————————

基于情感感知,主動理解用戶需求


隨著人臉識別、表情識別、肢體跟蹤等技術(shù)的提升,機(jī)器逐漸學(xué)會感性語言,主動感知用戶內(nèi)在情感和心理需求。


2019年1月的CES展上起亞亮相的互動式“情感駕駛空間”技術(shù),可通過傳感器讀取用戶的面部表情、心率等反應(yīng),調(diào)整駕駛空間內(nèi)的燈光、影片類型、音樂風(fēng)格等,舒緩艙內(nèi)乘客心情,由此提供更人性化的出行體驗(yàn)。

用戶總是會期待更貼心的服務(wù),設(shè)計師未來對同理心的情感嗅覺更加敏銳:


利用感性線索定位用戶情緒:需要通過面部表情、特殊時間節(jié)點(diǎn)或者識別到的關(guān)鍵詞,對用戶情緒進(jìn)行理解和定位,判斷用戶情感理解用戶內(nèi)心訴求是自由探索、趣味娛樂、或者靜謐修行并提供符合用戶當(dāng)下心境的服務(wù)。


綜合使用感性元素進(jìn)行設(shè)計:通過使用線條、色彩、聲音和動作等傳達(dá)并喚起相對應(yīng)的情感,提供更加人性化的體驗(yàn)。


小結(jié)

更智能的服務(wù)提供方式會讓人們生活擁有更多可能性,但一旦火候把握不得當(dāng),可能就會造成對人們生活的野蠻入侵。關(guān)于如何讓科技更好造福于人們,早在上個世紀(jì),施樂帕克研究中心提出了寧靜技術(shù)(Calm Technology)的愿景,認(rèn)為影響最深遠(yuǎn)的技術(shù)應(yīng)該是隱匿不見的,它們?nèi)缋w維般融入日常生活,絲絲入扣,直至不可分辨。


隨著科技的發(fā)展,設(shè)計師對新技術(shù)不應(yīng)是不加克制地應(yīng)用,而應(yīng)該潤物細(xì)無聲般地提供服務(wù),幫助人們從繁雜喧囂的數(shù)字世界中解脫出來,將寶貴的注意力資源投放在讓生活更美好的事物上。



回顧人類和機(jī)器的交流語言,從命令行界面、圖形用戶界面到自然用戶界面,人機(jī)交互方式越來越貼合人與人之間更自然的交流方式,其背后是心智模型與實(shí)現(xiàn)模型的高度擬合的趨勢。


在自然用戶界面中,為滿足新形態(tài)智能硬件對新接口的需求,以及人們對更豐富強(qiáng)大的交互方式的自然訴求,越來越多的自然用戶界面被開發(fā)出來。語音交互和隔空手勢交互便是近幾年迅速發(fā)展并落地的兩種交互方式。



2-1

——————————

隔空手勢交互:更自由、更靈動


為了讓機(jī)器更好地讀懂用戶的身體語言,能夠感知深度信息的攝像頭走進(jìn)了日常手機(jī)。2019年國內(nèi)外手機(jī)廠商的發(fā)布大會上,LG 手機(jī) G8 ThinQ 以及華為發(fā)布 Mate 30 系列推出的隔空手勢,可實(shí)現(xiàn)一些簡單的諸如滑動、切歌、截屏等效果。



除此以外,隔空手勢支持更加細(xì)微的手勢,如旋轉(zhuǎn)、揉搓等,可以更直觀、更靈活的方式操控界面,讓用戶獲得一種像魔術(shù)師用意念控制事物運(yùn)作的快感。



對于隔空手勢操作網(wǎng)上的言論褒貶不一,其中爭議性最大的就是隔空手勢宛如“殺雞用牛刀”,明明可以用更加精準(zhǔn)的手勢觸控,為什么還要用看似很酷炫其實(shí)精準(zhǔn)度更低的隔空手勢操作?


隔空手勢并不是要替代觸控手勢成為主流的人機(jī)交互方式,更多是對情境式障礙場景的補(bǔ)充。在某些場景下,用戶使用設(shè)備的條件可能是充滿干擾的。想想看當(dāng)你邊看手機(jī)食譜邊炒菜的時候、邊煲劇邊剝小龍蝦的時候、疫情期間出門佩戴橡膠手套無法正常觸控手機(jī)屏幕時.....隔空手勢是不是特別好用?


每個人在特殊的場景下都有可能面臨感官障礙,未來的設(shè)計也應(yīng)該更多地考慮情境式障礙的場景,讓用戶無論身處何時何地依舊能一如既往無障礙地使用設(shè)備。




2-2

——————————

語音交互:更精準(zhǔn)、更好玩

語音交互作為更趨近于人與人之間最自然的交流方式,近些年有許多發(fā)展的突破點(diǎn)。


在發(fā)展主線上,語音交互趨向更自然、更人性化、更個性化。過去反人類的一些溝通方式慢慢被“調(diào)教”。此外,多人會話場景下的技術(shù)方案日漸增多。


2019的 Google I/O 大會展示了一個視頻片段,視頻中的兩位嘉賓相繼吐槽,經(jīng)常出現(xiàn)針鋒相對難以聽清的時候,這時用戶可以調(diào)節(jié)音源音量選擇性增強(qiáng)自己關(guān)注的人物聲音,讓另一個人“靜音”。


  滑動選擇音源


此外,語音交互除了在智能音箱領(lǐng)域廣泛應(yīng)用以外,也逐漸應(yīng)用在廣告等更多的傳播媒介中,刷新人們?nèi)粘J褂皿w驗(yàn)。2020年2月索尼提交了一項(xiàng)廣告播放新專利。當(dāng)用戶在觀看電視節(jié)目時,如果出現(xiàn)廣告,只要站起來大喊廣告中對應(yīng)品牌的名字,便可直接跳過這個廣告。


設(shè)計師在語音交互場景下,需要留意以下幾個比較容易被忽視的因素:


用戶語音交互習(xí)慣培養(yǎng):如今還處于培養(yǎng)用戶語音交互使用習(xí)慣階段,設(shè)計師需要更多地考慮應(yīng)用的語音交互規(guī)則如何才能更趨近于人們?nèi)粘5臏贤?xí)慣,并進(jìn)一步為人們的社會習(xí)俗所接納。


真實(shí)場景下的多人音源:在現(xiàn)實(shí)情境中, 在多人對話場景下將面臨音源不清、穿插停頓、噪音過多等影響體驗(yàn)的情況,由于計算機(jī)聽覺分析能力開始從單人音源拓寬到了多人音源,多人對話解決方案上還有很大想象空間。


改變傳統(tǒng)的視聽體驗(yàn):在使用場景上,語音交互接口也將逐漸運(yùn)用到更多的媒介上,更全面地刷新用戶體驗(yàn)。



小結(jié)

人類擁有雙手、眼睛、耳朵和發(fā)聲的嘴巴,但是并不總是在每個使用場景下都能自如地使用:在安靜的自習(xí)室下聲音收到限制,在駕駛場景下注意力受到限制,在雙手拎著東西場景下雙手受到限制......但目前許多產(chǎn)品設(shè)計都建立在用戶能完整使用感官功能這一理想化的基礎(chǔ)上。


未來的發(fā)展趨勢傾向于將視、聽、觸、嗅等多通道信息完美整合起來,綜合使用多種輸入通道和輸出通道,根據(jù)用戶使用場景用最恰當(dāng)?shù)姆绞絺鬟f服務(wù),滿足用戶多方位的需求。




盡管喬布斯曾斷言3.5英寸是手機(jī)的黃金尺寸,但作為人們?nèi)粘?nèi)容消費(fèi)與娛樂的窗口,手機(jī)屏幕毫無疑問地變得越來越大,甚至超出傳統(tǒng)物理限制。人們對大屏享受的追求與設(shè)備攜帶便捷性之間的矛盾由來已久,硬件形態(tài)的變化對舊有的用戶體驗(yàn)設(shè)計思路帶來的新的挑戰(zhàn)。


3-1

——————————

大屏幕:單手持握新挑戰(zhàn)

屏幕橫縱比越來越大,而人類的手部具有先天限制,曾經(jīng)慣用的界面布局方式在高橫縱比的屏幕上可能無法被大拇指無障礙全覆蓋,使得越來越多的設(shè)計更加重視利用移動屏幕下半部分。


操作與信息進(jìn)一步下移


高德地圖、蘋果地圖的搜索框下移,方便單手操作用戶快速激活輸入框;


影視資訊平臺IMDB強(qiáng)化底部標(biāo)簽欄功能,雙擊“搜索”tab即可激活輸入框,無須艱難地觸摸頂部。


即時戰(zhàn)斗類手游皇室戰(zhàn)爭的說明卡片主要展示在下半部分,方便用戶進(jìn)行卡片上的相關(guān)操作。



底部導(dǎo)航被賦予更多能力

Pocket的底部標(biāo)簽欄現(xiàn)在兼任漢堡菜單功能,在激活狀態(tài)下再次點(diǎn)擊主頁icon可選擇主頁上須展示的內(nèi)容。


利用下滑手勢代替點(diǎn)擊

Snapchat的許多表示前后進(jìn)退關(guān)系的頁面都不是”返回“按鈕,而是向下箭頭,用戶可下滑退出當(dāng)前頁面。







3-2

——————————

折疊屏:新形態(tài)的交互方式

為了解決設(shè)備形態(tài)和人類手部先天限制之間的矛盾,折疊屏誕生瀏覽并顛覆舊有的界面設(shè)計方式。


更靈活的信息布局


過去在單屏設(shè)計下,考慮到用戶注意力由上到下縱向衰減,因此信息布局更多是按照優(yōu)先級從上往下排序。而折疊屏中,屏幕展開后便可以開辟出更大的可利用空間,將次級頁面或者較為重要的內(nèi)容曝光在第二屏,對信息的布局將帶來全新的變化。設(shè)計師為保證大小屏下順暢的閱讀體驗(yàn),需要對信息模塊在不同空間布局下的流動性有更強(qiáng)的把控能力。


更便捷的多任務(wù)操作


在過去的單屏體驗(yàn)中,用戶只能將注意力完全集中在當(dāng)前的界面中,一次只做一件事。但在實(shí)際生活中,用戶面臨的情景往往是主線任務(wù)和支線任務(wù)的頻繁交錯,并且根據(jù)會任務(wù)不同的性質(zhì)自由調(diào)動自己的注意力重心,如邊看視頻邊聊天、邊看直播邊逛街等等。在折疊屏中,設(shè)計師可以探索更多主線和支線交錯進(jìn)行的場景,利用折疊屏帶來的更大的屏幕空間,可以讓用戶在不離開主線場景的基礎(chǔ)上進(jìn)行支線任務(wù)的處理,大大節(jié)約了在不同App上來回切換的操作成本。



更直觀的拖拽交互


此外,隨著多任務(wù)處理越來越廣泛使用,拖拽交互將成為重要的交互模式之一。文本、表情包、圖片、視頻等交互對象,不再需要經(jīng)過復(fù)雜的分享轉(zhuǎn)發(fā)流程才能在不同App中流轉(zhuǎn),通過拖拽的方式可以更直觀地進(jìn)行交互。




雙面屏互動玩法


外折疊屏在折疊狀態(tài)下可轉(zhuǎn)為雙面屏,等于是給用戶增加多一個觀看視角。例如華為 Mate X 的鏡像拍攝可以讓被拍攝者即時獲知自己的鏡頭影像是否滿意,這一拍女友神器有望成為直男拍攝終結(jié)者。在未來更多的多人觀看和互動玩法將被開拓出來。


 華為Mate X 的鏡像拍攝


未來隨著5G通訊技術(shù)的成長,越來越多的設(shè)備可以同時加入物聯(lián)網(wǎng),人們的生活將被各種智能設(shè)備圍繞,設(shè)計師需要參與更多屏幕外的設(shè)計,讓不同設(shè)備串聯(lián)在一起協(xié)同合作,讓用戶能更加自在地享受科技的便利。



席卷全球的新冠疫情讓數(shù)十億用戶乖乖待在家里。過去需要花費(fèi)大量精力去教育的用戶使用習(xí)慣因?yàn)橐咔榧娂娹D(zhuǎn)變。云購物、云蹦迪、云賞櫻、云監(jiān)工......人們足不出戶便可還原許多線下場景。隨著用戶線上和線下生活的界限進(jìn)一步模糊,用戶對于應(yīng)用的效率和情感訴求也發(fā)生了變化。



4-1

——————————

更關(guān)注效率導(dǎo)向

疫情讓遠(yuǎn)程辦公學(xué)習(xí)需求劇增,多人協(xié)作場景越來越頻繁,許多企業(yè)隨之升級了電話、視頻會議、文檔制作等多人協(xié)作效率軟件。過去僅僅考慮少人場景協(xié)作的方式不適用,設(shè)計師需要比以往更多地考慮多人協(xié)作場景下,如何對海量密集的信息進(jìn)行分析處理和展示。


在學(xué)習(xí)方式上,由于線下學(xué)習(xí)轉(zhuǎn)移至線上,學(xué)生群體對于娛樂向軟件也有了效率訴求。為了順應(yīng)用戶訴求變化,2020年5月QQ推出學(xué)習(xí)模式,屏蔽娛樂性的內(nèi)容推送,讓學(xué)生更專注在學(xué)習(xí)上。



4-2

————————————

更注重緩解社交疏離感


除了效率訴求急劇提升以外,隨著長時間的線上學(xué)習(xí)與辦公所產(chǎn)生社交疏離感和缺失感,人們對于線上學(xué)習(xí)工作的情感化訴求也進(jìn)一步增強(qiáng)。


2020年推出的plagi遠(yuǎn)程辦公軟件支持設(shè)置每個人的avartar形象,讓大家在遠(yuǎn)程辦公時依舊能時刻感受到彼此的存在。在完成任務(wù)時還可以放鞭炮慶祝,讓員工能感受到親密無間的線上辦公體驗(yàn)。


設(shè)計師需要更加關(guān)注如何讓線上生活進(jìn)一步與現(xiàn)實(shí)生活圈和時間線接軌,通過拓展真實(shí)社交下的更多伴生行為讓線上也能還原線下的真實(shí)場景細(xì)節(jié)和互動體驗(yàn),以彌補(bǔ)用戶對真實(shí)社交的缺失感。



4-3

——————————

加速人和信息的強(qiáng)連接


疫情的發(fā)生加速了人與信息之間的連接。人們越來越習(xí)慣將自身的身體資料、心情狀態(tài)等信息沉淀在智能設(shè)備上。


為了做好廣大市民群眾的健康監(jiān)測服務(wù),輔助疫情防控工作,微信和支付寶在2020年年初都上線了健康碼服務(wù),不同顏色的健康碼代表人們不同的健康情況,市民出入特定場所都需初始健康碼。



隨著人的數(shù)據(jù)化越來越深入,個人身份信息的線上化在各平臺上將成為更加通用的能力。設(shè)計師需要考慮如何更自然更低成本地將線下動態(tài)變化的資料信息線上化,更有效地對用戶信息進(jìn)行加工處理,以及記憶用戶的使用習(xí)慣和行為,以便幫助用戶更地完成任務(wù)。


疫情的出現(xiàn)加速了線下生活線上化,短短時間內(nèi)我們看到日常習(xí)以為常的應(yīng)用為響應(yīng)疫情下的特殊需求紛紛出現(xiàn)改造,釘釘、QQ群被改造成上網(wǎng)課、批改作業(yè)的地方,醫(yī)療衛(wèi)生公眾號開辟了實(shí)時疫情播報與辟謠通道,無接觸設(shè)計和服務(wù)需求異常突出......這也啟發(fā)了設(shè)計師需要保持對突發(fā)事件的敏感力以及應(yīng)急能力,在日常生活中留心思考,為日后突發(fā)事件提供充足的場景支撐。




在洶涌的資本語境下,互聯(lián)網(wǎng)設(shè)計師裹挾在商業(yè)驅(qū)動的結(jié)果導(dǎo)向中狂奔,對設(shè)計的倫理和責(zé)任鮮有發(fā)聲,但伴隨著互聯(lián)網(wǎng)紅利退潮,發(fā)展放緩,狂奔之下的人本問題也逐漸浮出水面。在大趨勢下,UX設(shè)計師需要培養(yǎng)自身設(shè)計對倫理和責(zé)任的敏感度,在滿足商業(yè)目的外,重拾節(jié)操,為多群體,為大社會設(shè)計,更加注重“以人為本”。




5-1

——————————

更包容性的設(shè)計

包容性設(shè)計師指在做設(shè)計產(chǎn)品的時候,考慮到各類用戶的訴求,輸出具有包容性的設(shè)計方案。包容性設(shè)計依舊是2020年設(shè)計主題之一,伴隨著互聯(lián)網(wǎng)產(chǎn)品全球化,在通用性和包容性上也提出了新的要求。




為身障人士設(shè)計


三星在2019年針對東南亞市場推出了一款讓聾盲人士和健全人實(shí)時交流的app:Good Vibes,盲聾人輕擊屏幕輸入摩斯電碼,預(yù)先連線好的另一臺手機(jī)就會顯示從盲聾人發(fā)來的短信。健全人用普通的文字輸入回復(fù),在盲聾人這一端就會翻譯成摩斯電碼、以手機(jī)振動的方式讀出短信內(nèi)容。

   GOOD VIBES宣傳視頻


餓了么:在餓了么送貨騎手中,約8%受色盲色弱的困擾(全國男性群體中紅綠色盲色弱占比達(dá)8%-9%,餓了么騎手男性占比90%),為此餓了么設(shè)計團(tuán)隊在2019年對app的進(jìn)行了重新設(shè)計,包括使用WCAG無障礙色彩對比度,以及無障礙色盤,以及調(diào)整字階,使用輔助圖形等設(shè)計手段來解決部分騎手在送貨途中使用APP的痛點(diǎn)問題。


餓了么UED:《為騎士創(chuàng)造平等 — 配送 App 的包容性設(shè)計》



跨年齡段設(shè)計


谷歌助手禮貌功能 ( Google Pretty Please ) :開啟谷歌助手禮貌功能后,如果使用者在下達(dá)指令的語句中包括“Please”,谷歌助手會對禮貌的請求表示感謝,以此培養(yǎng)孩子的禮貌言行。

Google Pretty Please功能宣傳



Swift Playground:當(dāng)10后小學(xué)生VITA君的編程課被“可敬的發(fā)量”刷滿彈幕時,Swift playgrounds功不可沒,這款為兒童新手學(xué)習(xí)編程的軟件,用趣味的游戲方式為4歲以上低齡用戶提供了一個學(xué)習(xí)編程的低門檻平臺。



為性別平等而設(shè)計


蘋果emoji回看歷年蘋果emoji的更新,從膚色平等,到性別、性向平等,再到為殘疾人設(shè)計,2020年再為跨性別者增加新表情,性別平等依舊是包容性設(shè)計中重要一環(huán)。



Airbnb插畫:愛彼迎在插畫系統(tǒng)中,也為不同膚色,不同職業(yè),不同性別,以及身障人士進(jìn)行了人物的繪制。






5-2

——————————

關(guān)注用戶隱私

2019是互聯(lián)網(wǎng)科技隱私問題沉浮的一年,國外有Facebook因泄露隱私收到史上最大罰單,國內(nèi)則打響了“人臉識別第一案”。籠罩在隱私信任危機(jī)下,個人信息和數(shù)據(jù)立法突飛猛進(jìn),美國推動《加州消費(fèi)者隱私法案》,國內(nèi)也將在2020年出臺《個人信息保護(hù)法》和《數(shù)據(jù)安全法》。


MIUI12推出隱匿面具功能


Android開放生態(tài)導(dǎo)致的權(quán)限隱私問題一直被用戶所詬病,某些APP存在用戶不授權(quán)就無法使用情況,針對這一情況,MIUI12推出了隱匿面具功能。當(dāng)用戶在開啟某些APP要求授權(quán)權(quán)限時,可以選擇空白通行證進(jìn)行授權(quán),從而保護(hù)用戶真實(shí)信息。


   在MIUI12的更新中,還推出了照明彈、攔截網(wǎng)兩項(xiàng)隱私保護(hù)功能


iOS 14剪貼板提醒


在iOS 14的更新中,保護(hù)用戶隱私方面進(jìn)一步升級。

其中剪貼板提醒設(shè)計很貼心,當(dāng)用戶打開應(yīng)用,如果該應(yīng)用讀取了你剪貼板的內(nèi)容,會在系統(tǒng)頂部彈出提示,用戶能在第一時間意識到剪貼板內(nèi)容被讀取,幫助用戶更好的保護(hù)自己的隱私內(nèi)容。




5-3

——————————

健康的數(shù)碼生活方式


科技的發(fā)展是一把雙刃劍,互聯(lián)網(wǎng)產(chǎn)品的發(fā)展給用戶帶來便捷和沉浸體驗(yàn)的同時,也使得用戶沉溺于科技所帶來的惰性和投食之下,逐漸喪失了對真實(shí)生活的把控權(quán),被科技綁架。


數(shù)字福祉(digital wellbeing)近年被頻頻提起,指科技產(chǎn)品需要權(quán)衡好數(shù)碼產(chǎn)品和真實(shí)生活之間的平衡,防止數(shù)碼產(chǎn)品過渡分散用戶的注意力而影響生活質(zhì)量。


Android Q 專注模式  Google Android Q Focus Mode


Android Q的更新加入了專注模式,用戶在專注模式下,可以在系統(tǒng)層面快捷地關(guān)閉使你分心的應(yīng)用,讓你聚焦于更重要的事情。



防沉迷系統(tǒng)升級


推薦技術(shù)的進(jìn)步,產(chǎn)品體驗(yàn)的升級,給用戶帶來了更合胃口的菜式和沉浸體驗(yàn),但同時也被冠上了“電子海洛因”的稱號。游戲或者內(nèi)容產(chǎn)品的防沉迷系統(tǒng)依舊會是數(shù)字福祉下不可避免的趨勢。


王者榮耀在2020年升級防沉迷系統(tǒng),對青少年的娛樂時間和點(diǎn)券充值的限制進(jìn)行了進(jìn)一步升級。承接話。B站在2019年推出青少年模式,在該模式下,使用時長和內(nèi)容推薦等做了定制化處理。






2020年的UI設(shè)計趨勢,一方面是對往年風(fēng)格的衍變和細(xì)化,另一方面,在扁平克制的界面風(fēng)格盛行后,設(shè)計師們向往更自由、更突破的視覺表達(dá)。



6-1

——————————

深色模式


2019年iOS 13深色模式姍姍來遲,緊接著大廠APP相繼推出此功能。在2020年,深色模式會繼續(xù)普及外,也會在可視性和實(shí)現(xiàn)成本方面有更多細(xì)節(jié)打磨和研究。





6-2

——————————

新擬態(tài)

設(shè)計趨勢的發(fā)展是螺旋式上升的,在扁平化設(shè)計流行之后,對物體的擬真再一次回歸設(shè)計圈,新擬態(tài)以一種對舊擬物風(fēng)格的再創(chuàng)新,重新流行起來。


新擬物風(fēng)格(Neumorphism)緣起于設(shè)計師Alexander Plyuto發(fā)布在dribbble的一組作品,以投影重新對扁平界面進(jìn)行了塑造,模仿出類似浮雕的視覺效果,感受耳目一新,引起大量設(shè)計師相盡模仿。


新擬態(tài)的實(shí)用性和可落地性有待商榷,但是作為一種新的風(fēng)格受到設(shè)計師擁躉,也不失為下一波風(fēng)潮到來前的靈感繆斯。



WWDC2020對mac OS的更新也重新定義了新擬態(tài)設(shè)計語言,在mac OS新系統(tǒng)Big Sur中,圖標(biāo)的設(shè)計增添了輕微的漸變、投影、高光,以此來營造圖標(biāo)內(nèi)元素之間的縱深關(guān)系。




6-3

——————————

多彩配色


在扁平簡潔UI風(fēng)格盛行之后,豐富的色彩依舊是設(shè)計趨勢之一,大面積色塊,碰撞配色,帶來更具沖擊感的視覺體驗(yàn)。





6-4

——————————

字體裝飾化


UI界面逐漸扁平,色塊圖標(biāo)弱化,為突出頁面重心和內(nèi)容,iOS 11在界面標(biāo)題上使用更大的字號,更粗的字重。近年在大標(biāo)題的風(fēng)格衍變下,文字在傳達(dá)信息外,也開始有了裝飾性作用,采用超大字體,成為頁面排版美化的一部分。





6-5

————————

更大圓角

大圓角的風(fēng)格會繼續(xù)延續(xù),相較以往,卡片的處理圓角會更大,隨之帶來的是多的留白處理,結(jié)合大字號,帶來更透氣通透的視覺感受。



Mac OS Big Sur的界面相對舊版本采用了更大的圓角;系統(tǒng)圖標(biāo)的設(shè)計統(tǒng)一成圓角矩形。





6-6

——————————

更豐富的插圖


UI插圖的豐富體現(xiàn)在樣式和內(nèi)容上,樣式上開始3D化,內(nèi)容上更注重插圖敘事的表達(dá)。


3D插圖


3D圖形往年更多運(yùn)用在動態(tài)影像或運(yùn)營類設(shè)計中,隨著3D的普及運(yùn)用,UI插圖也會迎來3D化,給用戶帶來更立體,更新鮮的視覺感受。




講求敘事表意


相較于往年追求形式的UI插圖,新趨勢下的插圖更講求功能性,每一副插圖都承載一定的作用——傳達(dá)功能信息或透傳品牌情感;同時插圖更講求畫面表意和情節(jié),給用戶敘事性的視覺體驗(yàn),增進(jìn)用戶和產(chǎn)品之間的情感聯(lián)系。




插圖組件化


插畫的流行,隨之而來的是成本的水漲船高——一套系列插圖為保持風(fēng)格統(tǒng)一,往往由唯一設(shè)計師繪制,同時為兼容各類場景,設(shè)計師往往要繪制多張。


為解決插圖的成本和效率,插圖開始以組件化的方式進(jìn)行繪制——插圖設(shè)計師將插畫進(jìn)行拆分繪制——不同人物,不同場景,不同物件等,再通過組件化的拼接合成,使用組件的設(shè)計師可以根據(jù)需求場景自由組合,也避免了風(fēng)格不統(tǒng)一問題。


設(shè)計師Pablo Stanley將日常繪制的插畫制成一套矢量插圖組件庫,將人物分為:半身、全身和坐姿3大類。通過不同表情、發(fā)型和服裝可自由搭配出近60萬種組合。


Pablo Stanley人物插畫系統(tǒng)




6-7

————————

多維度動畫表現(xiàn)


新趨勢下,動畫一方面回溯復(fù)古線描手繪風(fēng)格,另一方面追求更三維的體驗(yàn),同時幀率進(jìn)一步提升,追求更流暢的視覺感受。


手繪動畫


手繪插圖是往年的熱門,其隨性自然的筆觸,能給用戶帶來親切的感受,在新的趨勢下,動畫的加入賦予手繪插圖一份靈性和趣味。


3D運(yùn)動


Google Material Design通過卡片投影層級和二維動畫規(guī)律,賦予扁平界面Z軸的縱深感。隨著3D的普及流行,新趨勢下的界面,界面的運(yùn)動從二維走向三維,表現(xiàn)出3D場景下透視感。



高幀率動畫


高幀率影視從線下電影院移步到線上流媒體,手機(jī)高幀率屏幕從90Hz到120Hz逐步升級,用戶對畫面流暢的定義一再刷新,UI動畫的幀率升級也會是新的一輪趨勢。


Telegram的表情采用了高幀率動畫,給用戶更流暢的視覺感受。








體驗(yàn)的持續(xù)升級,產(chǎn)品的高速迭代,對UX設(shè)計師的設(shè)計師效率提出了更高的要求。的設(shè)計方式是一個永恒的趨勢。




7-1

——————————

從本地文件到云端協(xié)作


傳統(tǒng)的文件交接方式效率低下,導(dǎo)致設(shè)計師之間信息不對稱,最終影響產(chǎn)品的一致性體驗(yàn)。近些年在線設(shè)計協(xié)同工具發(fā)展迅速,從UI設(shè)計、 設(shè)計交付以及組件協(xié)同等環(huán)節(jié)上給設(shè)計師提供更加實(shí)時的協(xié)作體驗(yàn),獲得大量UX設(shè)計師的簇?fù)?。?019 uxtool的設(shè)計工具調(diào)研中,在線設(shè)計協(xié)同工具佼佼者figma以其協(xié)作和性能優(yōu)勢,大有追趕sketch之勢。


隨著團(tuán)隊對設(shè)計效率要求的提高,設(shè)計文檔從本地走向云端協(xié)作是不可逆趨勢。不過設(shè)計工具的迭代是需要成本的,尤其在大型設(shè)計團(tuán)隊,設(shè)計工具需要渡過陣痛期來完成迭代,進(jìn)而提升設(shè)計效率和體驗(yàn)一致性。



7-2

——————————

科學(xué)有效的設(shè)計系統(tǒng)


UX的發(fā)展,從早期的靜態(tài)規(guī)范到當(dāng)下的動態(tài)設(shè)計系統(tǒng),是為解決產(chǎn)品迭代增速后帶來的設(shè)計效率和產(chǎn)品體驗(yàn)問題。商業(yè)驅(qū)動下的產(chǎn)品迭代速度有增無減,設(shè)計系統(tǒng)依舊會是未來幾年的設(shè)計趨勢之一。


這里說的設(shè)計系統(tǒng)不是廣義上的設(shè)計系統(tǒng),而是在互聯(lián)網(wǎng)設(shè)計的發(fā)展中,對組件化設(shè)計逐步迭代升華的一套設(shè)計協(xié)作方法:


“設(shè)計系統(tǒng)(Design systems)是一組為了共同目標(biāo)而服務(wù)的內(nèi)在相互聯(lián)系的設(shè)計模式和多人協(xié)同執(zhí)行的方法?!保ㄒ浴禗esign systems》,Alla Kholmatova,C7210翻譯)。


設(shè)計系統(tǒng)歷程衍變


組件化的發(fā)展歷經(jīng)規(guī)范文檔到UI組件,再到設(shè)計系統(tǒng),形態(tài)從最初對設(shè)計一致性的指導(dǎo)規(guī)范,到對產(chǎn)品研發(fā)流程的規(guī)范,以及產(chǎn)品設(shè)計價值觀的輸出,當(dāng)下的設(shè)計系統(tǒng)以集大成者形式影響整個產(chǎn)品的設(shè)計形態(tài)。


設(shè)計系統(tǒng)的結(jié)構(gòu)見下圖:



設(shè)計系統(tǒng)的求同存異


設(shè)計系統(tǒng)并非一成不變的,他是一個動態(tài)進(jìn)化的系統(tǒng),會根據(jù)團(tuán)隊性質(zhì)、產(chǎn)品特性在內(nèi)容上有所區(qū)分——比如大團(tuán)隊更應(yīng)該大而全,小團(tuán)隊更傾向小而精;成熟產(chǎn)品的設(shè)計系統(tǒng)更傾向于打造完整閉環(huán)的合作流程機(jī)制,新產(chǎn)品的設(shè)計系統(tǒng)應(yīng)該以小為始,快速迭代……


隨著產(chǎn)品的垂直化,細(xì)分化,設(shè)計系統(tǒng)的趨勢會是在趨勢大同之下找到適合產(chǎn)品和團(tuán)隊自身的形態(tài)和節(jié)奏。


Material Design是一個包含了指導(dǎo)規(guī)范、組件,以及設(shè)計開發(fā)工具的自適應(yīng)性設(shè)計系統(tǒng)。


它作為平臺型性設(shè)計系統(tǒng),更為大而全的規(guī)范了整個生態(tài)系統(tǒng)的設(shè)計風(fēng)格,以及提供工具讓研發(fā)者能快速產(chǎn)出符合規(guī)范的產(chǎn)品。


  Google生態(tài)龐大繁雜,Material Design更為全面


Ant Design作為一個為to B產(chǎn)品提供解決方案的平臺,更多從設(shè)計可用性和完整性考慮設(shè)計系統(tǒng)的搭建。


Ant Design通過模塊化解決方案,降低冗余的生產(chǎn)成本,讓設(shè)計者專注于更好的用戶體驗(yàn)


QQ作為一款面向95后的2C社交產(chǎn)品,其設(shè)計系統(tǒng)Q語言從風(fēng)格調(diào)性上對設(shè)計進(jìn)行規(guī)范,同時給予設(shè)計師一定的自由度;也考慮到QQ內(nèi)兼顧多個產(chǎn)品,以及界面主題樣式,對基礎(chǔ)組件的使用場景和代碼進(jìn)行了規(guī)范,方便設(shè)計和開發(fā)敏捷開發(fā)。


Q語言,給予產(chǎn)品的自由調(diào)性之外,也針對主題和基礎(chǔ)組件進(jìn)行了規(guī)范


每個產(chǎn)品和團(tuán)隊都有自身的特征,設(shè)計系統(tǒng)的建設(shè)也應(yīng)該有的放矢,沒有可照搬的標(biāo)準(zhǔn)答案,在大方向下找到適合自身的解決方案才是的可行之道,將效率最大化。


科學(xué)有效的優(yōu)化迭代


組件是設(shè)計系統(tǒng)中的重要組成部分,但是以往靜態(tài)的、孤立的協(xié)作方式使得組件的更新迭代滯后和阻塞。隨著設(shè)計系統(tǒng)的發(fā)展,設(shè)計師組件化思維的普及,組件的更新需要更科學(xué)的方式進(jìn)行管理。


Figma在2019年推出的Design System Analytics功能,組件設(shè)計師可以借此查看組件的使用情況,包括引用次數(shù),解組次數(shù)等,并可以生成組件使用情況的曲線趨勢圖,以數(shù)據(jù)的形式,科學(xué)地推動組件的優(yōu)化迭代。


 1.選擇分析的時間段;2.組件使用的次數(shù)曲線圖;3.團(tuán)隊使用情況;4.所有組件使用情況



后記

未來的用戶體驗(yàn)會出現(xiàn)什么新趨勢?人工智能等算法的發(fā)展、5G技術(shù)普及、新的智能設(shè)備形態(tài)、新的信息處理技術(shù)、新一代用戶的喜好和口味......這些往后或?qū)⒂绊懹脩趔w驗(yàn)發(fā)展的走向。未來用戶對體驗(yàn)的要求只會越來越高。


用戶體驗(yàn)設(shè)計師需要了解更多的技術(shù)動向,但安身立命之本還是讓用戶真正受益:立足于用戶真實(shí)使用場景,在理性價值層面上,打造可用、易用、的設(shè)計;在感性需求層上賦予情感上的愉悅性,在反思層面賦予意義價值。




文章來源:站酷    作者:百度MEUX

藍(lán)藍(lán)設(shè)計sillybuy.com )是一家專注而深入的界面設(shè)計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計、BS界面設(shè)計 、 cs界面設(shè)計 、 ipad界面設(shè)計 、 包裝設(shè)計 、 圖標(biāo)定制 、 用戶體驗(yàn) 、交互設(shè)計、 網(wǎng)站建設(shè) 、平面設(shè)計服務(wù)



UX TRENDS | 注重隱私的用戶體驗(yàn)設(shè)計

ui設(shè)計分享達(dá)人

用戶隱私安全在產(chǎn)品設(shè)計中是很重要的一個環(huán)節(jié),本文從用戶體驗(yàn)角度切入,從匿名模式、減少永久性和減少公開性三個方面展開分析。



我們先看?組來??優(yōu)的2019年6?的調(diào)研數(shù)據(jù):70%的美國?認(rèn)為,與5年前相?個?信息變得更不安全。尤其是?學(xué)歷?收?群體。由此可??戶對個?信息數(shù)據(jù)的隱私擔(dān)憂?以往更甚。



?戶隱私安全很重要,涉及的范圍和?度也很多。本次的分析從?戶體驗(yàn)?度切?,涉及如下三個??:

  1. Incognito Mode匿名模式;

  2. Reducing Permanence減少永久性;

  3. Reducing Publicity減少公開性。



01 匿名模式


下圖是Google系A(chǔ)pp(Google AppChromeYouTubeandGoogle Map)匿名模式切換,從交互體驗(yàn)上來說有如下?個特點(diǎn):

  1. 統(tǒng)?在右上?;

  2. 可以便捷切換?匿名模式,反過來也很容易切回登陸狀態(tài);

  3. 匿名模式的狀態(tài)提示,例如YouTube 在匿名模式下在界?底部有?字提示“您 當(dāng)前處于匿名模式”。


匿名模式不是最近才流?的功能,最早提供隱匿模式的是蘋果safari瀏覽器,早在 2005年就?持了匿名模式。Chrome瀏覽器在2008年就開始?持此模式。雖然由來已久,為什么到了2020年,匿名模式依然是國外互聯(lián)???趨勢呢?


我們看?組數(shù)據(jù):

這是來?DuckDuckGo 2019年9?的調(diào)研(DuckDuckGo是美國的?款不記錄?戶?為保護(hù)?戶隱私的搜索引擎)。樣本來?美國、英國、德國和澳?利亞的成年??戶,共計3,411?的調(diào)研得出。各國?戶對使?搜索引擎的個?隱私安全?常在意(是否搜集個?的數(shù)據(jù)和記錄搜索?為)。

2020年5?DuckDuckGo?均搜索次數(shù)為6200萬。對?看2019年11?底?均搜索次數(shù)4900萬,2018年10?是2900萬。

最近?年的持續(xù)活躍度?幅增?證明了不記錄個?隱私的搜素引擎越來越受到?戶的?睞。

國內(nèi),頭條、UC瀏覽器在搜索框輸?狀態(tài)也提供了“?痕瀏覽”??。

不僅是搜索引擎領(lǐng)域,保護(hù)?戶隱私也成為Facebook最重要的戰(zhàn)略?向之?。Facebook CEO Mark Zuckerberg在2019年 F8開發(fā)者?會上喊出“THE FUTURE IS PRIVATE”。2019年3?Mark Zuckerberg發(fā)?,主題就是《聚焦于保護(hù)隱私的社交?絡(luò)》。



02 減少永久性


我們先看國外社交媒體Stories(?故事)產(chǎn)品形態(tài)的流?。

?們總是對于所分享的內(nèi)容永遠(yuǎn)記錄在?上感到擔(dān)憂。Stories24?時消失緩解了?們的隱私顧慮,這讓?戶更安?地?然分享。

Stories由Snapchat?創(chuàng),由 Facebook發(fā)揚(yáng)光?。早在2019年4?,F(xiàn)acebook+Messenger Stories, Instagram Stories?活?戶數(shù)就突破5億。 2020年2-3?LinkedIn,Twitter也先后宣布將上線類似功能。



03 減少公開性


來??優(yōu)的調(diào)研報告:41%的美國?經(jīng)歷過?絡(luò)騷擾,最常?的就是在社交媒體上。23%的?戶最近經(jīng)歷的?絡(luò)騷擾來?評論區(qū)的評論內(nèi)容。27%的?戶經(jīng)歷?絡(luò)騷擾后決定不再發(fā)布任何內(nèi)容。

我們以限定評論互動的公開性為例:

2020年5?Twitter上線了新的評論功能,可以限定誰可以回復(fù)帖?的功能,提供了三種選項(xiàng):誰都可以評論,只有被關(guān)注者可以評論,只有被提及者可以評論三種公開度的限定。

Instagram也在測試“評論限制”新功能,批量屏蔽/限制評論。?前已經(jīng)上線的?個例?:?戶(評論發(fā)布者)如果發(fā)布的評論含有攻擊性敏感詞,發(fā)布前伴有提示,提醒評論含有攻擊性敏感詞是否真的要發(fā)布。


注重隱私提供僅好友可?/僅??可?/僅作者可?/等多重維度的隱私設(shè)定有助于?戶更安?地參與互動。

另外?個例?是付費(fèi)頻道會員:付費(fèi)頻道會員-限定頻道的公開性讓內(nèi)容創(chuàng)作者減輕隱私顧慮不僅能獲得?告收?,也能得到來?會員、會費(fèi)的收?,形成“忠實(shí)粉絲”社區(qū),有助于內(nèi)容?態(tài)的社區(qū)化建設(shè)。

我們主要看YouTube的頻道會員案例:

YouTube有兩種會員模式。?種是YouTube整個平臺的付費(fèi)會員,去?告,看原創(chuàng)美劇影視,消費(fèi)?樂,可下載內(nèi)容的模式。第?種模式是Youtuber個?頻道付費(fèi)會員,吸引忠實(shí)粉絲加?。我想說的就是第?種。


為什么?V?紅有意愿開通頻道會員?


除了獲得忠實(shí)粉絲收?變現(xiàn)的商業(yè)價值以及付費(fèi)頻道會員可以為忠實(shí)粉絲提供各種專屬功能,背后也和?紅?V對個?隱私顧慮有關(guān)。

?紅?V在完全公開的社交?絡(luò)上需要始終保持?夠克制謹(jǐn)慎,避免引起爭議。但在忠實(shí)粉絲付費(fèi)頻道專屬會員群中,?紅?V會減輕隱私顧慮,更加回歸?我。

?如在頻道會員中發(fā)布更多與個??活相關(guān)的內(nèi)容,表達(dá)更多不便在完全公開的社交?絡(luò)中的想法和感受等,因?yàn)橹覍?shí)粉絲通常更具包容度,更不容易引起爭議。


YouTube頻道會員費(fèi)?可以從三種會費(fèi)(按?)區(qū)間選擇,?持多選:

  1. 低階 Low Levels $0.99~3.99;

  2. 中階 Medium Levels $4.99~14.99;

  3. ?階 High Levels $19.99~49.99;

頻道會員功能在2018年開始測試,?向粉絲數(shù)過10萬的YouTuber開放。



以上綜述,我們可以說:


1.匿名模式:

雖然匿名模式由來已久,但仍然是當(dāng)前的??基本?戶體驗(yàn)設(shè)計趨勢,尤其是匿名模式的切換便捷性?常重要。


2.減少永久性:

Stories?故事24?時消失緩解了?們的隱私顧慮,這讓?戶更安?地?然分享,已經(jīng)成為國外社交媒體平臺的必備功能,F(xiàn)acebook, Instagram平臺的最主要、最具影響?的功能之?。


3.減少公開性:

?戶總是對在社交媒體平臺發(fā)表評論有所顧忌,限定評論的公開性能夠有助于促進(jìn)?戶發(fā)帖表達(dá),其他?戶也可以更安?地參與互動。


付費(fèi)頻道會員可以限定頻道的公開性,讓內(nèi)容創(chuàng)作者減輕隱私顧慮不僅能獲得?告收?,也能得到來?會員會費(fèi)的收?,形成“忠實(shí)粉絲”社區(qū),有助于內(nèi)容?態(tài)的社區(qū)化建設(shè)。


從UE?度,我們可以為頻道會員提供專屬身份設(shè)計例如專屬徽章,專屬表情等。

THE FUTURE IS PRIVATE, 注重?戶隱私的體驗(yàn)設(shè)計越來越重要!

文章來源:站酷    作者:百度MEUX

藍(lán)藍(lán)設(shè)計sillybuy.com )是一家專注而深入的界面設(shè)計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計、BS界面設(shè)計 、 cs界面設(shè)計 、 ipad界面設(shè)計 、 包裝設(shè)計 、 圖標(biāo)定制 、 用戶體驗(yàn) 、交互設(shè)計、 網(wǎng)站建設(shè) 、平面設(shè)計服務(wù)



VUE-多文件斷點(diǎn)續(xù)傳、秒傳、分片上傳

seo達(dá)人

凡是要知其然知其所以然

文件上傳相信很多朋友都有遇到過,那或許你也遇到過當(dāng)上傳大文件時,上傳時間較長,且經(jīng)常失敗的困擾,并且失敗后,又得重新上傳很是煩人。那我們先了解下失敗的原因吧!


據(jù)我了解大概有以下原因:


服務(wù)器配置:例如在PHP中默認(rèn)的文件上傳大小為8M【post_max_size = 8m】,若你在一個請求體中放入8M以上的內(nèi)容時,便會出現(xiàn)異常

請求超時:當(dāng)你設(shè)置了接口的超時時間為10s,那么上傳大文件時,一個接口響應(yīng)時間超過10s,那么便會被Faild掉。

網(wǎng)絡(luò)波動:這個就屬于不可控因素,也是較常見的問題。

基于以上原因,聰明的人們就想到了,將文件拆分多個小文件,依次上傳,不就解決以上1,2問題嘛,這便是分片上傳。 網(wǎng)絡(luò)波動這個實(shí)在不可控,也許一陣大風(fēng)刮來,就斷網(wǎng)了呢。那這樣好了,既然斷網(wǎng)無法控制,那我可以控制只上傳已經(jīng)上傳的文件內(nèi)容,不就好了,這樣大大加快了重新上傳的速度。所以便有了“斷點(diǎn)續(xù)傳”一說。此時,人群中有人插了一嘴,有些文件我已經(jīng)上傳一遍了,為啥還要在上傳,能不能不浪費(fèi)我流量和時間。喔...這個嘛,簡單,每次上傳時判斷下是否存在這個文件,若存在就不重新上傳便可,于是又有了“秒傳”一說。從此這"三兄弟" 便自行CP,統(tǒng)治了整個文件界?!?

注意文中的代碼并非實(shí)際代碼,請移步至github查看代碼

https://github.com/pseudo-god...


分片上傳

HTML

原生INPUT樣式較丑,這里通過樣式疊加的方式,放一個Button.

 <div class="btns">

   <el-button-group>

     <el-button :disabled="changeDisabled">

       <i class="el-icon-upload2 el-icon--left" size="mini"></i>選擇文件

       <input

         v-if="!changeDisabled"

         type="file"

         :multiple="multiple"

         class="select-file-input"

         :accept="accept"

         @change="handleFileChange"

       />

     </el-button>

     <el-button :disabled="uploadDisabled" @click="handleUpload()"><i class="el-icon-upload el-icon--left" size="mini"></i>上傳</el-button>

     <el-button :disabled="pauseDisabled" @click="handlePause"><i class="el-icon-video-pause el-icon--left" size="mini"></i>暫停</el-button>

     <el-button :disabled="resumeDisabled" @click="handleResume"><i class="el-icon-video-play el-icon--left" size="mini"></i>恢復(fù)</el-button>

     <el-button :disabled="clearDisabled" @click="clearFiles"><i class="el-icon-video-play el-icon--left" size="mini"></i>清空</el-button>

   </el-button-group>

   <slot

   

//data 數(shù)據(jù)


var chunkSize = 10 * 1024 * 1024; // 切片大小

var fileIndex = 0; // 當(dāng)前正在被遍歷的文件下標(biāo)


data: () => ({

   container: {

     files: null

   },

   tempFilesArr: [], // 存儲files信息

   cancels: [], // 存儲要取消的請求

   tempThreads: 3,

   // 默認(rèn)狀態(tài)

   status: Status.wait

 }),

   

一個稍微好看的UI就出來了。




選擇文件

選擇文件過程中,需要對外暴露出幾個鉤子,熟悉elementUi的同學(xué)應(yīng)該很眼熟,這幾個鉤子基本與其一致。onExceed:文件超出個數(shù)限制時的鉤子、beforeUpload:文件上傳之前

fileIndex 這個很重要,因?yàn)槭嵌辔募蟼?,所以定位?dāng)前正在被上傳的文件就很重要,基本都靠它


handleFileChange(e) {

 const files = e.target.files;

 if (!files) return;

 Object.assign(this.$data, this.$options.data()); // 重置data所有數(shù)據(jù)


 fileIndex = 0; // 重置文件下標(biāo)

 this.container.files = files;

 // 判斷文件選擇的個數(shù)

 if (this.limit && this.container.files.length > this.limit) {

   this.onExceed && this.onExceed(files);

   return;

 }


 // 因filelist不可編輯,故拷貝filelist 對象

 var index = 0; // 所選文件的下標(biāo),主要用于剔除文件后,原文件list與臨時文件list不對應(yīng)的情況

 for (const key in this.container.files) {

   if (this.container.files.hasOwnProperty(key)) {

     const file = this.container.files[key];


     if (this.beforeUpload) {

       const before = this.beforeUpload(file);

       if (before) {

         this.pushTempFile(file, index);

       }

     }


     if (!this.beforeUpload) {

       this.pushTempFile(file, index);

     }


     index++;

   }

 }

},

// 存入 tempFilesArr,為了上面的鉤子,所以將代碼做了拆分

pushTempFile(file, index) {

 // 額外的初始值

 const obj = {

   status: fileStatus.wait,

   chunkList: [],

   uploadProgress: 0,

   hashProgress: 0,

   index

 };

 for (const k in file) {

   obj[k] = file[k];

 }

 console.log('pushTempFile -> obj', obj);

 this.tempFilesArr.push(obj);

}

分片上傳

創(chuàng)建切片,循環(huán)分解文件即可


 createFileChunk(file, size = chunkSize) {

   const fileChunkList = [];

   var count = 0;

   while (count < file.size) {

     fileChunkList.push({

       file: file.slice(count, count + size)

     });

     count += size;

   }

   return fileChunkList;

 }

循環(huán)創(chuàng)建切片,既然咱們做的是多文件,所以這里就有循環(huán)去處理,依次創(chuàng)建文件切片,及切片的上傳。

async handleUpload(resume) {

 if (!this.container.files) return;

 this.status = Status.uploading;

 const filesArr = this.container.files;

 var tempFilesArr = this.tempFilesArr;


 for (let i = 0; i < tempFilesArr.length; i++) {

   fileIndex = i;

   //創(chuàng)建切片

   const fileChunkList = this.createFileChunk(

     filesArr[tempFilesArr[i].index]

   );

     

   tempFilesArr[i].fileHash ='xxxx'; // 先不用看這個,后面會講,占個位置

   tempFilesArr[i].chunkList = fileChunkList.map(({ file }, index) => ({

     fileHash: tempFilesArr[i].hash,

     fileName: tempFilesArr[i].name,

     index,

     hash: tempFilesArr[i].hash + '-' + index,

     chunk: file,

     size: file.size,

     uploaded: false,

     progress: 0, // 每個塊的上傳進(jìn)度

     status: 'wait' // 上傳狀態(tài),用作進(jìn)度狀態(tài)顯示

   }));

   

   //上傳切片

   await this.uploadChunks(this.tempFilesArr[i]);

 }

}

上傳切片,這個里需要考慮的問題較多,也算是核心吧,uploadChunks方法只負(fù)責(zé)構(gòu)造傳遞給后端的數(shù)據(jù),核心上傳功能放到sendRequest方法中

async uploadChunks(data) {

 var chunkData = data.chunkList;

 const requestDataList = chunkData

   .map(({ fileHash, chunk, fileName, index }) => {

     const formData = new FormData();

     formData.append('md5', fileHash);

     formData.append('file', chunk);

     formData.append('fileName', index); // 文件名使用切片的下標(biāo)

     return { formData, index, fileName };

   });


 try {

   await this.sendRequest(requestDataList, chunkData);

 } catch (error) {

   // 上傳有被reject的

   this.$message.error('親 上傳失敗了,考慮重試下呦' + error);

   return;

 }


 // 合并切片

 const isUpload = chunkData.some(item => item.uploaded === false);

 console.log('created -> isUpload', isUpload);

 if (isUpload) {

   alert('存在失敗的切片');

 } else {

   // 執(zhí)行合并

   await this.mergeRequest(data);

 }

}

sendReques。上傳這是最重要的地方,也是容易失敗的地方,假設(shè)有10個分片,那我們?nèi)羰侵苯影l(fā)10個請求的話,很容易達(dá)到瀏覽器的瓶頸,所以需要對請求進(jìn)行并發(fā)處理。


并發(fā)處理:這里我使用for循環(huán)控制并發(fā)的初始并發(fā)數(shù),然后在 handler 函數(shù)里調(diào)用自己,這樣就控制了并發(fā)。在handler中,通過數(shù)組API.shift模擬隊列的效果,來上傳切片。

重試: retryArr 數(shù)組存儲每個切片文件請求的重試次數(shù),做累加。比如[1,0,2],就是第0個文件切片報錯1次,第2個報錯2次。為保證能與文件做對應(yīng),const index = formInfo.index; 我們直接從數(shù)據(jù)中拿之前定義好的index。 若失敗后,將失敗的請求重新加入隊列即可。


關(guān)于并發(fā)及重試我寫了一個小Demo,若不理解可以自己在研究下,文件地址:https://github.com/pseudo-god... , 重試代碼好像被我弄丟了,大家要是有需求,我再補(bǔ)吧!

   // 并發(fā)處理

sendRequest(forms, chunkData) {

 var finished = 0;

 const total = forms.length;

 const that = this;

 const retryArr = []; // 數(shù)組存儲每個文件hash請求的重試次數(shù),做累加 比如[1,0,2],就是第0個文件切片報錯1次,第2個報錯2次


 return new Promise((resolve, reject) => {

   const handler = () => {

     if (forms.length) {

       // 出棧

       const formInfo = forms.shift();


       const formData = formInfo.formData;

       const index = formInfo.index;

       

       instance.post('fileChunk', formData, {

         onUploadProgress: that.createProgresshandler(chunkData[index]),

         cancelToken: new CancelToken(c => this.cancels.push(c)),

         timeout: 0

       }).then(res => {

         console.log('handler -> res', res);

         // 更改狀態(tài)

         chunkData[index].uploaded = true;

         chunkData[index].status = 'success';

         

         finished++;

         handler();

       })

         .catch(e => {

           // 若暫停,則禁止重試

           if (this.status === Status.pause) return;

           if (typeof retryArr[index] !== 'number') {

             retryArr[index] = 0;

           }


           // 更新狀態(tài)

           chunkData[index].status = 'warning';


           // 累加錯誤次數(shù)

           retryArr[index]++;


           // 重試3次

           if (retryArr[index] >= this.chunkRetry) {

             return reject('重試失敗', retryArr);

           }


           this.tempThreads++; // 釋放當(dāng)前占用的通道


           // 將失敗的重新加入隊列

           forms.push(formInfo);

           handler();

         });

     }


     if (finished >= total) {

       resolve('done');

     }

   };


   // 控制并發(fā)

   for (let i = 0; i < this.tempThreads; i++) {

     handler();

   }

 });

}

切片的上傳進(jìn)度,通過axios的onUploadProgress事件,結(jié)合createProgresshandler方法進(jìn)行維護(hù)

// 切片上傳進(jìn)度

createProgresshandler(item) {

 return p => {

   item.progress = parseInt(String((p.loaded / p.total) * 100));

   this.fileProgress();

 };

}

Hash計算

其實(shí)就是算一個文件的MD5值,MD5在整個項(xiàng)目中用到的地方也就幾點(diǎn)。

秒傳,需要通過MD5值判斷文件是否已存在。

續(xù)傳:需要用到MD5作為key值,當(dāng)唯一值使用。

本項(xiàng)目主要使用worker處理,性能及速度都會有很大提升.

由于是多文件,所以HASH的計算進(jìn)度也要體現(xiàn)在每個文件上,所以這里使用全局變量fileIndex來定位當(dāng)前正在被上傳的文件

執(zhí)行計算hash


正在上傳文件


// 生成文件 hash(web-worker)

calculateHash(fileChunkList) {

 return new Promise(resolve => {

   this.container.worker = new Worker('./hash.js');

   this.container.worker.postMessage({ fileChunkList });

   this.container.worker.onmessage = e => {

     const { percentage, hash } = e.data;

     if (this.tempFilesArr[fileIndex]) {

       this.tempFilesArr[fileIndex].hashProgress = Number(

         percentage.toFixed(0)

       );

     }


     if (hash) {

       resolve(hash);

     }

   };

 });

}

因使用worker,所以我們不能直接使用NPM包方式使用MD5。需要單獨(dú)去下載spark-md5.js文件,并引入


//hash.js


self.importScripts("/spark-md5.min.js"); // 導(dǎo)入腳本

// 生成文件 hash

self.onmessage = e => {

 const { fileChunkList } = e.data;

 const spark = new self.SparkMD5.ArrayBuffer();

 let percentage = 0;

 let count = 0;

 const loadNext = index => {

   const reader = new FileReader();

   reader.readAsArrayBuffer(fileChunkList[index].file);

   reader.onload = e => {

     count++;

     spark.append(e.target.result);

     if (count === fileChunkList.length) {

       self.postMessage({

         percentage: 100,

         hash: spark.end()

       });

       self.close();

     } else {

       percentage += 100 / fileChunkList.length;

       self.postMessage({

         percentage

       });

       loadNext(count);

     }

   };

 };

 loadNext(0);

};

文件合并

當(dāng)我們的切片全部上傳完畢后,就需要進(jìn)行文件的合并,這里我們只需要請求接口即可

mergeRequest(data) {

  const obj = {

    md5: data.fileHash,

    fileName: data.name,

    fileChunkNum: data.chunkList.length

  };


  instance.post('fileChunk/merge', obj,

    {

      timeout: 0

    })

    .then((res) => {

      this.$message.success('上傳成功');

    });

}

Done: 至此一個分片上傳的功能便已完成

斷點(diǎn)續(xù)傳

顧名思義,就是從那斷的就從那開始,明確思路就很簡單了。一般有2種方式,一種為服務(wù)器端返回,告知我從那開始,還有一種是瀏覽器端自行處理。2種方案各有優(yōu)缺點(diǎn)。本項(xiàng)目使用第二種。

思路:已文件HASH為key值,每個切片上傳成功后,記錄下來便可。若需要續(xù)傳時,直接跳過記錄中已存在的便可。本項(xiàng)目將使用Localstorage進(jìn)行存儲,這里我已提前封裝好addChunkStorage、getChunkStorage方法。


存儲在Stroage的數(shù)據(jù)




緩存處理

在切片上傳的axios成功回調(diào)中,存儲已上傳成功的切片


instance.post('fileChunk', formData, )

 .then(res => {

   // 存儲已上傳的切片下標(biāo)

+ this.addChunkStorage(chunkData[index].fileHash, index);

   handler();

 })

在切片上傳前,先看下localstorage中是否存在已上傳的切片,并修改uploaded


   async handleUpload(resume) {

+      const getChunkStorage = this.getChunkStorage(tempFilesArr[i].hash);

     tempFilesArr[i].chunkList = fileChunkList.map(({ file }, index) => ({

+        uploaded: getChunkStorage && getChunkStorage.includes(index), // 標(biāo)識:是否已完成上傳

+        progress: getChunkStorage && getChunkStorage.includes(index) ? 100 : 0,

+        status: getChunkStorage && getChunkStorage.includes(index)? 'success'

+              : 'wait' // 上傳狀態(tài),用作進(jìn)度狀態(tài)顯示

     }));


   }

構(gòu)造切片數(shù)據(jù)時,過濾掉uploaded為true的


async uploadChunks(data) {

 var chunkData = data.chunkList;

 const requestDataList = chunkData

+    .filter(({ uploaded }) => !uploaded)

   .map(({ fileHash, chunk, fileName, index }) => {

     const formData = new FormData();

     formData.append('md5', fileHash);

     formData.append('file', chunk);

     formData.append('fileName', index); // 文件名使用切片的下標(biāo)

     return { formData, index, fileName };

   })

}

垃圾文件清理

隨著上傳文件的增多,相應(yīng)的垃圾文件也會增多,比如有些時候上傳一半就不再繼續(xù),或上傳失敗,碎片文件就會增多。解決方案我目前想了2種

前端在localstorage設(shè)置緩存時間,超過時間就發(fā)送請求通知后端清理碎片文件,同時前端也要清理緩存。

前后端都約定好,每個緩存從生成開始,只能存儲12小時,12小時后自動清理

以上2中方案似乎都有點(diǎn)問題,極有可能造成前后端因時間差,引發(fā)切片上傳異常的問題,后面想到合適的解決方案再來更新吧。

Done: 續(xù)傳到這里也就完成了。


秒傳

這算是最簡單的,只是聽起來很厲害的樣子。原理:計算整個文件的HASH,在執(zhí)行上傳操作前,向服務(wù)端發(fā)送請求,傳遞MD5值,后端進(jìn)行文件檢索。若服務(wù)器中已存在該文件,便不進(jìn)行后續(xù)的任何操作,上傳也便直接結(jié)束。大家一看就明白

async handleUpload(resume) {

   if (!this.container.files) return;

   const filesArr = this.container.files;

   var tempFilesArr = this.tempFilesArr;


   for (let i = 0; i < tempFilesArr.length; i++) {

     const fileChunkList = this.createFileChunk(

       filesArr[tempFilesArr[i].index]

     );


     // hash校驗(yàn),是否為秒傳

+      tempFilesArr[i].hash = await this.calculateHash(fileChunkList);

+      const verifyRes = await this.verifyUpload(

+        tempFilesArr[i].name,

+        tempFilesArr[i].hash

+      );

+      if (verifyRes.data.presence) {

+       tempFilesArr[i].status = fileStatus.secondPass;

+       tempFilesArr[i].uploadProgress = 100;

+      } else {

       console.log('開始上傳切片文件----》', tempFilesArr[i].name);

       await this.uploadChunks(this.tempFilesArr[i]);

     }

   }

 }

 // 文件上傳之前的校驗(yàn): 校驗(yàn)文件是否已存在

 verifyUpload(fileName, fileHash) {

   return new Promise(resolve => {

     const obj = {

       md5: fileHash,

       fileName,

       ...this.uploadArguments //傳遞其他參數(shù)

     };

     instance

       .post('fileChunk/presence', obj)

       .then(res => {

         resolve(res.data);

       })

       .catch(err => {

         console.log('verifyUpload -> err', err);

       });

   });

 }

Done: 秒傳到這里也就完成了。

后端處理

文章好像有點(diǎn)長了,具體代碼邏輯就先不貼了,除非有人留言要求,嘻嘻,有時間再更新

Node版

請前往 https://github.com/pseudo-god... 查看

JAVA版

下周應(yīng)該會更新處理

PHP版

1年多沒寫PHP了,抽空我會慢慢補(bǔ)上來

待完善

切片的大?。哼@個后面會做出動態(tài)計算的。需要根據(jù)當(dāng)前所上傳文件的大小,自動計算合適的切片大小。避免出現(xiàn)切片過多的情況。

文件追加:目前上傳文件過程中,不能繼續(xù)選擇文件加入隊列。(這個沒想好應(yīng)該怎么處理。)

更新記錄

組件已經(jīng)運(yùn)行一段時間了,期間也測試出幾個問題,本來以為沒BUG的,看起來BUG都挺嚴(yán)重

BUG-1:當(dāng)同時上傳多個內(nèi)容相同但是文件名稱不同的文件時,出現(xiàn)上傳失敗的問題。


預(yù)期結(jié)果:第一個上傳成功后,后面相同的問文件應(yīng)該直接秒傳


實(shí)際結(jié)果:第一個上傳成功后,其余相同的文件都失敗,錯誤信息,塊數(shù)不對。


原因:當(dāng)?shù)谝粋€文件塊上傳完畢后,便立即進(jìn)行了下一個文件的循環(huán),導(dǎo)致無法及時獲取文件是否已秒傳的狀態(tài),從而導(dǎo)致失敗。


解決方案:在當(dāng)前文件分片上傳完畢并且請求合并接口完畢后,再進(jìn)行下一次循環(huán)。


將子方法都改為同步方式,mergeRequest 和 uploadChunks 方法





BUG-2: 當(dāng)每次選擇相同的文件并觸發(fā)beforeUpload方法時,若第二次也選擇了相同的文件,beforeUpload方法失效,從而導(dǎo)致整個流程失效。

原因:之前每次選擇文件時,沒有清空上次所選input文件的數(shù)據(jù),相同數(shù)據(jù)的情況下,是不會觸發(fā)input的change事件。


解決方案:每次點(diǎn)擊input時,清空數(shù)據(jù)即可。我順帶優(yōu)化了下其他的代碼,具體看提交記錄吧。


<input

 v-if="!changeDisabled"

 type="file"

 :multiple="multiple"

 class="select-file-input"

 :accept="accept"

+  οnclick="f.outerHTML=f.outerHTML"

 @change="handleFileChange"/>

重寫了暫停和恢復(fù)的功能,實(shí)際上,主要是增加了暫停和恢復(fù)的狀態(tài)





之前的處理邏輯太簡單粗暴,存在諸多問題。現(xiàn)在將狀態(tài)定位在每一個文件之上,這樣恢復(fù)上傳時,直接跳過即可





封裝組件

寫了一大堆,其實(shí)以上代碼你直接復(fù)制也無法使用,這里我將此封裝了一個組件。大家可以去github下載文件,里面有使用案例 ,若有用記得隨手給個star,謝謝!

偷個懶,具體封裝組件的代碼就不列出來了,大家直接去下載文件查看,若有不明白的,可留言。


組件文檔

Attribute

參數(shù) 類型 說明 默認(rèn) 備注

headers Object 設(shè)置請求頭

before-upload Function 上傳文件前的鉤子,返回false則停止上傳

accept String 接受上傳的文件類型

upload-arguments Object 上傳文件時攜帶的參數(shù)

with-credentials Boolean 是否傳遞Cookie false

limit Number 最大允許上傳個數(shù) 0 0為不限制

on-exceed Function 文件超出個數(shù)限制時的鉤子

multiple Boolean 是否為多選模式 true

base-url String 由于本組件為內(nèi)置的AXIOS,若你需要走代理,可以直接在這里配置你的基礎(chǔ)路徑

chunk-size Number 每個切片的大小 10M

threads Number 請求的并發(fā)數(shù) 3 并發(fā)數(shù)越高,對服務(wù)器的性能要求越高,盡可能用默認(rèn)值即可

chunk-retry Number 錯誤重試次數(shù) 3 分片請求的錯誤重試次數(shù)

Slot

方法名 說明 參數(shù) 備注

header 按鈕區(qū)域 無

tip 提示說明文字 無

后端接口文檔:按文檔實(shí)現(xiàn)即可

藍(lán)藍(lán)設(shè)計sillybuy.com )是一家專注而深入的界面設(shè)計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計、BS界面設(shè)計 、 cs界面設(shè)計 、 ipad界面設(shè)計 、 包裝設(shè)計 、 圖標(biāo)定制 、 用戶體驗(yàn) 、交互設(shè)計、 網(wǎng)站建設(shè) 、平面設(shè)計服務(wù)






日歷

鏈接

個人資料

存檔