<address id="ttjl9"></address>

      <noframes id="ttjl9"><address id="ttjl9"><nobr id="ttjl9"></nobr></address>
      <form id="ttjl9"></form>
        <em id="ttjl9"><span id="ttjl9"></span></em>
        <address id="ttjl9"></address>

          <noframes id="ttjl9"><form id="ttjl9"></form>

          首頁

          掌握這20條用戶體驗設計原則,助力設計成長!

          ui設計分享達人

          文章整理了20條用戶體驗設計原則,希望通過這份簡潔易懂的合集能夠讓你對用戶體驗領域有一個初步的概覽和了解。

          1.以用戶為中心 

          這是最常被提及的用戶體驗設計基礎,當涉及到產品設計決策時,提醒我們要學會使用同理心,而不是僅憑個人的想法或意見。

          真正好的用戶體驗設計是為用戶量身打造的,用戶的意見、痛點、愿望、偏好和需求對產品來說至關重要,所以在項目初始階段需要投入大量的時間和精力去了解用戶。

          用戶體驗研究重點是了解用戶,為接下來的產品設計做準備。以用戶為中心的設計理念是設計師迎合用戶的需求,區分了設計任何人都可以使用的產品和為目標用戶設計的產品。


          一款特定的產品需要面對不同的目標群體,前期研究中需要了解目標人群需要什么并在產品中反映出來,這是針對性很強的設計研究。 


          2.了解信息架構

          可能很多人對信息架構的定義很模糊,這里舉個例子來具象說明一下信息架構的含義。

          例如在一款產品中,如果把所有內容都堆到一個列表或頁面中,可能我們將無法使用這款產品,所以我們看到大多數的App和網站都包含很多的導航和頁面結構,按照內容重要程度有序地來組織內容。

          信息體系結構的最終目標是幫助用戶理解他們在看什么,并幫助他們找到需要尋找的內容。

          信息架構在制作線框圖或原型之前完成,因為它是產品的基礎,有助于設計師考慮什么功能是最重要的,哪些是用戶最需要的以及哪些次要內容可以隱藏起來等。

          這種結構與產品的導航設計密切相關,有助于將用戶引導到正確的位置。導航和信息架構都試圖讓用戶以最少的認知努力來完成操作。


          信息架構的設計不當會造成重大故障甚至可能危及整個產品。如果用戶在使用產品時找不到任何想要的內容,點擊任何元素都沒有反應,會給用戶帶來很糟糕的使用體驗。 


          3.考慮使用場景

          沒有場景,任何設計都很難生效。設計師在項目開始時會投入時間去了解用戶面臨的問題以及圍繞這些問題的背景。


          這條原則有助于設計師考慮還有哪些因素會影響用戶和產品,很多產品設計會為用戶提供一些有助于消除使用摩擦的操作提示。 
          例如在設計表單時,會盡可能的添加 輸入提示,最大程度地減少用戶出錯的機會。 


          4.了解一致性及其重要性

          保持一致性是用戶體驗設計的關鍵原則。擁有一致設計的產品可以更快地被新用戶接受,因為用戶不需要再次學習如何操作,他們會回憶起之前的操作習慣并將其作為指導,這也解釋了為什么同類型的產品例如電商類App頁面設計的很相似。

          保持一致意味著在需要時可以重復使用某些UI組件,并在整個產品中保持一致的行為。例如當點擊或懸停在按鈕上面時,所以按鈕的狀態應該是一致的。


          從邏輯上講,產品越大,這種一致性會變得越來越有挑戰性,這促使許多設計團隊創建自己的設計系統。一款產品的學習曲線越長越陡,放棄的用戶就會越多,在市場營銷中,這通常被稱為銷售漏斗中的漏洞。 


          5.給予用戶適當的控制權

          這條原則意味著用戶希望能控制產品,無論是完成任務還是定制滿足他們需求的內容。

          在設計過程中一直試圖給用戶盡可能多的控制權,例如允許用戶撤消操作、更改設置、自定義UI外觀、創建快捷方式等中。


          需要注意的是,當提供太多選項或用戶太依賴于自己的選擇時,用戶可能會不知所措,造成所謂的 選擇悖論。所以在設計時要了解用戶樂于掌控的余地,不能讓用戶感到使用壓力。 


          6.把可用性放在首位

          在整體上看,建立高標準的可用性是為用戶做的最好的事情,有助于檢查用戶是否能夠輕松地完成任務、產品是否正常運行以及是否完成工作。


          可用性的重要之處在于要理解可用性的靈活性和重要性。 


          7.了解用戶測試

          結合可用性的概念,我們還要進行用戶測試,這是設計師對工作進行測試的方式,對新的產品來說至關重要。

          當設計思想和理念被轉化為有形的原型時,設計師要觀察真實的用戶是如何與之交互的,可以通過許多不同的方式例如簡單的A/B測試到全面的審核測試等來實現。


          測試通常分幾輪進行,團隊在向原型添加更多細節之前驗證每個步驟。隨著測試結果的出現,設計也隨之發生了變化。 
          如果發生更改,將會進行新一輪的測試,通過這個過程,設計團隊可以改進他們的工作,直到達到可用性標準。 


          8.少即是多

          在創造力和創造獨特事物的渴望中,很多設計師很容易無意中弄亂產品界面甚至產品本身。

          功能過多的產品可能會失去焦點并削弱吸引力。具有太多元素的頁面會變得充滿視覺沖擊,但也會給用戶帶來負面體驗,在設計時要學會克制并優先考慮真正關鍵的部分很重要。


          另外手機端的屏幕空間非常小,創建一個有效的布局,想出巧妙的方法來隱藏次要元素并創建一個令人愉悅的界面需要付出很大的努力和創造力。 


          9.視覺層次

          視覺層次是向用戶傳達產品中元素重要性的方式。良好的層次結構有助于用戶視線在界面上移動,并立即了解最重要的內容以及這些內容與其他部分的關系。

          視覺層次結構與布局設計緊密相連,幫助用戶消化所接觸到的信息。


          創建層次結構從概念的草圖開始,一直持續到完成設計。例如發送按鈕通常會用綠色而是不紅色,而次要按鈕會顯示為灰色或與背景混合,并顯示“撤消”或“返回”。 


          10.了解用戶的心智模型

          為用戶創建心智模型是嘗試使用同理心的一種方式,是幫助設計師從用戶的角度看待問題的工具。

          正確使用意味著用戶無需投入精力就可以使用的直觀產品,而錯誤的思維模型會導致一些問題,例如界面混亂、高昂的交互成本。


          為了匹配用戶的心智模型,可以采用多種不同類型的研究方法,常見的方法包括 卡片分類、決策樹、對用戶行為的密切觀察,或者使用大量的數據來建立關鍵用戶的心理模型。 


          11.設計中的講故事

          講故事的方式更加直觀,利用圖像、視頻、動畫和文本等元素讓整個頁面與用戶對話。用戶體驗設計中的視覺敘事是為了喚起用戶的情感,給用戶留下持久的印象。


          想出一種可視化的方式來傳達復雜的內容具有挑戰性,但同時也是有益的,可以更好地接近用戶并將其作為提高產品可學習性的方法。 


          12.不要直接跳到高保真原型上

          高保真原型是設計項目的最終目標,但是直接使用原型軟件不斷添加各種頁面細節是錯誤的操作。


          避免直接出高保真的主要原因是因為這樣做的成本會更高。在沒有任何用戶研究和測試的情況下,一款產品無論具有多少的細節都有可能面臨不符合用戶使用的情況。 


          13.可訪問性測試很重要

          不僅要檢查關鍵用戶是否可以流暢地使用產品,還應該檢查其他所有用戶例如少數群體等是否都能夠正常使用產品。


          事實上,殘疾人和其他用戶一樣需要數字產品,但很多產品在設計時并沒有考慮到這些群體,但這也提供了一個機會,為所有用戶提供一個可以依賴的好產品。 


          14.熟悉并在用戶體驗設計中使用

          我們知道為用戶提供一致的設計有助于克服學習曲線,同時為用戶提供熟悉的東西也有助于縮短學習曲線。

          例如,大多數用戶都會立即識別某些UI組件(漢堡菜單/單選按鈕),這意味著他們會本能地知道這些組件代表什么意思或者如何操作。

          使用用戶已經熟悉的東西并不一定會讓產品的獨特性消失,有經驗的設計師會利用這種熟悉性來來創造一些獨特的設計,同時也是直觀的,不需要太多努力就可以使用。


          設計一個完全不依賴熟悉度的產品可能是具有風險的行為,因為它很容易讓那些不熟悉產品的用戶超負荷,形成巨大的學習曲線,增加用戶負擔。 


          15.了解交付成果的力量

          可交付成果是可以在整個團隊中交付的內容,包括用戶畫像、心智模型、用戶旅程以及線框圖和原型等,是一種有形和具體的表現。

          可交付成果是用戶體驗設計原則,可以幫助設計團隊和其他利益相關者理解和交流概念。

          ▲ 用戶畫像可以捕捉理想用戶,并提供可以相關聯的真實面孔,是一種指導設計的工具。用戶旅程圖幫助設計師了解用戶完成任務需要的具體步驟,有助于確保這些步驟確實可以輕松執行,并且整個過程很流暢。


          這些交付成果服務于關鍵功能,設計師需要在整個項目中都依賴它們,不斷轉換為用戶可以與之交互的真實有形的設計。 


          16.專業的原型設計工具

          用戶體驗設計的過程不是線性的,而是一個循環。無論創建什么樣的產品,都需要專業的原型工具,將基本框架放在一起,然后添加可能需要的所有細節。


          從邏輯上講,設計團隊的具體需求會因團隊而異,但一些關鍵功能例如團隊協作、需求管理、交互設計和開發移交等,對于大多數團隊來說是必要的。 


          17.精心管理產品需求

          一切都從收集需求開始,然后慢慢創建關鍵列表。雖然簡單地列出一個列表聽起來很容易,但隨著項目的進展,要保持列表的條理性確實是一個挑戰。


          除了創建需求和檢查復選框之外,還有一個問題就是調整需求,需要從 設計、技術和業務各個方面來處理各種需求,還要確保這些需求之間沒有相互矛盾。  


          18.了解移動和網絡產品之間的差異

          網頁端和移動端產品最明顯的區別是屏幕尺寸,這意味著所有的視覺層次結構和信息架構都將將從Web到App發生變化。


          移動端產品會有更多影響設計決策的因素,例如設備的操作系統、使用產品的環境等。了解移動端產品在 導航設計、用戶流程等關鍵方面的差異是至關重要的用戶體驗設計原則。 


          19.利用UX設計模式

          幾乎所有的產品都專注于設計模式,它們可靠、易于查找并通過減少設計時間來為項目增加實用性。


          ▲ 當用戶在谷歌搜索中輸入的內容有問題時,谷歌會提供一個相關的搜索提示,輔助用戶進行精確地搜索,解決用戶使用不同方式在搜索欄中傳達他們正在尋找的內容的問題。 


          20.使用合適的工具才能有效

          擁有單一的內容來源可以為團隊帶來清晰性和高效性,如果線框和原型分散在多個渠道中,這種內容的集合就會變得很難達成。


          通過合適高效的工具能夠避免產品在到達終點時遇到各種各樣的可用性問題,防止產品細節沒有表現出來或者被忽略。 


          最后

          通過這份用戶體驗設計原則的合集希望能夠讓你對這個領域有一個大致的了解。

          沒有人知道用戶體驗設計在未來會引領我們走向哪里,不過我們可以確定,無論它帶給我們什么,肯定都會很有趣。

          慢慢來比較快,希望對你有所幫助~

          文章來源:站酷  作者:Clippp
          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          騰訊公益小紅花火爆全網,背后的設計思維是什么?

          ui設計分享達人

          今年是騰訊發起99公益日的第七個年頭。騰訊公益不僅在配捐機制、產品體系、企業聯動、公益基礎建設上全面升級,還連接數億網友、近萬家慈善組織和愛心企業,為全民公益交出一張漂亮的成績單:

          數據顯示,小紅花互動人次超1.25億,送小紅花、答公益題目等行為公益實現破圈傳播,億萬愛心網友共同領取了超9000萬朵助力小紅花,共計有超過6870萬人次在99公益日期間捐出35.69億元,加上騰訊公益慈善基金會的6億元資金支持,共募得善款41.69億元。

          99 公益日為何能實現破圈傳播,作為騰訊公益日和 99 公益日的品牌符號,小紅花的設計背后又傳達了怎樣的思考?今天就來聊聊小紅花那些事。



          2015年9月9日,騰訊公益聯合國內數百家公益組織、知名企業共同發起了中國第一個互聯網公益日。

          為了讓用戶了解互聯網公益的核心特色與參與方式,讓更多的人參與到互聯網公益中,第一屆 99 公益日的活動主題定調為“一起愛”,在logo的設計中也借用了“無限”符號表示“愛無止境”的含義。


          在前三年的 99 公益日中,募款額度得到了廣度上的增長,在用戶已經了解到互聯網公益低門檻、多形式、透明度、可記錄的特點之后,如何留住用戶,對互聯網公益形成日常習慣和持久投入,就成為了設計亟需解決的問題。

          “小紅花”是騰訊公益平臺在2018年給出的答案。因為小紅花作為國人的集體回憶,關聯著你我兒時從老師那里收獲到的鼓勵。每一朵小紅花背后,是我們完成的一件“好事”。

          延續小紅花的記憶線索進行延展,在公益中,小紅花是對用戶的捐贈給予的最大肯定,是受助者正在發生的改變。在傳播上,小紅花是記錄用戶每一次公益行為的符號,通過「戴小紅花,一塊做好事」而得到成就感的有效激勵。

          于是,2018年99公益日的主視覺上,無數的愛心化為花瓣,匯聚成一朵小紅花,這是小紅花在騰訊公益平臺的初次綻放。



          為了讓品牌有延續性,加深用戶對小紅花和99公益日的認知,小紅花作為核心品牌元素開始貫穿在每一年99公益日的主視覺中,并通過不同的畫面故事表達每一年的主題。

          比如,2018年的主題是積小善,成大愛,于是在設計中,讓很多愛心小花匯聚在一起,讓小的愛心變成大愛;2019年的主題是一塊做好事,通過每個人的善意匯聚成小紅花……



          在2019年,“小紅花”正式成為騰訊公益與99公益日的品牌符號。



          從2020年開始,小紅花開始發力于傳播,聯動外部品牌 IP 如QQ、微信、Bilibili、狐妖小紅娘等開啟推廣,在各種不同的場景,詮釋“一塊做好事”的內涵。

          這一年,小紅花之歌火了,同名神曲MV播放量超1億次;在線下,小紅花也開到喜茶等連鎖品牌的店里。

          而2021年,屬于用戶獨特的小紅花愛心賬戶上線了,用戶在騰訊公益平臺做好事打卡,向好友發起集小紅花的自發傳播,從而爭取更大的配捐額,在增強用戶捐款積極性的同時,撬動更多用戶了解并參與到活動中來。


          小紅花愛心賬戶


          用戶還可將積累的小紅花兌換周邊禮品。在推廣上則從創作入手,發起共繪小紅花的活動。



          可以說,小紅花串聯起了用戶從感知、到行動、到反饋的全流程,保證了用戶參與互聯網公益的動機和動力。

          在預熱推廣階段,騰訊公益推出一支小紅花為主角的宣傳片,試圖為小紅花是什么,做出來自官方的定義。

          不管是線上線下征集用戶繪制的小紅花,“每個人的小紅花”畫展,還是在感恩日隨證書送出的小紅花畫作,都讓用戶全方位地感受到騰訊公益小紅花的“玩法”,也為小紅花元素賦予了豐富的內涵。

          征集到的部分小紅花作品


          寄出公益榮譽證書


          愛心用戶的開箱視頻


          99公益日期間,小紅花與騰訊新聞、微保、騰訊視頻、騰訊會議等多產品的玩法聯動,讓小紅花開遍“地球村”。


          多款產品聯動一塊做好事


          而在線下,小紅花也伴隨系列廣告,落地在線上下,IP聯盟、異業合作、核心城市燈光投影秀等,讓小紅花無處不在。


          部分城市地標燈光投影秀


          最后,小紅花這一品牌形象的成功,不僅在公益設計這一領域上有借鑒的意義,在品牌IP的設計上同樣有值得學習的地方。

          文章來源:站酷  作者:零弟小武
          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          為什么越簡單的設計越說不出理由

          ui設計分享達人

          常見場景


          設計師日常工作中,經常遇見的那些顯而易見的設計邏輯,卻難以給出設計理由的情況到底指的是什么呢?


          以我自己近期的工作為例,不妨為大家舉個簡單的例子:


          下圖是一個補貼規則的設置流程,在用戶未設置補貼規則之前,明確告知用戶還未設置補貼規則,當用戶設置了補貼規則后,可以對補貼規則進行修改。



          我認為這是一個非常簡單且合理的頁面路徑跳轉,并且在很多現有的產品中都有類似這樣的邏輯存在。然而在與上下游同學對接的過程中,卻遇到了不同的意見:有人認為沒有必要區分用戶是否設置了規則,用戶未設置規則可以直接展示系統默認的補貼條件和補貼范圍,如果用戶認為不合理,自行修改便是。

          不知道大家看到這里是什么感覺,我在聽到「方案二」時的反應是:能夠理解卻并不認同,說不出來哪里不對,就是覺得這事它不應該這樣。


          以上,就是在我工作中發生的一次非常具體的案例。


          直覺真的不如推理靠譜嗎?


          那么為什么我會產生“感覺哪里不對,卻又說不出為什么”的強烈感受呢?


          最直接的原因是,這樣的設計方案(方案一)是用直覺做出來的,缺少了對方案本身的思考。


          直覺,指的是那些沒有經過分析推理的觀點,因此常常給人一種不靠譜的感覺。


          可是有時候我們依賴「直覺」做事真的就完全不靠譜嗎?帶著這樣的疑惑,我去查閱了一些相關的資料來輔助我更好理解這種直覺性思考,恰好找到了一個真實的實驗案例:


          1997年,Bechara, Antoine et在一個賭博游戲實驗中發現:「直覺」比「意識」更能指引正常人做出有利的的選擇。

          該實驗先后邀請了10名正常人和6名前額葉損傷的決策缺陷患者,以探究人們做出正確選擇是在對相關知識進行推理之前還是之后。在游戲開始前,工作人員給予每位參與者2000美金、發放4副牌,要求參與者在游戲過程中翻出100張卡片,并盡可能的多贏錢,但他們不會告知參與者每副牌中的卡片價值:從A、B兩副牌中翻出正常的卡片能賺100美金,C、D兩副牌中的正??ㄆ?0美金,同時每副牌中也隱藏著罰款,A、B兩副牌中的罰款比C、D兩副牌的罰款重,參與者很可能會輸光所有的錢。

          實驗結果顯示:正常人在意識到哪副牌贏面更大之前就開始選擇有利的卡牌,而決策缺陷患者即使知道了正確的策略,卻仍然繼續選擇對自己不利的卡牌。


          根據上述實驗,我們起碼能發現直覺未見得不可靠,也就是說,憑借直覺出的設計方案,并不意味著不是一個正確的方案


          可是在日常溝通協作的過程中,「直覺設計」一旦遇到不同的意見,就會缺少理論支撐。決策者無法判斷設計師的直覺是否可靠,從而覺得方案本身也不可靠。


          遇到這種看似「死胡同」的情況,我們應該怎么去思考呢?


          很簡單,直覺在前,策略性推理在后。


          喬納森?海特(Jonathan Haidt),著名社會心理學家,在《正義之心》中有提到:


          判斷和論證是兩個相互分離的過程,直覺與推理的關系就像大象與騎象人,騎象人(推理)騎在大象(直覺)上,騎象人不斷發展以服務于大象。


          拿上述的方案來說,當我面對這類的質疑時,我也會有愣住,但我知道我不能驚慌,而是該讓騎象人(推理)表演了。


          其實仔細分析一下上述案例就會發現,方案一和方案二最本質的區別在于:


          是否需要區分用戶(商家)自行設置過「補貼規則 」?


          百度百科對規則的定義是:


          規則,一般指由群眾共同制定、公認或由代表人統一制定并通過的,由群體里的所有成員一起遵守的條例和章程。


          規則本身是屬于利益相關者之間的約定。按照這個邏輯,「補貼規則」可以理解為用戶(商家)與消費者形成的基本約定


          用戶(商家)未設置規則,如果系統直接展示默認的補貼條件和補貼范圍,就會給用戶(商家)一種平臺借以商家的名義與消費者形成了約定的印象,這與現實不符,甚至可能給用戶(商家)的業務帶來不必要的紛爭。因此,區分用戶是否設置過補貼規則是非常有必要的。


          為什么要為自己的設計辯護?


          在上述場景中,雖然我的直覺先于理性給我發送了信號,但設計師如果光依靠直覺卻給不出任何說明,同樣會帶來一系列麻煩。


          湯姆·格里弗(Tom Greever)在一篇文章提到,偉大的設計往往取決于你怎么說。


          描述設計不是一件容易的事情,但每個設計師都不得不向很多沒有設計經驗的人講述自己的設計,并且要讓他們信服自己是對的,這群人很可能是方案的決策者。決策者通常會選擇那個聽上去最合理的方案,所以方案的表述對于最終方案的確立至關重要。


          普通設計師和頂級設計師之間的差距不僅僅是他們解決問題的能力,還在于他們能否用一種讓人心服口服、并促使人們同意的方式來闡述他們是怎么解決問題的。理論上,最好的設計應該勝出,然而事實并非如此,設計評審很容易變成設計批判會,每個人都在告訴設計師要怎么設計。


          最終,那些能夠說服別人“我是對的”的人會勝出。設計師如果沒有辦法說服別人為什么他們要這么做,就不得不按照他們不同意的方式去修改設計,原因僅僅是因為他們沒有辦法簡要的為自己的設計辯護。


          聽起來似乎這些決策有失公允,甚至成了設計師的辯護大會,那么對于一些有著出色能力卻不善言辭的設計師而言,就真的沒有任何方法了嗎?


          如何突破直覺,能言善辯?


          設計師要想守衛自己的設計,就要警惕那些單憑設計直覺做出來的方案。


          設計直覺的形成與個人經歷、閱讀經歷相關。遇到相似的問題,設計師如果有這方面的經驗固然是好的,直接復用之前的做法可以大大提升設計效率。但我們完成設計后,最好想想哪些地方存在路徑依賴,以確保自己的方案能經得住質疑。


          一個最實用的可以判斷自己的設計方案,是不是由直覺得來的,就是多向自己提問。


          同樣,我們來用實際的案例做個說明:


          想想下圖中「智能上傳」「更多操作」按鈕放在表格的左下方行不行?


          很明顯不行,但重點是支持這么做不行的理由是什么?


          如果你的理由是:


          “別的頁面是將按鈕放在了列表左上角的”

          “放在左下角不好看呀”

          “沒見過有產品這么放啊”

          “......”


          那這個方案就是直覺設計的產物了。


          想要突破直覺設計,設計師需要盡可能在每個設計點上多思考幾步,比如:


          為什么別的頁面會將按鈕放在左上角?


          根據2006年NNGroup 在眼動實驗中的發現,人們在網絡中的閱讀成F型,即用戶進入頁面中的第一眼,通常會落在頁面的左上角,也就是說左上方的區域是頁面的黃金區?!钢悄苌蟼鳌埂父嗖僮鳌箤儆陧撁娴暮诵牟僮?,那么放在列表左上方是非常合理的。


          此外,我們可以看到頁面的翻頁器是可以篩選列表展示的條數,假設用戶設置的條數,超出了屏幕顯示范圍,也就意味用戶進入到頁面會看不到操作選項,所以按鈕放在表格的左下方也是不合理的。


          為什么別的頁面按鈕放在左上角這個頁面也要這么做?


          因為我們需要保障產品的一致性,產品的核心操作方式保持一致,可以有效地降低用戶的學習成本,避免不必要的思考。


          總結


          在設計協作的過程中,設計師不可避免地會接收到來自四面八方的聲音,而我自己也曾在設計溝通中陷入過類似困境,因此我越發明白只有清晰地表述出自己的設計思考,才可能贏得每個人的支持。


          • 憑借直覺出的設計方案,并不意味著不是一個正確的方案。

          • 直覺在前,策略性推理在后。

          • 頂尖的設計師,也是頂尖的交流者。

          • 要想守衛自己的設計,就要警惕那些單憑設計直覺做出來的方案。

          • 多向自己提問,以確保自己的方案能經得住質疑。


          以上是關于這篇文章的關鍵思考總結,回到設計師個體而言,我認為我們需要對直覺設計保持警惕,因為看似簡單的設計背后往往蘊含著復雜的設計原理,而一個好的設計師除了擁有過硬的設計能力,強大的設計思考力和表達能力以外,我相信同樣在跨學科的研究和學習上會遠強于普通設計師,否則根本無法支撐起背后的設計思考。

          文章來源:站酷  作者:范思蜀
          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務


          js_防抖與節流(閉包的使用)

          前端達人

          js的防抖與節流

          防抖事件

          定義:持續觸發事件,一定時間內沒有觸發事件,事件處理函數只會執行一次,
          當設定的時間內觸發過一次事件后會重新開始延時。
          例:輸入框的事件(2s顯示內容,不是實時刷新顯示內容),對比輸入框的內容事件。
          實時刷新的效果

           <div class="container"> <div class="left"> <p>實時刷新顯示內容</p> <input type="text" id="leftInput" /> <div class='textDiv' id="textShow"></div> </div> <div class="right"></div> </div> <script> var inputDom=document.getElementById('leftInput'); inputDom.addEventListener('keyup',function(e){ var textDom=document.getElementById('textShow'); console.log(e.target.value); textDom.innerText=e.target.value; }) </script>  
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17

          輸入123456會依次打印123456的金字塔
          在這里插入圖片描述

          防抖(1s內顯示輸入內容)

           <div class="container"> <div class="left"> <p>防抖(1s內顯示輸入內容)</p> <input type="text" id="leftInput" /> <div class='textDiv' id="textShow"></div> </div> <div class="right"></div> </div> <script> // 防抖 var inputDom = document.getElementById('leftInput'); // 函數柯里化 function debounce(delay, callback) { let timer return function(value) { //閉包內存泄漏 clearTimeout(timer) timer = setTimeout(function() { //執行 callback(value) }, delay) } } // 顯示內容的函數 function showText(value) { var textDom = document.getElementById('textShow'); console.log(value) textDom.innerText = value; } var debounceFunc = debounce(1000, showText); inputDom.addEventListener('keyup', function(e) { let value = e.target.value debounceFunc(value) }) </script>  
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36

          1s內輸入123456只會打印一次123456
          在這里插入圖片描述

          節流事件

          定義:一段時間直只調用一次事件處理函數
          實際用例:提交事件 、游戲的技能cd(在游戲cd中點擊n次都不會發動技能)

          // 節流
                      var skillDom = document.getElementById('skillTriger');
                      function throttle(wait,callback) {
                          let timeOut;
                          return function(value) {
                              if (!timeOut) {
                                  timeOut = setTimeout(function() {
                                      callback(value);
                                      //執行一次,時間段內的都不知執行
                                      timeOut = null;
                                  }, wait)
                              }
                          }
                      }
                      function skillEvent(value){
                          var textDom = document.getElementById('skillEventId');
                          console.log(value)
                          ++count
                          textDom.innerText = value+count;
                      }
                      var skillAc=throttle(3000,skillEvent)
                      var count=0
                      skillDom.addEventListener('click', function(e) {
                          let value = e.target.value
                          skillAc(value)
                      })  
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26

          在這里插入圖片描述

          完整的html

          <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>防抖與節流</title> </head> <style> * { margin: 0; padding: 0; } .container { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); width: 600px; height: 400px; background: #262626; display: flex; } .left { position: relative; width: 50%; height: 100%; background: #00cec9; box-sizing: border-box; overflow: hidden; } .right { position: relative; width: 50%; height: 100%; background: #b2bec3; } </style> <body> <div class="container"> <div class="left"> <p>防抖(1s內顯示輸入內容)</p> <input type="text" id="leftInput" /> <div class='textDiv' id="textShow"></div> </div> <div class="right"> <p>節流(3s內觸發一次)</p> <input type="submit" id="skillTriger" value="發動技能" /> <div class='skillEvent' id="skillEventId"></div> </div> </div> <script> // 防抖 var inputDom = document.getElementById('leftInput'); // 函數柯里化 function debounce(delay, callback) { let timer return function(value) { //閉包內存泄漏 clearTimeout(timer) timer = setTimeout(function() { //執行 callback(value) }, delay) } } // 顯示內容的函數 function showText(value) { var textDom = document.getElementById('textShow'); console.log(value) textDom.innerText = value; } var debounceFunc = debounce(1000, showText); inputDom.addEventListener('keyup', function(e) { let value = e.target.value debounceFunc(value) }) // 節流 var skillDom = document.getElementById('skillTriger'); function throttle(wait, callback) { let timeOut; return function(value) { if (!timeOut) { timeOut = setTimeout(function() { callback(value); //執行一次,時間段內的都不知執行 timeOut = null; }, wait) } } } function skillEvent(value) { var textDom = document.getElementById('skillEventId'); console.log(value) ++count
                          textDom.innerText = value + count; } var skillAc = throttle(3000, skillEvent) var count = 0 skillDom.addEventListener('click', function(e) { let value = e.target.value skillAc(value) }) </script> </body> </html>  
          
          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12
          • 13
          • 14
          • 15
          • 16
          • 17
          • 18
          • 19
          • 20
          • 21
          • 22
          • 23
          • 24
          • 25
          • 26
          • 27
          • 28
          • 29
          • 30
          • 31
          • 32
          • 33
          • 34
          • 35
          • 36
          • 37
          • 38
          • 39
          • 40
          • 41
          • 42
          • 43
          • 44
          • 45
          • 46
          • 47
          • 48
          • 49
          • 50
          • 51
          • 52
          • 53
          • 54
          • 55
          • 56
          • 57
          • 58
          • 59
          • 60
          • 61
          • 62
          • 63
          • 64
          • 65
          • 66
          • 67
          • 68
          • 69
          • 70
          • 71
          • 72
          • 73
          • 74
          • 75
          • 76
          • 77
          • 78
          • 79
          • 80
          • 81
          • 82
          • 83
          • 84
          • 85
          • 86
          • 87
          • 88
          • 89
          • 90
          • 91
          • 92
          • 93
          • 94
          • 95
          • 96
          • 97
          • 98
          • 99
          • 100
          • 101
          • 102
          • 103
          • 104
          • 105
          • 106
          • 107
          • 108
          • 109
          • 110
          • 111
          • 112
          • 113

          1

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

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          轉自:csdn
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 平面設計服務

          配合前端vue實現表格的增刪改查

          前端達人

          前言:

                  這個章節內容是比較多的,分為前端部分和后端部分。

          目錄:

          實現效果:增刪改查

           一、后端部分:

          (1)數據庫:

                  新建一張表user,設置幾個字段,效果如下:

           (2)egg邏輯部分:

          提供的接口:http://localhost:7001/setUserList

           (3)egg具體實現步驟:

          1、router.js中添加:

          2、新建:app / controller / new / user.js

          (1)查,模糊查詢 

          (2)增

           (3)改

           (4)刪

           user.js 源碼:

          3、引入mysql:點我

          4、跨域問題解決:點我

           二、前端部分:

          新建vue文件:testApi.vue

          1、初始化查詢列表數據:頁面展示列表,列表數據mouted獲取

          2、頁面點擊新增:展示彈框,并將彈框內容去除掉,點擊新增,將彈框內容發送給后端

           3、頁面點擊列表里面具體數據的編輯:彈框,并回填數據,修改將當前數據的id和表格數據傳給后端

          4、刪除按鈕,點擊出現二次確認彈框,點擊確認將當前數據的id給后端就行 

           testApi.vue 源碼:


          實現效果:增刪改查

           一、后端部分:

          (1)數據庫:

                  新建一張表user,設置幾個字段,效果如下:

           (2)egg邏輯部分:

          提供的接口:http://localhost:7001/setUserList

          1. get 請求,獲取數據,支持模糊查詢
          2. post 請求,新增數據
          3. put 請求,給后端當前數據id,修改內容
          4. delete 請求,根據數據id刪除當前條數據

           (3)egg具體實現步驟:

          1、router.js中添加:

           
          
          1. /**
          2. * 路由配置
          3. * @param app
          4. */
          5. module.exports = app => {
          6. const { router, controller } = app;
          7. //--------------------------------------------------
          8. // server接口
          9. //--------------------------------------------------
          10. app.get('/setUserList', controller.new.user.getUserList);
          11. app.post('/setUserList', controller.new.user.postUserList);
          12. app.put('/setUserList', controller.new.user.putUserList);
          13. app.delete('/setUserList', controller.new.user.deleteUserList);
          14. }

          2、新建:app / controller / new / user.js

          (1)查,模糊查詢 

          select * from user where name like ? % 內容 %

          (2)增

          this.app.mysql.insert('表名',內容)

           (3)改

          UPDATE loginlist SET `password` = 'Ad123456' WHERE id = 2

           (4)刪

          delete from user where id = 1

           user.js 源碼:

           
          
          1. /**
          2. * 用戶信息路由
          3. * @param app
          4. * @returns {HomeController}
          5. */
          6. const Controller = require('egg').Controller;
          7. class NewsController extends Controller {
          8. async getUserList() {
          9. //查詢庫里的user表
          10. let params = this.ctx.query //獲取路徑后面的參數
          11. console.log('用戶的參數:');
          12. console.log(params);
          13. let sql = 'select * from user'
          14. let initSql = sql
          15. let content = [];//參數
          16. let isMore = false;//是否有多個查詢參數
          17. /**
          18. * @模糊查詢-量大的時候效率低
          19. * select * from user where name like ? % 內容 %
          20. * 在user表中全局查找name值 == 內容的
          21. * % 內容 % 全局查找內容
          22. * 內容 % 查找以 內容 開頭的數據
          23. * */
          24. if(params.name){
          25. sql += " where name like ?";
          26. content.push( "%"+params.name+"%" );
          27. isMore = true;
          28. }
          29. if(params.age){
          30. if(isMore){//true代表有多個參數
          31. sql += "and age LIKE ?";//and是兩個條件都必須滿足,or是或的關系
          32. }else{
          33. sql += " WHERE age LIKE ?";
          34. }
          35. content.push( "%"+params.age+"%" )
          36. isMore = true;
          37. }
          38. if(params.address){
          39. if(isMore){//true代表有多個參數
          40. sql += "and address LIKE ?";//and是兩個條件都必須滿足,or是或的關系
          41. }else{
          42. sql += " WHERE address LIKE ?";
          43. }
          44. content.push( "%"+params.address+"%" )
          45. isMore = true;
          46. }
          47. if(params.phone){
          48. if(isMore){//true代表有多個參數
          49. sql += "and phone LIKE ?";//and是兩個條件都必須滿足,or是或的關系
          50. }else{
          51. sql += " WHERE phone LIKE ?";
          52. }
          53. content.push( "%"+params.phone+"%" )
          54. }
          55. //開啟分頁
          56. if(params.page || params.pageSize){
          57. let current = params.page;//當前頁碼
          58. let pageSize = params.pageSize;//一頁展示多少條數據
          59. sql += " limit ?,?";
          60. content.push((current-1)*pageSize,parseInt(pageSize));
          61. }
          62. let allList = await this.app.mysql.query(initSql);
          63. let userList= await this.app.mysql.query(
          64. sql,content
          65. );
          66. this.ctx.body = {
          67. code:200,
          68. masg:'success',
          69. data: {
          70. list:userList,
          71. total:allList.length
          72. }
          73. };
          74. }
          75. /**
          76. * 新增用戶信息
          77. * INSERT INTO loginlist (aaa,bbb,ccc) VALUES ('"'+111+'","'+222+'","'+333+'"')
          78. * this.app.mysql.insert('表名',內容)
          79. * this.app.mysql.insert('表名',{
          80. * name:123,
          81. * age:1,
          82. * address:西安
          83. * })
          84. */
          85. //
          86. async postUserList() {
          87. console.log(this.ctx.request.body);
          88. //新增數據-user表
          89. let data = this.ctx.request.body
          90. data.id = parseInt(Math.random()*100000)
          91. let insertResult = await this.app.mysql.insert(
          92. 'user', data
          93. );
          94. this.ctx.body = {
          95. code:200,
          96. masg:'success',
          97. data:insertResult
          98. };
          99. }
          100. /**
          101. * 修改用戶信息
          102. * UPDATE loginlist SET `password` = 'Ad123456' WHERE id = 2(唯一值),修改一個
          103. * UPDATE loginlist SET username = 'admins', `password` = 'Ad123456' WHERE id = 2,修改多個
          104. */
          105. async putUserList(){
          106. //新增數據-user表
          107. let id = this.ctx.query.id //獲取路徑后面的參數
          108. let data = this.ctx.request.body
          109. let sql = 'update user set '
          110. let isMore = false;//是否有多個查詢參數
          111. if(!id){
          112. this.ctx.body = {
          113. code:200,
          114. masg:'warning',
          115. data:'id沒有傳'
          116. };
          117. return
          118. }
          119. //姓名
          120. if(data.name){
          121. sql += 'name = "'+data.name+'"'
          122. isMore = true
          123. }
          124. //年齡
          125. if(data.age){
          126. if(isMore){
          127. sql += ',age = "'+data.age+'"'
          128. }else{
          129. sql += 'age = "'+data.age+'"'
          130. }
          131. isMore = true
          132. }
          133. //地址
          134. if(data.address){
          135. if(isMore){
          136. sql += ',address = "'+data.address+'"'
          137. }else{
          138. sql += 'address = "'+data.address+'"'
          139. }
          140. isMore = true
          141. }
          142. //手機號
          143. if(data.phone){
          144. if(isMore){
          145. sql += ',phone = "'+data.phone+'"'
          146. }else{
          147. sql += 'phone = "'+data.phone+'"'
          148. }
          149. isMore = true
          150. }
          151. //郵箱地址
          152. if(data.email){
          153. if(isMore){
          154. sql += ',email = "'+data.email+'"'
          155. }else{
          156. sql += 'email = "'+data.email+'"'
          157. }
          158. }
          159. sql += ' where id = ' + id
          160. let insertResult = await this.app.mysql.query(sql)
          161. this.ctx.body = {
          162. code:200,
          163. masg:'success',
          164. data:insertResult
          165. };
          166. }
          167. /**
          168. * 注銷用戶接口
          169. * DELETE FROM loginlist WHERE username = 'superman'
          170. */
          171. async deleteUserList(){
          172. //查詢庫里的user表
          173. let params = this.ctx.query //獲取路徑后面的參數
          174. console.log('用戶的參數:');
          175. console.log(params);
          176. let sql = 'delete from user where id = '+ params.id
          177. let res = await this.app.mysql.query(
          178. sql
          179. );
          180. this.ctx.body = {
          181. code:200,
          182. masg:'success',
          183. data:res
          184. };
          185. }
          186. /**
          187. * 模糊查詢封裝方法
          188. * @params = auth
          189. * */
          190. async query( auth ) {
          191. const TABLE_NAME = 'user';
          192. const QUERY_STR = 'id, name, age, phone, address';
          193. let sql = `select ${QUERY_STR} from ${TABLE_NAME} where authName like "%${auth.authName}%"`;
          194. const row = await this.app.mysql.query(sql);
          195. return row;
          196. }
          197. }
          198. module.exports = NewsController;

          3、引入mysql:點我

          4、跨域問題解決:點我

           二、前端部分:

          新建vue文件:testApi.vue

          1、初始化查詢列表數據:頁面展示列表,列表數據mouted獲取

           
          
          1. <el-table
          2. :data="tableInfo.list"
          3. style="width: 100%">
          4. <el-table-column
          5. type="index"
          6. label="序號"
          7. align="center">
          8. </el-table-column>
          9. <el-table-column
          10. prop="name"
          11. label="姓名"
          12. align="center">
          13. </el-table-column>
          14. <el-table-column
          15. prop="age"
          16. label="年齡"
          17. align="center">
          18. </el-table-column>
          19. <el-table-column
          20. prop="address"
          21. label="地址">
          22. </el-table-column>
          23. <el-table-column
          24. prop="phone"
          25. label="手機號">
          26. </el-table-column>
          27. <el-table-column
          28. prop="email"
          29. label="郵箱">
          30. </el-table-column>
          31. <el-table-column
          32. label="操作"
          33. width="100">
          34. <template slot-scope="scope">
          35. <el-button type="text" size="small" @click="editFun(scope.row)">編輯</el-button>
          36. <el-button type="text" size="small" @click="deleteFun(scope.row)">刪除</el-button>
          37. </template>
          38. </el-table-column>
          39. </el-table>
           
          
          1. mounted(){
          2. this.initPage()
          3. },
          4. methods: {
          5. /***
          6. * 獲取列表數據
          7. */
          8. initPage() {
          9. let params = {
          10. page: this.tableInfo.page, //當前頁
          11. pageSize: this.tableInfo.pageSize //一頁展示多少條
          12. }
          13. this.$axios.get('http://localhost:7001/setUserList',{
          14. params
          15. }).then(res => {
          16. this.tableInfo.list = res.data.data.list
          17. this.tableInfo.total = res.data.data.total
          18. }).catch(error => {
          19. this.$message(error.data.message)
          20. })
          21. },
          22. }

          2、頁面點擊新增:展示彈框,并將彈框內容去除掉,點擊新增,將彈框內容發送給后端

           3、頁面點擊列表里面具體數據的編輯:彈框,并回填數據,修改將當前數據的id和表格數據傳給后端

           

           

          4、刪除按鈕,點擊出現二次確認彈框,點擊確認將當前數據的id給后端就行 

           testApi.vue 源碼:

           
          
          1. <template>
          2. <div class="pro_body">
          3. <el-button type='success' @click="addModal">新增</el-button>
          4. <el-table
          5. :data="tableInfo.list"
          6. style="width: 100%">
          7. <el-table-column
          8. type="index"
          9. label="序號"
          10. align="center">
          11. </el-table-column>
          12. <el-table-column
          13. prop="name"
          14. label="姓名"
          15. align="center">
          16. </el-table-column>
          17. <el-table-column
          18. prop="age"
          19. label="年齡"
          20. align="center">
          21. </el-table-column>
          22. <el-table-column
          23. prop="address"
          24. label="地址">
          25. </el-table-column>
          26. <el-table-column
          27. prop="phone"
          28. label="手機號">
          29. </el-table-column>
          30. <el-table-column
          31. prop="email"
          32. label="郵箱">
          33. </el-table-column>
          34. <el-table-column
          35. label="操作"
          36. width="100">
          37. <template slot-scope="scope">
          38. <el-button type="text" size="small" @click="editFun(scope.row)">編輯</el-button>
          39. <el-button type="text" size="small" @click="deleteFun(scope.row)">刪除</el-button>
          40. </template>
          41. </el-table-column>
          42. </el-table>
          43. <el-pagination
          44. class="work_pagination"
          45. background
          46. :layout="'total,prev, pager, next,sizes'"
          47. :total="tableInfo.total"
          48. :hide-on-single-page="false"
          49. :current-page="tableInfo.page"
          50. :page-size="tableInfo.pageSize"
          51. @current-change="pageChange"
          52. @size-change="pageSizeChange"
          53. >
          54. </el-pagination>
          55. <!--彈框部分-->
          56. <el-dialog
          57. custom-class="modalName"
          58. :visible.sync="modal.show"
          59. :width="modal.type === 'delete'? '470px' : '800px'">
          60. <h3 v-if="modal.type === 'add'" slot="title">新增</h3>
          61. <h3 v-if="modal.type === 'edit'" slot="title">修改</h3>
          62. <h3 v-if="modal.type === 'delete'" slot="title">提示</h3>
          63. <div v-if="modal.type !== 'delete'" class="editNameBody">
          64. <el-form class="editNameFrom" :model="modalFrom" label-width="120px" label-position="right">
          65. <el-form-item label="姓名:">
          66. <el-input v-model="modalFrom.name"></el-input>
          67. </el-form-item>
          68. <el-form-item label="年紀:">
          69. <el-input v-model="modalFrom.age"></el-input>
          70. </el-form-item>
          71. <el-form-item label="手機號:">
          72. <el-input v-model="modalFrom.phone"></el-input>
          73. </el-form-item>
          74. <el-form-item label="郵箱:">
          75. <el-input v-model="modalFrom.email"></el-input>
          76. </el-form-item>
          77. <el-form-item label="地址:">
          78. <el-input v-model="modalFrom.address" type="textarea"></el-input>
          79. </el-form-item>
          80. </el-form>
          81. </div>
          82. <div v-if="modal.type === 'delete'">
          83. <i class="el-icon-warning" style="margin-right:7px;color:#FFAA00;font-size: 16px;"></i>請確認是否刪除
          84. </div>
          85. <div slot="footer" class="dialog-footer">
          86. <el-button @click="modal.show = false">取 消</el-button>
          87. <el-button v-if="modal.type === 'add'" type="primary" @click="addUserList">新增</el-button>
          88. <el-button v-if="modal.type === 'edit'" type="primary" @click="editUserList">修改</el-button>
          89. <el-button v-if="modal.type === 'delete'" type="primary" @click="deleteUserList">確 認</el-button>
          90. </div>
          91. </el-dialog>
          92. </div>
          93. </template>
          94. <script>
          95. export default {
          96. data() {
          97. return {
          98. tableInfo:{
          99. columns:[
          100. {
          101. title: '序號',
          102. type: 'index',
          103. },{
          104. title: '姓名',
          105. prop: 'name',
          106. align: 'center'
          107. },
          108. {
          109. title: '年齡',
          110. prop: 'age',
          111. align: 'center'
          112. },{
          113. title: '地址',
          114. prop: 'address',
          115. align: 'center'
          116. },{
          117. title: '郵箱',
          118. prop: 'email',
          119. align: 'center'
          120. },{
          121. title: '手機號',
          122. prop: 'phone',
          123. align: 'center'
          124. },
          125. {//內容slot
          126. slot: 'operateT'
          127. }
          128. ],
          129. list:[],
          130. page:1,
          131. pageSize:10,
          132. total:0,
          133. },
          134. modal:{
          135. show:false,
          136. type:'add'
          137. },
          138. modalFrom:{
          139. name:'',
          140. age:'',
          141. phone:'',
          142. address:'',
          143. email:''
          144. }
          145. };
          146. },
          147. mounted(){
          148. this.initPage()
          149. },
          150. methods: {
          151. /***
          152. * 獲取列表數據
          153. */
          154. initPage() {
          155. let params = {
          156. page: this.tableInfo.page, //當前頁
          157. pageSize: this.tableInfo.pageSize //一頁展示多少條
          158. }
          159. this.$axios.get('http://localhost:7001/setUserList',{
          160. params
          161. }).then(res => {
          162. this.tableInfo.list = res.data.data.list
          163. this.tableInfo.total = res.data.data.total
          164. }).catch(error => {
          165. this.$message(error.data.message)
          166. })
          167. },
          168. /**
          169. * 當前頁發生改變
          170. * */
          171. pageChange(page) {
          172. this.tableInfo.page = page
          173. this.initPage() //刷新列表數據
          174. },
          175. /**
          176. * 當前第幾頁發生改變
          177. * */
          178. pageSizeChange(pageSize) {
          179. this.tableInfo.page = 1
          180. this.tableInfo.pageSize = pageSize
          181. this.initPage() //刷新列表數據
          182. },
          183. //新增彈框
          184. addModal(){
          185. this.modalFrom ={
          186. name:'',
          187. age:'',
          188. phone:'',
          189. address:'',
          190. email:''
          191. }
          192. this.modal.show = true
          193. this.modal.type = 'add'
          194. },
          195. //修改彈框
          196. editFun(row){
          197. this.modalFrom = row
          198. this.modal.show = true
          199. this.modal.type = 'edit'
          200. },
          201. //刪除彈框
          202. deleteFun(row){
          203. this.modalFrom = row
          204. this.modal.show = true
          205. this.modal.type = 'delete'
          206. },
          207. addUserList(){
          208. this.$axios({
          209. method:'post',
          210. url:'http://localhost:7001/setUserList',
          211. data:this.modalFrom
          212. }).then(res => {
          213. this.$message.success('新增成功')
          214. this.initPage() //刷新數據
          215. this.modal.show = false
          216. })
          217. },
          218. editUserList(){
          219. this.$axios({
          220. method:'put',
          221. url:'http://localhost:7001/setUserList',
          222. params:{
          223. id:this.modalFrom.id
          224. },
          225. data:this.modalFrom
          226. }).then(res => {
          227. this.$message.success('修改成功')
          228. this.initPage() //刷新數據
          229. this.modal.show = false
          230. })
          231. },
          232. deleteUserList(){
          233. this.$axios({
          234. method:'delete',
          235. url:'http://localhost:7001/setUserList',
          236. params:{
          237. id:this.modalFrom.id
          238. }
          239. }).then(res => {
          240. this.$message.success('刪除成功')
          241. this.initPage() //刷新數據
          242. this.modal.show = false
          243. })
          244. }
          245. }
          246. }
          247. </script>
          248. <style lang='scss'>
          249. .modalName{
          250. h3{
          251. padding:10px;
          252. }
          253. }
          254. </style>


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

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          轉自:csdn
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 平面設計服務

          全面總結圖表設計的思路和方法

          資深UI設計者

          數據成為了日常工作的一大重要角色,越來越多的公司以數據驅動產品進行迭代。但令人困惑的是可視化圖表無處不矮,但卻給大家帶來了誤導。作者分享了一些簡單的思路與方法,以此來改善這些問題,希望對你有所幫助。


          越來越多的公司以數據驅動產品進行迭代,從中我們能看出數據的重要性。

          日常工作中,無論是匯報還是設計,都離不開圖表的使用。但令人困惑的可視化圖表無處不在,往往給人帶來誤導性,通過遵循下面這些簡單的思路和方法可以有效改善這些問題。

          一、選擇正確的圖表類型

          選擇錯誤的圖表類型,或默認使用最常見的類型,可能會混淆用戶對數據產生誤解。

          一組數據可以有多種表示方式,具體類型取決于用戶希望看到的內容。

          二、根據正負值確定方向

          當數據中出現正負值時,要先確定基線的位置,再確定數據位置,將正值分布在基線上側(X軸)或右側(Y軸),負值分布在下側(X軸)或左側(Y軸)。

          避免在基線的同一側同時添加正值和負值,造成用戶對圖表信息理解錯誤。

          三、始終從零開始繪制條形圖

          單看左側的條形圖,能發現B的值比D的值要多3倍以上,但在右側從零開始的條形圖中,實際差異要小得多。從零開始可確保用戶獲得更準確的數據展示。

          四、折線圖使用自適應Y軸

          對折線圖來說,如果始終將Y軸的比例限制為從零開始,一旦數據波動幅度很小,那整個折線圖會看起來很平坦,效果不明顯。

          折線圖主要用來表現趨勢,根據給定時間的數據調整比例,并保持折線區域能占到Y軸范圍的三分之二。

          五、使用折線圖時考慮時間間隔

          折線圖是由一條條小線段連接組成,這些線段展示了在短時間內數據是如何變化的。當時間間隔很大或數據更新不頻繁時,就要慎重考慮是否使用折線圖。

          例如想表示年收入,左側的兩個折線圖樣式都不太合適,每個月的收入是固定的數字,而折線圖展現的數據更像是收入的變化,相反右側的條形圖更適合來展示每月具體的收入。

          六、不要使用平滑的折線

          平滑的折線圖可能看著很舒服,但它們歪曲了背后的實際數據,而且過粗的線條掩蓋了真正的節點。

          七、謹慎使用雙軸折線圖

          當兩組數據出現X軸代表的信息相同但Y軸不同時,為節省空間我們可能會考慮用雙軸圖。

          但大部分雙軸圖難以閱讀,只是感覺圖表上有很多數據,但遠遠沒有單個圖表展示的清晰。

          八、限制餅圖的切片數量

          餅圖是最受歡迎但經常被誤用的圖表之一。在使用餅圖時,首先要注意切片的數量最好保持在5-7片。

          如果還有很多占比很小的切片,可以將這些全部歸到“其他”切片中。

          九、直接在圖表上標注

          如果沒有正確的標注,無論圖表設計的多好看都沒有意義。

          直接在圖表上標注數據或信息對使用者來說更直觀,更節省時間和精力。

          十、不要在切片上標注

          將數值放在切片上雖然很直觀,但可能會導致很多問題,例如左側餅圖數值的可讀性問題、切片太薄無法添加數值等,對比來看,右側餅圖添加標注的方式更合適。

          十一、餅圖切片的排序

          餅圖切片的排序是一個很容易忽略的問題,將餅圖切片只是一個開始,通過合理的排序保證用戶清晰觀看圖表才是關鍵。

          常見的排序方法是將面積最大的切片放在12點鐘位置,然后按順時針降序放置第二大的切片,以此類推。

          十二、避免隨機性

          同樣的建議適用于其他類型的圖表。盡量不要默認按字母順序排序,將最大值放在頂部(水平條形圖)或左側(對于垂直條形圖),以確保最重要的值占據最突出的空間,減少視線運動和閱讀圖表所需的時間。

          十三、避免極端的環形圖

          環形圖,又稱為甜甜圈圖,是餅圖的一種變體,本質是餅圖將中間區域挖空,用在多樣品間的多種數據的比較中。

          雖然環形圖騰出中間區域來顯示額外的信息,但犧牲清晰度走極端會讓圖表變得毫無用處。

          十四、讓數據自己說話

          不必要的設計樣式不僅會分散注意力,還可能導致用戶對數據誤解并產生錯誤印象,圖表在設計上應避免:

          • 3D元素、陰影、漸變;
          • 斑馬紋、過多的網格線;
          • 裝飾性過強的斜體、粗體或襯線字體。

          十五、選擇與數據性質匹配的調色板

          顏色是保持數據可視化有效的組成部分,在設計時考慮3種調色板類型:

          • 分類色板(左)適合顯示分類數據,當你想區別不連續且內在沒有順序關系的數據時可以使用這種類型;
          • 連續色板(中)適用于需要按特定順序放置的變量中,使用色調/亮度或兩者組合創建色板。
          • 離散色板(右)是兩個連續色板的組合,中間有一個中心值(通常為零)。不同的調色板會傳達正值和負值。

          十六、無障礙設計

          根據眼科研究中心的數據,大約每12個人中就有1個色盲,圖表只有在廣泛受眾可以訪問的情況下才是成功的:

          • 在調色板中使用不同的飽和度、亮度;
          • 黑白打印可視化圖表,檢查對比度和可讀性。

          十七、注重易讀性

          確保圖表排版在傳達信息并幫助用戶專注于數據,而不是分散注意力:

          • 選擇字跡清晰的字體,避免使用襯線和裝飾性很強的字體;
          • 避免使用斜體、粗體和全部大寫;
          • 確保文本與背景形成高對比度;
          • 不要旋轉文本。

          十八、使用水平條形圖代替旋轉標注

          這個簡單的技巧可以確保用戶能夠更有效地瀏覽圖表,而不會使他們感到緊張。

          十九、建立圖表庫

          如果你的任務是將交互式圖表添加到Web和移動項目中,那么首要考慮問題是將使用什么樣的圖表?

          基于定義的庫(Highcharts)進行設計將確保易于實現,并為我們提供大量的交互想法。

          二十、超越靜態報告

          通過更改參數、可視化類型、時間線幫助用戶進行探索,得出最大價值化的結論。例如IOS Health結合使用了各種數據表示來發揮優勢。



          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼ben_lanlan,報下信息,會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          文章來源:人人都是產品經理  作者:Clippp
          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 平面設計服務



          如何提升用戶體驗

          資深UI設計者

          現代人的生活離不開應用程序,我們的手機中有著各種各樣的app幫我們處理各種瑣事。各大互聯網公司開發多種應用商店,努力使我們的生活變得有趣,但要想提高整體的用戶體驗,還需要注意五點,不然再好的app也會讓用戶放棄使用。


          1.禁止使用大段的功能介紹

          我們必須要提示一下:如果一個應用程序要在手機屏幕上發揮作用——必須簡單。這個應用需要使用冗長的功能介紹,才能讓用戶熟悉使用起來,那很可能是開發人員在這個版本中設置太多功能。用戶并不介意多次更新程序,適應新版本,但他們也不可能為了使用程序而閱讀長如圣經般的介紹。


          2.牢記用戶需求


          如果想要急于求成,跳過用戶調研,上線新的應用,那么失敗的概率會大大增加。大多數應用開發團隊都容易犯這樣的錯誤,只拿到了用戶發送給支持團隊的數據。通過分析數據,就能迅速確定用戶所需的功能,使用缺陷等,但是,總的來說,聯系支持團隊的用戶是那些產生挫敗感的人;那么99%(或更多)的用戶從來沒有和支持部門談過?難道你不愿意讓他們一直滿意,而是花費時間,只讓使用支持功能的1%用戶滿意?


          即使你認為自己了解用戶需求,也需要與他們進行溝通。


          3.使用屏幕技術


          當人們花費了近萬元買了一部智能手機時,他們希望能使用手機上的所有功能。所以制作這款手機時沒有任何借口在視覺內容上偷工減料(或忽視任何技術能力)。這就是用戶花錢的原因,要想提高用戶體驗,就需要滿足用戶期望。


          4.停用費時的設置向導


          設置向導的本意是為用戶提供更好的內容,更能讓用戶獲取自己想要的。為了優化用戶體驗可以讓用戶填寫一些內容,但并不意味著暴露全部隱私。最好在需要時索取,而非提前取得全部數據。


          5.減少通知次


          每個軟件都想要發送通知,但是每一個通知都是必要的嗎?每隔兩秒鐘就有一些應用告知用戶一些無用消息,比如誰誰誰又發了微博,誰誰誰上線了,又或者誰誰誰開始直播了,可以根據用戶的興趣選取推送而不是一股腦全部告知用戶,所以請盡量減少的通知消息吧!

          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼ben_lanlan,報下信息,會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          文章來源:站酷  作者:馬克筆留學設計

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 平面設計服務


          B端產品設計規范之數據展示

          資深UI設計者


          數據展示有哪些?



          01.徽標

          是收納消息數量的樣式,一般出現在圖標或者頭像右上角。



          02.標簽

          數據展示里面抽取出來的共性特征,將它們轉化為標簽。標簽樣式有線框、帶不透明底或者面性。



          03.走馬燈

          相當于c端的輪播圖




          04.文字提示

          可以出現在鼠標懸浮按鈕時候的行為解釋說明,也可以是文案或者導航圖標的解釋說明。鼠標移入時候出現移出時候消失。



          05.氣泡卡片

          比起文字提示可以承載更多內容,相對彈窗,氣泡卡片操作更輕盈。




          06.標簽頁/選項卡

          標簽頁可以幫助用戶在一個頁面內快速切換不同類型內容,提升單個頁面整體的擴展性。標簽本質上就是內容區的導航。



          07.折疊面板

          折疊面板可以更好的收納內容區域,提高頁面利用率??梢院捅砀窠Y合使用,折疊表格部分詳情內容,使得縱向空間更節約。




          08.表格

          表格是數據展示的重要內容。當有大量結構化數據需要展示時或者需要對數據進行排序、搜索分頁時可以用表格進行展現。


          當筆記本過小,表格展示不全時候,可以固定首尾重要信息進行滾動。


          帶排序的表頭,可對數量或者金額進行排序。


          帶分組的表格,建議帶邊框并且用色塊區分表頭和內容。


          單元格可編輯


          批量選中時只會選中當前頁,因為分頁還沒加載出來,為了給用戶正確的引導,可以給上提示性文案,例如“已選中XX項內容”。


          如果當前頁批量選中的數據量不滿足要求,可以改變分頁器,增加當前頁數據量,從而增加選項。


          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼ben_lanlan,報下信息,會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          文章來源:站酷  作者:最多三分糖

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 平面設計服務



          如何做好直播設計的體系化復盤?

          資深UI設計者

          前言

          “直播”作為一個大熱領域,用戶規模早在 2020 年就突破了 5 億大關,在“直播+”的模式下,電商、教育甚至是醫美,都能在直播領域下找到新賽道,并產生持續性獲客。但就是這樣一個核心領域,具體要怎么分析復盤,卻鮮少看到系統化的文章。本文主要是結合我近期參與產品直播項目的思考,總結了自己的一套直播復盤方法論和大家分享。

          為什么要做直播復盤?

          雖然“直播+”模式已成為行業趨勢,但在產品接入直播模塊而產生的付費效益又不明顯時,其存在的意義和價值仍時常被挑戰,因此首要的就是驗證其價值;

          同時,新領域缺乏可復用的方法論,只有不斷探索、優化、沉淀才能促進其健康化生長;

          最后,在產品范圍下的直播領域,定向吸引的還是產品用戶為主,持續挖掘探索直播能為產品開辟的新賽道,為產品帶來拉新,是“直播+”模式對于產品的直接價值體現。

          如何做好直播設計的體系化復盤?

          直播復盤怎么做?

          直播具備快節奏性和強競爭性,在兼顧快速復盤的同時,還需要考慮階段性的整體化的對直播數據進行監控,因此需要將直播復盤分為快速復盤和階段復盤 2 個大方向。

          1. 快速復盤

          在直播結束當天或隔天對昨日數據進行快速復盤,此時重點關注單期直播下的直觀數據表現和用戶反饋。目的是獲得沉淀當天直播的經驗并快速應用至后續直播中,是一個不斷 PDCA 的過程。

          在復盤維度上,可以分為數據側和用戶側:

          數據側中我們重點聚焦本期的數據表現,同時橫向對比其他直播期,去明確本期的數據表現

          1)橫向對比時,需要將直播關注的 3 大核心數據(總人數、最高在線人數、評論人數、在線時長均值)與其他期對比,明確該期直播的“優劣”。

          如何做好直播設計的體系化復盤?

          當期直播核心數據

          2)聚焦本期時,重點關注直播數據的整體在線人數變化趨勢,定位到最高在線點,和直播內容擬合,能夠幫助我們定位直播的“高光點”。

          用戶側中則更關注主播在播、用戶在聽和答的過程,包含:

          • 直播過程中,用戶情緒、反饋異常的節點(如消極發言等),定位用戶可能存在的痛點。
          • 固定同學作為“直播觀眾”時,察覺到的異常問題(如信息銜接不自然等),及時復盤。
          • 在直播間的互動評論中,呼聲最高的內容,可以作為后續直播可以“返場”的內容,納入直播內容需求池中。

          2. 階段復盤

          在累計多場直播后,此時最需要的就是階段性的復盤,從宏觀角度對多期直播進行收斂分析,能夠幫助我們明確直播對于產品的核心價值,并定位核心用戶圈層、吸引點及直播應該要有的“節奏”。

          在階段復盤中,除了數據側、用戶側外,我們還需要關注市場側:

          數據側—不同于快速復盤,數據側我們關注整體宏觀角度上直播對產品的價值,以及直播整體的數據表現,熱點分布等

          1)從直播對產品價值定位來說,在未探索付費的情況下,直播能為產品做的就是吸引新用戶,增加用戶活躍、延長用戶在產品內停留的時長上。

          如何做好直播設計的體系化復盤?

          價值定位時關注的數據范圍

          在明確價值后,就應該明確后續要如何把直播做的更好,這里數據上可以分為 2 個大的方向,一是熱點分析,二是直播節奏分析。

          2)熱點分析上,需要從單期、分類、詞項拆解上看。首先,單期直播就是簡單地對單期直播數據進行排序,找到“好”的直播提煉其特征性;其次,分類分析上關注各類直播數據間的橫向對比,能從分類數據對比上,看出哪一類直播更吸引用戶;最后,通過對每期直播的標題進行詞項拆解,篩除掉無意義的詞項,再乘以對應期直播的人數,對每個出現 2 次及以上的詞項數據取出其對應的單期直播人數均值,即可定位到用戶最關注、最能吸引用戶的核心關鍵詞。

          如何做好直播設計的體系化復盤?

          熱點分析

          3)直播節奏分析上,得益于階段性復盤的龐大數據量,我們可以聚類出多期直播聚類下的直播趨勢線,在趨勢線上,亦關注 3 大核心點 “拉新、增長、流失”。

          a. 用戶進入直播的高峰期(即新增高峰),可用于定位直播亮點,并對應布局以留住用戶

          如何做好直播設計的體系化復盤?

          用戶進入直播節奏分析

          b. 通過直播數據排序后的高于中位數直播、低于中位數直播的 2 種直播數據走勢的對比,我們能夠看出好的直播應有的數據走勢應該是什么樣的。以我這次分析的直播為例,能夠直觀看出,“差”的直播在增長黃金期都“爬”的很慢,而在黃金期后直播數據逐漸平緩,“差”的直播數據就成了定局。因此要做的就是在增長黃金期,去盡量促進增長。

          如何做好直播設計的體系化復盤?

          用戶流入流出關系分析

          c. 那么在增長黃金期,從產品策略來看,要做的是留住用戶?還是盡量去拉新?從數據上,我們有 2 種方式判別,分別是相關性分析和假設分析。在相關性分析中,將新增人數/流失率對標最高在線人數,以數據模型分析其相關性,從相關系數來看哪個指標與最高在線人數相關性最高,即影響最大;在假設分析中,我們可以將“低于中位數”的直播數據中的新增人數/流失率分別對標“高于中位數”直播的數據,其他保持不變,看哪種情況下,最高在線人數是更高,數據是更好的,就可以定位出更應該在哪塊發力。

          用戶側—要明確直播受眾及用戶圈層,并針對這部分受眾的觀看體驗,進行服務體驗走查,更能夠幫我們明確后續業務重心、范圍及宣傳模式。

          在用戶圈層上,我們對觀眾數據清洗,從年齡、性別、地域、渠道等各項維度去定位觀眾的特征。同時,考慮到直播本身是以產品為載體,其用戶圈層基本上與產品本身重合,但會存在一定差異性。因此,此處可以結合 TGI 分析,可以定位到直播用戶圈層相較于產品來說的差異點,從而更針對受眾進行直播內容調整。

          如何做好直播設計的體系化復盤?

          用戶圈層分析

          同時,直播本身因其特殊性質,也可類比至服務體驗設計的思維,因此在用戶側分析時,從直播前-中-后 3 個大環節上分析用戶行為、需求、痛點、快點,從而定位到各個環節直播優化的機會點,推進優化。

          如何做好直播設計的體系化復盤?

          直播-體驗地圖

          市場側—在市場分析時,我們不僅需要關注那些在直播領域做的好的同類競品,同時也要去多分析在受眾群體中,最近的熱門話題是什么,有助于后續在宣發時引出直播核心話題,也能夠帶領我們思考直播的新賽道,以協助產品拓寬其用戶圈層。

          小結

          直播作為互聯網新賽道,直播+的模式可用于產品宣發、獲客、促活等各個方面,挑戰與機遇并存。但正因為是新賽道,也相對缺乏體系化的方法論。本文主要是分享我在工作中沉淀下來的直播復盤方法論,也歡迎大家有什么見解或者想法也可以與我分享。

          藍藍設計建立了UI設計分享群,每天會分享國內外的一些優秀設計,如果有興趣的話,可以進入一起成長學習,請掃碼ben_lanlan,報下信息,會請您入群。歡迎您加入噢~~希望得到建議咨詢、商務合作,也請與我們聯系。

          文章來源:優設  作者:番茄

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務




          CORS和JSONP的區別,如何解決跨域問題?

          前端達人

          在我們了解JSONP 和 CORS 之前我們先明確一下:

          我們為什么要使用cors和jsonp呢?

          實際上,cors和jsonp都是用于解決跨域問題,當兩個頁面的協議、域名、端口號中有一個不一致時就存在了跨域,一旦出現跨域,瀏覽器發送跨域請求后,請求回來的數據都會被瀏覽器所攔截,準備一張圖給大家看看:

           

          核心點:如何實現跨域數據請求?(?????)

          現下實現跨域數據請求,最主要的兩種解決方案分別是 JSONP 和 CORS 。

          JSONP  出現的早,兼容性好(兼容低版本 IE )。是前端程序員為了解決跨域問題,被迫想出來的一種 臨時解決方案,最主要的缺點 是只支持 GET 請求,不支持 POST 請求。
          CORS  出現的較晚,它是 W3C 標準,屬于跨域 Ajax 請求的根本解決方案。支持 GET 和 POST 請 求。缺點 是不兼容某些低版本的瀏覽器。

          什么是JSONP(???)

          JSONP (JSON with Padding) 是 JSON 的一種“使用模式”,可用于解決主流瀏覽器的跨域數據訪問的問題。

          JSONP的實現原理(???) 

          1. 概念:瀏覽器端通過 <script> 標簽的 src 屬性,請求服務器上的數據,同時,服務器返回一個函數的調用。這種請求數據的方式叫做 JSONP

          2. 特點: 

             JSONP 不屬于真正的 Ajax 請求,因為它沒有使用 XMLHttpRequest 這個對象

              JSONP 僅支持 GET 請求,不支持 POST、PUT、DELETE 等請求

          什么是CORS(?????)

          1. CORS (跨域資源共享) 由一系列 HTTP 響應頭組成,這些 HTTP 響應頭決定瀏覽器 是否阻止前端 JS 代碼跨域獲取資源

          2. 瀏覽器的同源安全策略默認會阻止網頁“跨域”獲取資源。但如果接口服務器配置了 CORS 相關的 HTTP 響應頭,就可以解除瀏覽器端的跨域訪問限制

           

           

          下面分別向大家演示通過CORS和JSONP實現跨域的案例:

          一、通過CORS中間件解決跨域問題 :

          index.html文件代碼演示:

          
              
          1. <!DOCTYPE html>
          2. <html lang="en">
          3. <head>
          4. <meta charset="UTF-8">
          5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
          6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
          7. <title>Document</title>
          8. <script src="jquery.min.js"></script>
          9. </head>
          10. <body>
          11. <button class="get">get請求</button>
          12. <button class="post">post請求</button>
          13. <script>
          14. $('.get').on('click', function() {
          15. $.ajax({
          16. method: 'get',
          17. url: 'http://127.0.0.1/api/get?name=hua&age=18',
          18. success: function(res) {
          19. console.log(res);
          20. }
          21. })
          22. })
          23. $('.post').on('click', function() {
          24. $.ajax({
          25. method: 'post',
          26. url: 'http://127.0.0.1/api/post',
          27. data: {
          28. name: 'lajitong',
          29. age: '111'
          30. },
          31. success: function(res) {
          32. console.log(res);
          33. }
          34. })
          35. })
          36. </script>
          37. </body>
          38. </html>

          此時會出現跨域問題,我們需要使用 cors 中間件解決跨域問題

          1. cors 是 Express 的一個第三方中間件。通過安裝和配置 cors 中間件,可以很方便地解決跨域問題

          2. 使用步驟

            • 安裝中間件: npm install cors

            • 導入中間件: const cors = require('cors')

            • 配置中間件: 在路由之前調用app.use(cors())

          3. express接口案例代碼

          
              
          1. // 導入 express 模塊
          2. const express = require('express')
          3. // 創建 express 的服務器實例
          4. const app = express()
          5. // 導入中間件
          6. const cors = require('cors')
          7. // 配置中間件
          8. app.use(cors())
          9. // 配置解析表單數據的中間件
          10. app.use(express.urlencoded({ extended: false }))
          11. // 導入路由模塊(被單獨分離后導入)
          12. const router = require('./apiRouter')
          13. // 把路由模塊,注冊到 app 上
          14. app.use('/api', router)
          15. // 調用 app.listen 方法,指定端口號并啟動 web 服務器
          16. app.listen(80, () => {
          17. console.log('http://127.0.0.1')
          18. })

          apiRouter路由文件代碼:

          
              
          1. const express = require('express');
          2. const router = express.Router();
          3. router.get('/get', (req, res) => {
          4. const query = req.query;
          5. res.send({
          6. status: 0,
          7. msg: 'get請求成功',
          8. data: query
          9. })
          10. })
          11. router.post('/post', (req, res) => {
          12. // const body = req.body; //獲取客戶端請求的數據
          13. res.send({
          14. status: 0,
          15. msg: 'post請求成功',
          16. data: req.body
          17. })
          18. })
          19. module.exports = router;

          在終端中運行express接口代碼后打開index.html文件并點擊get及post按鈕得到請求結果:

           二、通過JSONP中間件解決跨域問題 :

          創建 JSONP 接口的注意事項

          1. 如果項目中已經配置了 CORS 跨域資源共享,為了防止沖突,必須在配置 CORS 中間件之前聲明 JSONP 的接口

            否則 JSONP 接口會被處理成開啟了 CORS 的接口

          2. 實現步驟:

                  (1)獲取客戶端發送過來的回調函數的名字

                  (2)得到要通過 JSONP 形式發送給客戶端的數據

                  (3)根據前兩步得到的數據,拼接出一個函數調用的字符串

                  (4)把上一步拼接得到的字符串,響應給客戶端的 <script> 標簽進行解析執行

          案例代碼如下:

          
              
          1. //導入express模塊
          2. const express = require('express');
          3. //創建express服務器實例
          4. const app = express();
          5. //掛載路由
          6. app.get('/jsonp', (req, res) => {
          7. // 通過解構req.query客戶端通過查詢字符串的形式發送到客戶端的參數fn
          8. const { callback } = req.query
          9. //在服務器端定義一個obj對象
          10. const obj = {
          11. uname: 'zjj',
          12. age: '18'
          13. }
          14. //obj對象轉為res.send可處理的字符串形式后從服務器端相應回調函數至客戶端
          15. res.send(`${callback}(${JSON.stringify(obj)})`)
          16. })
          17. app.listen(80, () => {
          18. console.log('http://127.0.0.1');
          19. })

          創建jsonp.html客戶端來接收服務器端響應過來的回調函數,代碼如下:

          url中callback=fn為客戶端發送請求攜帶的參數 既服務器端中的req.query.callback

          
              
          1. <script>
          2. function fn(res) {
          3. console.log(res);
          4. }
          5. </script>
          6. <script src="http://127.0.0.1/jsonp?callback=fn"></script>




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

          分享此文一切功德,皆悉回向給文章原作者及眾讀者.

          轉自:csdn
          免責聲明:藍藍設計尊重原作者,文章的版權歸原作者。如涉及版權問題,請及時與我們取得聯系,我們立即更正或刪除。

          藍藍設計www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務

          日歷

          鏈接

          個人資料

          藍藍設計的小編 http://www.syprn.cn

          存檔

          亚洲va欧美va天堂v国产综合