前言
跨域問題來源于JavaScript的同源策略,即只有 協議+主機名+端口號(如存在)相同,則允許相互訪問。也就是說JavaScript只能訪問和操作自己域下的資源,不能訪問和操作其他域下的資源,主要是安全問題。
在很多時候跨域問題我都是讓后端解決,嘿嘿。但也有需要自己解決的項目!
首先在項目的根目錄下建一個vue.config.js
如下:
//改變webpack的設置
const { default: Axios } = require("axios")
module.exports = {
publicPath :"./",
devServer: {
// 設置主機地址
// host: 'xxx.1xx.1xx.xxx',
// // 設置默認端口
// port: 8051,
// 設置代理
proxy: {
'/api': {
// 目標 API 地址
target: 'http://xxx.xxx.xxx.xxx:8051',//服務器地址
// 如果要代理 websockets
ws: true,
// 將主機標頭的原點更改為目標URL
changeOrigin: false
}
}
},
chainWebpack: config => {//沒有用到scss的這里就不需要啦!
const oneOfsMap = config.module.rule('scss').oneOfs.store
oneOfsMap.forEach(item => {
item
.use('sass-resources-loader')
.loader('sass-resources-loader')
.options({
// 要公用的scss的路徑
resources: './src/assets/base.scss'
})
.end()
})
}
}
轉自:csdn 論壇 作者:可 樂 伢
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
因為學習的時候用的版本比較新,而網上的教程又全是老版本,所以出現了很多問題,總結以下,幫同樣初學的師傅們踩坑了。
廢話不多說:
1:
file->new->project新建一個普通java項目:
工程名可以隨意命名
2:
工程名上右鍵->Add Framework Support:
在Web Application上打勾,點擊OK
3:
展開工程名->web->WEB-INF,在WEB-INF下新建兩個文件夾,分別是classes、lib:
4:
按下ctrl+alt+shift+S,調出Project Structure,
選到Modules->Paths,單選框選到use module xxxxx,將兩個路徑改為剛才創建的classes。
然后選到Dependencies,點擊下面的+號,選擇jars or dirxxxxxxxx,選擇剛創建的lib目錄,讓選擇目錄用處的話,選擇jar direxxxxxxx,打上勾,點擊apply,OK
5:
將tomcat/lib目錄下的servlet-api.jar復制到我們創建的lib目錄里。
6:
點擊右上角小錘子旁邊的Add Configuration,點擊加號,選擇tomcat server->local。這里注意不要選成tomEE的,兩者圖標一樣,但是不是一個東西。其他配置不變,點擊aplly上面的fix,application context可以隨意命名,建議一個/就可以。然后aplly,OK。
7:
改一改index.jsp中帶的title和end,運行一下,如果類似以下,那基本就OK了。
8:
在src里面新建一個java class,嘗試寫一個servlet:
這里也是與其他版本不同的地方,老版本都是import javax.servlet.xxxxx,這里是import jakarta.servlet.xxxxx,具體應該import的包,可以展開servlet-api.jar看到。
import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @WebServlet(name = "login") public class Login extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<!DOCTYPE HTML>"); out.println("<HTML>"); out.println(" <HEAD><TITLE>login</TITLE></HEAD>"); out.println(" <BODY>"); out.print(" this is login page"); out.print(this.getClass()); out.println(" </BODY>"); out.println("</HTML>"); out.flush(); out.close(); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<!DOCTYPE HTML>"); out.println("<HTML>"); out.println(" <HEAD><TITLE>login</TITLE></HEAD>"); out.println(" <BODY>"); out.print(" this is login page"); out.print(this.getClass()); out.println(" </BODY>"); out.println("</HTML>"); out.flush(); out.close(); } }
然后修改web.xml文件,如下:
servlet-name可以任意命名,只要上下兩個一致就可以,servlet-class應該與類名相同,url-pattern是與java class中的@WebServlet(name=“xxxx”)的xxxx相同,這里的xxxx就是路徑。
此時編譯并運行,在地址欄輸入我們寫的url,就可以訪問到動態資源了:
全篇結束,只是記錄踩坑,希望能對大家有幫助。
轉自:csdn 論壇 作者:Hausa_
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
中新網客戶端北京4月16日電(記者 李金磊)16日,中國一季度經濟數據出爐,中國經濟取得開門紅,GDP、消費、投資、出口等主要指標呈現兩位數的增長。同時,就業物價等民生指標總體穩定,豬肉價格出現“報復性”下降。
一季度GDP同比大增18.3%
國家統計局數據顯示,初步核算,一季度國內生產總值249310億元,按可比價格計算,同比增長18.3%。
18.3%,兩位數增速,這個數字非常漂亮,在外界看來,這可謂是“報復性”增長。
不過要看到,增速的大幅反彈,主要是受到上年較低基數、員工就地過年工作日有所增加等不可比因素影響。
受到疫情的影響,2020年一季度GDP出現了負增長,同比下降6.8%。此后,中國經濟在全球主要經濟體中率先恢復正增長,2020年全年增長2.3%。
數據顯示,2021年一季度GDP比2020年四季度環比增長0.6%;比2019年一季度增長10.3%,兩年平均增長5.0%,這表明我國經濟穩定恢復。
主要經濟指標取得兩位數增速
從消費、投資、出口等主要經濟指標來看,同比均取得了兩位數的增幅。
具體數據顯示,一季度,社會消費品零售總額105221億元,同比增長33.9%;全國固定資產投資(不含農戶)95994億元,同比增長25.6%;貨物進出口總額84687億元,同比增長29.2%。出口46140億元,同比增長38.7%;進口38547億元,同比增長19.3%。
從季度環比看,主要指標繼續保持增長,一季度規模以上工業增加值比上年四季度環比增長2.01%,社會消費品零售總額環比增長1.86%,固定資產投資環比增長2.06%。
從兩年平均的增速看,一季度國內生產總值兩年平均增長5%,規模以上工業增加值兩年平均增長6.8%,社會消費品零售總額兩年平均增長4.2%,固定資產投資兩年平均增長2.9%,貨物進出口總額兩年平均增速也接近10%。
“所以,綜合這些指標來判斷,可以說,總體經濟處于穩定恢復的狀態中?!眹医y計局新聞發言人劉愛華16日在新聞發布會上說。
再來看收入、就業、物價等民生指標,總體上是收入漲、失業率降、物價持平的態勢。
——居民收入繼續增加
數據顯示,一季度,全國居民人均可支配收入9730元,同比名義增長13.7%,兩年平均名義增長7.0%;扣除價格因素同比實際增長13.7%,兩年平均增長4.5%。
按常住地分,城鎮居民人均可支配收入13120元,同比名義增長12.2%,實際增長12.3%;農村居民人均可支配收入5398元,同比名義增長16.3%,實際增長16.3%。全國居民人均可支配收入中位數8014元,增長12.7%。
企業效益的改善為居民收入增加奠定了基礎。在企業利潤方面,1-2月份,規模以上工業企業利潤總額同比增長1.79倍,兩年平均增長31.2%;規模以上服務業企業扭虧為盈,實現利潤總額達到了1690億元,上年同期是虧損的。
——城鎮調查失業率下降
就業是民生之本。一季度,全國城鎮新增就業297萬人,完成了全年預定目標任務的27%。
3月份,全國城鎮調查失業率為5.3%,比2月份下降0.2個百分點,比上年同期下降0.6個百分點。
不過,劉愛華提醒,3月份16-24歲年輕人的調查失業率是13.6%,比上年同期上升,說明年輕人就業還面臨一定的困難。這可能和春節節后大量年輕人進入勞動力市場,帶來摩擦性的失業有關系,一定程度上可能也反映了就業市場在趨于活躍。但年輕人就業問題的解決還需要一段時間的消化,這方面總量的壓力確實是存在的。
——豬肉價格大幅下降
從物價看,一季度居民消費價格同比持平,其中3月份由上月的下降0.2%轉為上漲0.4%,漲勢比較溫和。
近日多地豬肉價格重新回到了十幾元的時代。劉愛華稱,在一系列保供穩價的措施作用下,生豬產能得到了顯著恢復。今年一季度,生豬存欄同比增長了29.5%,連續六個季度環比增加。在生豬產能恢復的作用下,個別地區豬肉價格回落比較多,從全國居民消費價格來看,3月份當月豬肉價格同比下降18.4%,環比也是下降的。綜合生產、供應改善的情況來看,豬肉價格進一步回落是有基礎的。
劉愛華稱,另外一方面,糧食價格最近也比較穩定。今年以來糧食生產形勢比較好,冬小麥苗情是略好于往年水平的,從這方面來講,糧食安全也是有保障的。所以,不管是從豬肉價格還是從糧食價格來看,CPI上漲的壓力不大。(完)
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
圖標是 UI 設計中最基礎也是很重要的部分,輔助人們更好的理解功能內容。隨著扁平化設計風格的普及,圖標的風格越來越簡約,看似簡單的圖形,實際要準確的表達含義,也是需要注意一些方法的。以下是圖標設計技巧的分享內容:
設計圖標是一個藝術創作的過程,里面也有很多需要被關注而不可忽視技巧。要知道如何設計好圖標,是對于 UI 設計師來說是不可或缺的重要技能。
在我設計圖標的時候,我個人認為有以下7個規則:
一個圖標一個非寫實的表現。不需要擔心圖標不夠真實,消除不必要的細節,用基本的形狀只保留最基礎的部分,讓這個圖標更容易被理解。
有時候圖標會因為有更多細節而傳達了更復雜的意思,這反而是樣式問題!
在整個圖標系統中,你的圖標要保持同一種樣式來確保圖標完美協調。比如同樣的形狀,填充,描邊粗細,尺寸等。要制定好可以被復用的柵格,規范和樣式。
如果可以的話,盡可能重新設計這些圖標,而不要混入其他不同風格的圖標來使用。
設計「完美像素」的圖標,特別是在圖標非常小的時候。這樣圖標的描邊就可以保持銳利,不會有模糊。注意半像素的情況出現,盡量避免小數點參數。
這也可以幫你保持圖標的辨識度,在你等比縮放他們的時候保持清晰。
確保你的圖標的所有形狀有足夠的空間。筆畫和空間過于狹小會使圖標更難被理解。
最少給2px的負空間
確保你的圖標看起來是正確的,適當的調整元素的對齊來達到視覺上的平衡。
不要只關注參數,如果有需要就用上你的眼睛來衡量,輕微移動這些元素。
所有圖標保持同樣的尺寸,在圖標周圍定義一個可調整的內邊距范圍,盡量讓元素設計在這個范圍內。不要擠滿所有元素。
當圖標需要額外控件時可以超出這個內邊距范圍。
在設計階段,你的圖標可能看起來是完美的,但還是需要將圖標放到實際的界面環境中,測試他們是不是完美,有沒有可以調整的細節問題。
確保每個新增的圖標和其他圖標顯示一致。
你在設計圖標過程中,有用到以上的這些技巧嗎?可以在評論區告訴我,你是怎么怎么設計圖標的。
文章來源:優設網 作者:布萊恩臣
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
一起深度用案例解析B端導航設計中的交互
hello各位在B端奮斗的小伙伴們,你是否會時常因為面對導航多種多樣的形式從而面對需求時無從下手,你又是否因為雖然見過了很多的案例仍然不得導航設計的要領和精髓,沒關系,今天我們就一起來解決這個在B端設計中困擾我們多時的難題,從交互的角度結合案例對導航進行一個立體的剖析
如果你準備好了那么就請系上安全帶現在就發車
要探討一個概念那么首先需要知道的是其精準的定義,才能展開研究,而所謂的導航(Navigation)的精準定義可以闡述為:是一種對信息的分類,幫助用戶找到想要的信息、完成預期的任務
如果你覺得這個定義很抽象,那么不妨從這個角度去理解,如果說任何界面上的功能都能夠找到在我們物理世界的隱喻的話,那么導航映射的就是我們物理世界中的路牌、導覽、線路示意圖等,因為立足于其功能而言,導航的作用用一種大白話的說法就是:告訴用戶你從哪里來,你在哪里,你可以去哪里
由此我們對導航有了一個較為準確的把控,那么請在座的各位快速回答我一個問題,你能夠告訴我以上6個內容那些不是導航嗎?
3
2
1
OK公布答案,如果你的答案是2和6那么恭喜你,你對導航的理解是較為優秀的,2和6的名稱大家想必也不陌生那就是:菜單,但是不夸張的說日常的工作中仍舊有不小數目的一波同學搞不清楚這二者的區別,那么如何對二者進行一個有效的區分呢
同樣是從定義來入手,參照前面我們給導航進行的定義方式,菜單就是:是一種對動作的分類和集合,
幫助用戶快速達到某個功能,也就是說當你對菜單的某一個欄目進行點擊時會立馬生成一個具體的動作,而導航則是對信息的分類與合集
那么明白了這點我們就可以對導航進行分類了,提到導航的分類大家一定會脫口而出一堆詞匯如:頂部導航、底部導航、左側導航、舵式導航、標簽導航、菜單導航……沒錯這的確是一種分類,但他只是導航在外觀這個維度的分類,并不是我們今天從交互、結構層去討論的重點
而立足于結構來對導航進行分類又將是如何呢?較為科學的來說是以下幾類:
全局導航
局部導航
輔助導航
內嵌導航
友好導航
遠程導航
下面我們來對這6類導航進行一步一步的具體分析
所謂全局導航是指他可以覆蓋整個產品的通路,往往表現為產品的一級分類(而且大部分情況都是一級分類),他不一定包含全局信息,但是一定可以讓用戶可以去到其目標的關鍵節點
所謂局部導航是指在同一個框架中,可以到這個節點上的上下級通路,他一定存在于嚴格的父子級關系中
所謂輔助導航就是提供用戶在全局/局部導航不可達到相關內容的快捷途徑(這個快捷途徑在本產品內)
所謂內嵌導航也叫上下文導航,是指嵌入頁面自身內容的導航,通常同在上下文超鏈接、引導搜索等
所謂友好導航是指它可以為用戶提供一個便利的前進途徑,在需要的時候能夠找到入口信息,通常在不需要的時候成隱藏狀態
所謂遠程導航是指不包含在產品結構中,以獨立的方式存在產品內,通常表現為網站地圖、索引表(地址選擇、品牌選擇)等
在從結構的層面了解了導航的基本類型之后,順便給大家提一提導航的外觀,這里并不展開說,大家需要知道的是導航的外觀使用遵循的是“同構異型”的準則,什么意思呢?同樣的結構(比如同一組數據集:商品、商品名稱、商品價格)可以嵌套進入不同的外觀如:卡片式、列表、詳情……這個視具體的業務情況、使用場景而定
常用的導航外觀基本分為以上七種外觀即:菜單欄、樹狀表、頂欄、選項卡、面包屑、文字鏈接、步驟
知道了導航的結構分類和使用場景,那么不妨來給大家一些關于導航本身的小貼士作為原則參考解決大家在實戰中的一些問題
對于B端產品來說穩定相當重要!因為B端產品對于用戶來說使用和學習成本、門檻較大,如果你很頻繁地對其路徑進行修改調整,用戶就會因為產品不符合操作的習慣、心智模型對產品很容易滋生負面情緒,對于產品本身來說這樣的傷害是需要盡量避免的
還是從穩定的方面來說,我們需要保證的是導航的變化不會因為產品的變化而發生很大的變化,舉個很簡單的例子就是當我們的產品的功能增多時,尤其是二級導航的項目增多,導致原來如果是橫向布局的導航不得不改成縱向布局的導航,這就所謂的因為產品的變化發生很大的變化,所以在選擇導航布局的時候就需要打下一個很好的基礎便于日后的拓展
這是站在一個外觀和交互共同的層面去看,導航的大小一定要足夠,而且其位置一定要是用戶認為足夠清晰的,確保在視覺反饋的的層面對于用戶來說是友好的,其次就是所有的可交互區域需要有積極的響應,與內容區要有對比,可以將其稱為界面的熱情度,這也是一個優秀界面的自我修養
一個頁面中允許出現兩個主導航,同一個界面中允許出現兩個同樣的導航項,并不是說一個項在導航中只能夠出現一次,并沒有那么死板
這對于To B 的設計來說十分重要,不同于To C的產品,B端產品的一個重點就是要符合用戶的預期,所以我們一定要避免“因為有趣所以這設計”這個思路
界面上面所有的界面編排,所有的組件,所有的控件,所有的模式都是可以找到隱喻的,比如文字鏈和帶“跳轉”的文字鏈,它代表的隱喻是不一樣的,所以我們就需要賦予其不同的外觀和交互響應對應戶進行反饋
回到最初導航的定義,它的本質是對信息進行分類,讓用戶快速完成任務,這也是導航的本職工作,很多時候不一定要拘泥于這個項目它應該嚴格存在于哪個層級之中這樣的思路進行設計,而是根據用戶的需求,如何將這個項目合理的分類于最適合的集合之中
這是一個立足于外觀的點,根據大量的案例分析和眼動測試,目前市面上最為常見的按照信息權重布局的導航可分為:橫向式、縱向式、縱橫式,由于這部分我們不展開說,所以直接在上圖整理了每種布局的特征、優劣勢和應用場景
知道了上面的分類和注意事項之后,下面我們用一個具體案例來對導航的交互層面設計進行一個深度體驗(因為此內容十分精彩也涉及到機密,所以不在這里做具體展示,以示意的方式來敘述),總共分為六步,看看這是否也是你工作場景中比較頭疼的呢
需要搞清楚導航項的定義是因為導航項的定義決定了你的目標界面是什么,所謂的目標界面就是導航所引導你到的哪一個分類的信息處
所以我們首先先來整理一下導航中每個導航項的界面定義,這也是我們日常工作中對導航梳理十分重要的一步
當問題被羅列出來之后我們就會自然而然的產生各種各樣的疑問,比如導航分類之間存在有的存在流程上的關系,但是有的分類卻并不屬于流程,這是為什么呢?再比如有的導航分類和導航項之間名字一樣但內容卻不一樣這又是為什么呢……(想一想這是不是我們工作中也經常遇到的疑問呢)這都是后面我們需要去優化的地方
保留住上面的問題,我們來做第二步,這一步我們需要搞明白用戶的使用路徑,因為這樣我們可以很好的給任務類產品做一級分類
通過基于不同角色的用戶體驗地圖我們可以得出不同的用戶操作路徑,于是便可以很順暢的得出這一套操作流程的大框架
基于業務中的任務鏈路推導出每一步的操作路徑,于是我們就可以將用戶的操作路徑就可以提煉為一級導航
得出了一級導航,下面我需要角色的權限進行一下區分,這也是B端產品的必備屬性
于是我們為每一個導航項進行了角色權限的梳理對應,那么一級導航中每個導航分類所對應的角色也瞬間一目了然,這里面多說一句,當用戶用不同權限的賬號登錄產品時,能看到不同的內容這才是一個優秀的擁有權限設計的導航
到了這一部分對于一些完全沒有接觸過數據的同學來說理解起來可能會一些難度,我們首先需要知道的是:“相同的數據來源,可以幫我們區分界面性質,而且相同的數據來源,往往會有一組相同的界面來圍繞”
在此需要記住三個概念:
1.元數據:數據屬性的信息,用來支持如指示存儲位置、歷史數據、資源查找、文件記錄等功能,例如一件商品、一個客戶
2.記錄集:指定數據庫中檢索到的數據集合,例如訂單列表、發貨列表
3.關系列表:對來描述對象和對象的關系,比如你和我是好友,你和我在同一個企業微信群
于是我們為導航項進行數據性質的區分歸類,也就是說相同數據類型的實體往往圍繞著某個元數據并且包含系列的界面,當我們這里整理完后發現,相同數據性質的實體(這里可以理解為導航項)貌似可以歸類在一起,這是我們作為分類的一個依據
根據相同的數據性質將導航項歸入應該歸入的二級導航中,此時不妨和最初的版本進行對比,我們的一級二級導航相對而言已經通過改版清晰了很多
這一步其實是比較好理解的,很簡單的法則:“高頻次高優展示,低頻次降低權重甚至隱藏”這是針對于二級導航中每個導航項的排布進行的設計。這里不妨把頻次由高到低量化成為:實時關注、每天關注、每月關注、很少使用、極少使用這個幾個概念,分別用五角星、三角形、矩形、圓形、菱形進行代表
而關于使用頻次的高低甄別一般我們可以通過用戶調研和數據埋點的兩種常用方式來進行,這里并不展開講
于是我們可以將使用頻次作為一列新的參考放入導航項的表格中,瞬間清晰明了
根據使用頻次調整每個導航項的順序
這一步涉及的就是外觀了,不妨回顧一下2.8中對于導航的三種常見布局,根據產品的操作復雜程度等綜合需求,我們選擇了第二種形式成為最終形式
文章來源:站酷 作者:核糖bro
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
做中后臺產品的設計,基本都逃不開導航布局這個大框架。
基于用戶的 Z 字形掃描行為,重要的導航應當選擇左側導航或頂部導航。
可是橫著豎著有那么大差別嗎?被人問道為什么這么選擇,該如何回答?
今天給大家些靈感,從以下四個角度分析一下:
JR Kingsburg 曾經做過一次實驗(A comparison of three-level menu navigation structures for web design),研究 3 層導航中,哪種組合使用效率更高。
這三層中,每一層都有橫向和縱向兩種可能性,所以實驗總共有 2×2×2=8 種對照組:
他為這 8 種導航布局做了不同電商原型,讓用戶來買東西,并記錄各種數據,結果發現了很多有意思的數據:
綜合這些數據,看起來整體表現較好都是「左上上」、「左左上」、「左左左」。
科學雖然很嚴謹,卻缺乏靈活度,例如本次試驗的場景單一(電商購物),而且用來測試的界面未免也太簡陋了吧!
所以我們再從其他角度思考看看。
從占據面積的角度來看,橫向導航比縱向導航省地方,因為只要細細一條就好了。
然而,選項數量不多時橫向是可以;選項多起來,橫向導航就很擁擠了。
畢竟縱向導航方便滾動,橫向導航很少有用戶會嘗試滾動查看的,「…」也不是什么方便的操作。
所以,如果確定選項少可以選橫向,不確定或者數量多建議保險起見選縱向。
任何導航,都要占據屏幕不少空間,這對尺寸適配都是一件麻煩事。哪怕產品并不需要為移動端做響應式布局,只要是網頁端,就得考慮窗口尺寸的變化問題。因為設計師的 Mac 和大量用戶的 PC 甚至平板電腦之間,展示上的差異真的不小。
橫向導航占據空間最小,同時也是最難做尺寸適配的。尤其是如果上面除了導航之外,還放有各種 logo、頭像、圖標、搜索…各種東西時。橫向導航一般都有三種狀態:展開、折疊和收起。但是縱向導航就簡單了,只需要兩個狀態:展開和收起。頂多再讓展開狀態的寬度能夠自適應變化或手動拉伸就差不多了。
這么看來,如果產品需要考慮很多不同尺寸適配的問題,縱向導航是最簡單的選擇,除非橫向導航的內容不多維護起來不麻煩。
我之前為了研究確定按鈕放在左邊還是放在右邊好,做了一系列實驗分析,結果得出超出我預期的結論…放哪都沒多大問題,統一就好。于是,我想這個問題也可以類比一下。
大部分網站都是橫向導航,所以說如果產品是以網頁版為主,且用戶會經常穿插跳轉使用其它網頁,那么也使用橫向導航比較符合習慣。
而無論 PC 還是 Mac,系統頁面的導航在左側的情況比較多,所以說如果產品是系統軟件的話,縱向導航比較符合習慣。
然而,更更更更更重要的是,千萬不要同一個產品不同端或不同子系統的導航不一樣!用戶很可能一會兒用這個,一會兒用那個,結果操作習慣換來換去,人都弄暈啦!還有,就是改版換導航肯定要讓老用戶不滿,好不容易養成習慣改起來容易嗎?所以說,決定導航布局時還是要謹慎才好哦。
文章來源:優設 作者:體驗進階
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
前言
在企業工作中,每一個問卷調研都始于一個商業問題,問卷的質量也決定了最終結果是否能對業務起到幫助。本文將從定義問題-問卷設計-數據清洗與分析-報告撰寫這四個基本步驟相對完整地闡述企業問卷調研,希望可以給大家提供一些研究方法上的思路。
定義問題:情境分析法(SCQA)
在商業問題解決的過程中,既有公司內部的因素,也有外部行業的因素,影響因素錯綜復雜;周圍的環境也比較容易發生變化,具有很大的不確定性;同時又要保證解決方法的可落地性,產生實際的價值。相對來說,會比較復雜。在進行問卷設計之前,更有必要的是將問題梳理清楚,再決定是否采用問卷這種方式。
1.1 結構化思考:使用SCQA描述項目
SCQA是將不確定性考慮在內,一種結構化的問題分析方法,可以比較好地系統思考、查漏補缺。它包含四個環節:
情境(Situation):由大家都熟悉的現狀或事實作為起點,包含對象、所處階段等
沖突(Complication):實際情況往往和我們的目標有沖突,顛覆了穩定的狀態。說出行動的原因,包含威脅、機會和等著我們去克服的困難點
問題(Question):基于沖突提出問題,要怎么解決這個困難點
回答(Answer):我們的解決方案是什么,定位出需求點
1.2 如何洞悉情境和沖突:搞清楚為什么做調研
假設我們拿到上述案例作為調研項目,可以有兩種方式去進行洞悉情境和沖突:
一是思考為什么要做這個研究;二是跟相關利益者訪談盡可能多地獲取信息。
1)思考為什么要做這個研究:
- 需要回答什么問題?
- 為什么回答這些問題很重要?
- 打算如何使用最終的調研結果?
2)跟相關利益者訪談:
- 核心業務方是誰?其他業務方是?
- 每個業務方的關注點是什么?難點是什么?
- 各個相關方的目標之間是否沖突,是什么沖突?
根據上述方法,可以得到對應的情境和沖突:
情境:目前有三種產品方案A/B/C,分別對應的價格為100元/1000元/10000元。通過上述思考和信息了解,會知道這個事情和誰有關,在這個事件中承擔什么角色。
沖突:B的銷量不佳,跟其他方案差異不明顯,瞄準客群很有可能有重疊,未成交客戶難轉化,希望可以方案B進行調整。在用戶層,可能其他方案中的功能能滿足需求,不需要購買方案B;在公司層,整體收入結構可以更優化、健康;在業務層,系統和流程可能不太合理,有些可能需要重構。
1.3 問題拆解其實是建立一個假說/邏輯樹的過程
我們可以將問題進行拆解,拆解應遵循MECE原則(相互獨立且完全窮盡),這么做的好處是可以把問題進行逐層分解,逐級分析,最大可能保證需要考慮的因素全面不遺漏。
案例中的問題,可以從用戶方面、競品方面、成本/利潤方面進行拆解,針對每一個層面的問題又可以進行拆分。
對問題進行細致拆分之后,針對每個問題有不同的解決方案,有一些問題可以用問卷來解決,有一些問題需要使用其他方式進行解答。
問卷并不能解答所有問題~~
問卷設計
2.1 問卷的用途:定量為主
一般通過問卷來進行大樣本的數據收集,主要以用戶的基礎數據、行為數據和態度數據為主,既可以作為獨立的調研項目,可以跟其他方式進行結合,比如說結合訪談、結合企業內部的數據,本文比較推薦的方式是多種方式結合進行交叉驗證,提升調研結果的可靠性。
2.2 問卷設計的原則
基于第一部分的定義問題階段,已經對問題進行了分析,在此基礎之上,我們需要確定哪些問題可以由問卷進行解答,并明確問卷的研究目標與參與對象。特別地:利益相關方(項目組成員間)在項目前期應該達成統一,避免后續產生分歧,付出額外的溝通成本不說,還有可能相互甩鍋。
2.3 問卷的基本結構
一份問卷的基本結構包含標題、招募語、甄別題、主問卷、用戶基本特征、結束語。
2.4有邏輯的設計問題
一份有效的問卷需要從如何提問、如何措辭、如何設置答題邏輯、如何設置題目選項這些方面去考慮,設置有效的問題。以下是問卷設計中的一些基本原則:
2.5 提升回復率的tips
個性化:在說明信件/郵件或郵件開頭注明回復者的名字、研究活動的目的、所需時間。向回復者強調他們反饋信息的重要性。需要注意的是,這里出現信息錯誤,會降低回復率。
控制篇幅:問卷完成時間不要超過10分鐘,注意控制問題數量,避免出現需要大量思考、較難回復的題型。
用戶激勵:獎勵參與者油卡/現金紅包/優惠券等,昂貴的激勵物沒有特別顯著提高回復率,所以小的激勵就可以。
數據清洗與分析
3.1 數據清洗原則
剔除有效范圍外的數據:排除異常作答時間值(比如作答時間為10秒),判斷為作答不認真??梢愿鶕}項來確定,一般10道題設置篩選出60秒之內的問卷。
剔除連續重復值:在時間范圍內,再核查問卷是否出現連續重復值,出現的問卷予以刪除。如果問卷數量較大,可以使用STATA軟件編碼或Excel條件函數判斷進行處理。
剔除違背邏輯一致性的數據:在時間范圍內,核查問卷是否存在前后邏輯不一致的題,比如總體滿意度打分為非常滿意,但后續題目都選擇了非常不滿意。
剔除有缺失值的數據:嚴格來說應該將有缺失值的用戶予以刪除,但有時候回收樣本量沒有那么大,則可保留。
3.2 數據分析方法
數據分析方法有非常多,要在眾多的分析方法中選擇一種也是比較難的事,無論選擇什么樣高大上的方法都是其次,最重要的是選擇的分析方法能說明問題,能體現數據的價值。
比較分析是一個簡單的、比較通用的、易于理解的數據分析方法,可以分成趨勢分析、特征重要性、分組分析三種。
報告撰寫
最后,條理清晰地展現數據信息,表達你的觀點。報告寫作的過程是一個相對費勁的過程,特別是數據量多的情況下,總是覺得還有一些數據價值沒有被挖掘出來,但此時不要拘泥細節,細節可以回頭再補,會大大提升效率。
4.1 問卷的報告框架
報告主要發現:將總結放在最前面,閱讀者可以通過簡短的總結大致了解報告觀點,方便他們決定是否需要繼續了解詳細內容
目錄和分目錄:報告包含的內容組成部分,讓閱讀者對報告內容有初步概覽
調研背景和目的:陳述整個報告的背景和目的,對調研的范圍進行必要說明
單頁-詳細內容描述:有邏輯的描述項目的發現,總結數據表現,挖掘價值
單頁-詳細內容描述示例:
問卷調研不止是問卷本身,還包括前期項目組溝通、項目成員分工與配合、后續結果推廣、結果推動落地等,前期做好項目組溝通、明確項目分工,建立一個清晰的運行機制,有利于項目組成員對結果的認同,后續也有清晰的路徑去分工解決問題。所以,每一個環節都體現工作的價值,都同樣重要。希望大家在關注研究方法提升的同時,也可以更多關注更多工作方法提升。
文章來源:站酷 作者:酷家樂UED
藍藍設計( www.syprn.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務
function _getValue(target, valuePath, defalutVal) {
let valueType = Object.prototype.toString.call(target)
console.log(valueType)
// if (valueType == "[object Array]") {
let paths = valuePath.replace(/\[(\d+)\]/, `.$1`).split('.')
let result = target
for(const path of paths){
result = Object(result)[path]
if(result == undefined){
return defalutVal
}
}
return result
}
測試:
let obj = {
a:{
b:[
{
c:2
}
]
}
}
console.log(_getValue(obj, 'a.b[0].c')) //2
function isEqual(res1, res2) {
let a = getTypeOf(res1)
let b = getTypeOf(res2)
if(a !== b){
return false
}else if(a === 'base'){
console.log('base',res1,res2)
return res1 === res2
} else if(a === 'array'){
if(res1.length !== res2.length){
console.log('array',res1,res2)
return false
}else{
//遍歷數組的值比較
for(let i =0;i<res1.length;i++){
if(!isEqual(res1[i],res2[i])){
console.log('array',res1[i],res2[i])
return false
}
}
return true
}
return true
}else if(a === 'object'){
let ak = Object.keys(a)
let bk = Object.keys(b)
if(ak.length !== bk.length){
return false
}else{
for(let o in res1){
console.log(res1[o])
if(!isEqual(res1[o],res2[o])){
console.log('object',res1[o],res2[o])
return false
}
}
return true
}
}else if(a === 'null' || a === 'undefined'){
console.log('null')
return true
}else if(a === 'function'){
console.log('function')
return a === b
}
}
function getTypeOf(res) {
let type = Object.prototype.toString.call(res)
switch (type) {
case "[object Array]":
return 'array'
case "[object Object]":
return 'object'
case "[object Null]":
return 'null'
case "[object Undefined]":
return 'undefined'
case "[object Number]"||"[object String]"||"[object Boolean]":
return 'base'
case "[object Function]":
return 'function'
default:
return 'typeError'
}
}
測試:
let a = {
a:20,
b:{
c:30,
d:[1,2,3]
}
}
let b = {
a:20,
b:{
c:30,
d:[1,2,3]
}
}
console.log(isEqual(a,b)) //true
function _flat(arr){
let result = []
for(let i = 0;i<arr.length;i++){
if(Array.isArray(arr[i])){
result = result.concat(_flat(arr[i]))
}else{
result.push(arr[i])
}
}
return result;
}
let arr = [1,2,[3,4,[5,6]]]
_flat(arr) //[1,2,3,4,5,6]
//es6
function _flat2(arr){
while(arr.some(item=>Array.isArray(item))){
arr = [].concat(...arr)
}
return arr
}
let arr = [1,2,[3,4,[5,6]]]
_flat2(arr) //[1,2,3,4,5,6]
簡單深克隆,不考慮內置對象和函數
function deepClone(obj){
if(typeof obj !== 'object') return
let newObj = obj instanceof Array?[]:{}
for(let key in obj){
if(obj.hasOwnProperty(key)){
newObj[key] = typeof obj[key] === 'object'?deepClone(obj[key]):obj[key]
}
}
return newObj
}
復雜版深度克隆 考慮內置對象 比如date regexp 函數 以及對象的循環引用的問題
const isObject = (target) => typeof target === "object"&& target !== null;
function deepClone2(target, map = new WeakMap()) {
console.log(target)
if (map.get(target)) {
return target;
}
// 獲取當前值的構造函數:獲取它的類型
let constructor = target.constructor;
// 檢測當前對象target是否與正則、日期格式對象匹配
if (/^(RegExp|Date)$/i.test(constructor.name)) {
// 創建一個新的特殊對象(正則類/日期類)的實例
return new constructor(target);
}
if (isObject(target)) {
map.set(target, true); // 為循環引用的對象做標記
const cloneTarget = Array.isArray(target) ? [] : {};
for (let prop in target) {
if (target.hasOwnProperty(prop)) {
cloneTarget[prop] = deepClone(target[prop], map);
}
}
return cloneTarget;
} else {
return target;
}
}
filter去重
function _unique(arr){
return arr.filter((item,index,array)=>{
return array.indexOf(item) === index
})
}
es6 Set
function _unique2(arr){
return [...new Set(arr)]
}
includes
function _unique3(arr){
let newArr = []
arr.forEach(item => {
if(!newArr.includes(item)){
newArr.push(item)
}
});
return newArr
}
雙層for循環
function _unique4(arr){
for(let i =0;i<arr.length;i++){
for(let j =i+1;j<arr.length;j++){
if(arr[i] === arr[j]){
arr.splice(j,1)
j--
}
}
}
return arr
}
indexof
function _unique5(arr){
let newArr = []
for(let i = 0;i<arr.length;i++){
if(newArr.indexOf(arr[i] === -1){
newArr.push(arr[i])
})
}
return newArr
}
function _typeOf(obj){
let res = Object.prototype.toString.call(obj).split(' ')[1]
let mold = res.substring(0,res.length-1).toLowerCase()
return mold
}
_typeOf(5) //number
_typeOf('5') //string
function getParamsObj(params){
let paramsStr = params.replace(/^.+\?(.+)/,"$1")
let paramsArr = paramsStr.split('&')
let paramsObj = {}
for(let [key,value] of paramsArr.entries()){
if(/=/.test(value)){
let valArr = value.split('=')
val = decodeURIComponent(valArr[1]) //解碼
val = /^\d+$/.test(val)?parseFloat(val):val //判斷是不是數字
if(paramsObj.hasOwnProperty(valArr[0])){
paramsObj[valArr[0]] = [].concat(paramsObj[valArr[0]],val)
}else{
paramsObj[valArr[0]] = val
}
}
}
return paramsObj
}
//從一次傳入多個參數 編程多次調用每次傳入一個參數
function add(a, b, c, d, e) {
return a + b + c + d + e
}
function curry(fn) {
let dFn = (...args)=>{
if(args.length == fn.length) return fn(...args)
return (...arg)=>{
return dFn(...args,...arg)
}
}
return dFn
}
let addCurry = curry(add)
addCurry(1,2,3)(2)(3)
//添加了兩個功能
// 圖片加載完成后 移除事件監聽
// 加載完的圖片從imgList中移除
let imgList = [...document.querySelectorAll('img')]
let length = imgList.length
const imgLazyLoad = function () {
let count = 0
let deleteIndexList = []
imgList.forEach((img, index) => {
let rect = img.getBoundingClientRect()
//獲取元素到視圖的距離 top元素上邊到視圖上邊的距離 left元素左邊到視圖左邊的距離 right... bottom...
if (rect.top < window.innerHeight) {
// img.src = img.dataset.src
img.src = img.getAttribute('data-src')
deleteIndexList.push(index)
count++
if (count === length) {
document.removeEventListener('scroll', imgLazyLoad)
}
}
})
imgList = imgList.filter((img, index) => !deleteIndexList.includes(index))
}
imgLazyLoad()
document.addEventListener('scroll', imgLazyLoad)
圖片懶加載:https://juejin.cn/post/6844903856489365518#heading-19
函數防抖 觸發高頻事件 事件在n后執行,如果n秒鐘重復執行了 則時間重置
//簡易版
function debounce(func,wait){
let timer;
return function(){
let context = this;
let args = arguments;
console.log(timer)
clearTimeout(timer)
timer = setTimeout(function(){
func.apply(context,args)
},wait)
}
}
let btn = document.querySelector('button');
function aa(){
console.log(111)
}
btn.onclick = debounce(aa,2000)
// 復雜版
// 1.取消防抖
// 2.立即執行功能(點擊之后立即執行函數 但是 wait時間之后在點擊才能在立即執行)
// 3.函數可能有返回值
function debounce(func,wait,immediate){
let timer,result;
const debounce = function () {
const context = this
const args = arguments
if(timer) clearTimeout(timer)
if(immediate){
console.log(timer)
var callNow = !timer
timer = setTimeout(function () {
timer =null
},wait)
if(callNow) result = func.apply(context,args)
}else{
timer = setTimeout(function (params) {
result = func.apply(context,args)
},wait)
}
return result
}
debounce.cance = function () {
clearTimeout(timer)
timer=null
}
return debounce
}
let btn = document.querySelector('button');
function aa(){
console.log(111)
}
btn.onclick = debounce(aa,2000,true)```
函數節流 觸發高頻事件 且n秒只執行一次
//使用時間戳
function throttle(func,wait) {
var context,args;
var previous = 0
return function () {
context = this;
args = arguments;
let nowDate = +new Date()
if(nowDate-previous>wait){
func.apply(context,arguments)
previous = nowDate
}
}
}
//定時器
function throttle(func,wait) {
var context,args;
var timer;
return function(){
context = this;
args = arguments;
if(!timer){
timer = setTimeout(function () {
timer = null;
func.apply(context,args)
},wait)
}
}
}
//組合版 options.leading 為true 立即執行一次 options.trailing為true 結束之后執行一次 默認為true function throttle(func, wait ,options = {}) { var context, args, timer,result; var previous = 0; var later = function () { previous = options.leading === false ? 0 : new Date().getTime(); timer = null; func.apply(context, args) if (!timer) context = args = null; } var throttle = function () { var now = new Date().getTime() if (!previous && options.leading === false) previous = now; context = this; args = arguments; //下次觸發 func 剩余的時間 var remaining = wait - (now - previous); if (remaining <= 0 || remaining > wait) { // if (timer) { // clearTimeout(timer); // timer = null; // } previous = now; func.apply(context, args); if (!timer) context = args = null; } else if (!timer&& options.trailing !== false) { timer = setTimeout(later, remaining); } } throttled.cancel = function() { clearTimeout(timer); previous = 0; timer = null; } return throttle } function aa(e) { console.log(111) console.log(e) } let btn = document.querySelector('button'); btn.onclick = throttle(aa, 2000,{ leading:false, trailing:true
})
轉自:csdn論壇 作者:Selfimpr歐
移動互聯網的迅速崛起,讓移動網頁,移動客戶端越來越重要,客戶端的頁面設計也是一門很大的學問。科技迅速發展的今手機屏幕的尺寸越來越放大化,但卻始終 很有限,因此,在APP的界面設計中,精簡是一貫的準則。這里所說的精簡并不是內容上盡可能的少量,而是要注重重點的表達。在視覺上也要遵循用戶的視覺邏 輯,用戶看著順眼了,才會真正的喜歡。
接下來為大家分享精美的app UI設計案例:
icon的設計會貫穿全套設計稿,所以在設計的環節中必不可少,優質的icon設計會幫助品牌和企業更好的樹立形象,形成自己的設計語言。
接下來為大家分享一些經典案例:
--手機appUI設計--
--icon圖標賞析--
更多精彩文章:
藍藍設計的小編 http://www.syprn.cn