调查问卷,是一个低成本快速收集资料的定量分析工具。这是个看起来简单,产出的问卷也看似很简单,但是在整体设计的过程却是需要很多的思考和预备。
关于调查问卷,会分成三个部分来解说,
废话不说,直接开干!
1. 为什么做问卷
这个是问卷的目的,也直接影响后面问题的设计。
2. 如何使用问卷的研究结果
这是关于问卷解决方案的落地。不需要太过细致的落地计划,但是至少要清楚,这份问卷的研究成果,可以获得多少支持力度。不管问卷发现了多么伟大的问题,如果没有落地,其实是没有无意义。也切忌不要今年做的研究结果,明年来实施,那问卷的时效性和准确性就会大打折扣了,因为市场的瞬息万变。
这是做所有事前,都要问的问题,「为什么做 Why」。而这个问题为什么重要呢,因为这会关系到设计问卷的核心内容是什么,会影响问卷的构成,当然最后也会产出不同的结果。
问卷的目的主要可以分为六个方面
1. 收集用户信息
很多时候,我们或许知道理想目标用户是谁,但是谁才是真正使用我们产品的用户呢?了解真正使用的用户,可以对用户进行更针对性的分析和设计。
2. 了解用户使用习惯
了解用户在产品上是如何使用产品的,以及用户的使用路径是否按着我们期待的方式进行,这是很有必要,这也是一个验证的过程。
2. 满意度
了解用户对产品的满意程度,对于用户不满意的方面,可以进行归纳总结,并给出合理的解决方案
3. 建议反馈、吐槽、好评
从问卷中收集用户的心声,明白槽点是什么。同时也收集用户的好评,这也是激励团队一个很好的方法,因为是直接来自用户。
4. 体验优化
对一个成功的产品来说,它要好用,它也要好看。产品有大改版前,可以用问卷来评估整体产品的体验如何,以便在重新设计的方向上能更好聚焦。
5. 需求验证
很多时候,需求可能没那么明确,用户和产品间始终存在着 gap, 所以我们有时对方案琢磨不定时,可能会试运行,后续看用户反馈。通过合理设计问卷,我们也可以稍微窥探到用户的想法
但是对需求的验证,单通过问卷还是比较难的,只能窥探到比较浅的一层,最好后续可以对用户进行访谈来做后续跟踪,以便了解事情的全面。
这里要注意的是,问卷不适合探索用户的新的需求,或者要验证很精准的信息等比较复杂性的问题。
如果你问用户,近期会推出新功能,问他会不会用。大致上,你得到的回答都是肯定。很多时候,同意比拒绝更简单。
根据提问的方式,可以分为 「是什么」「怎么样」「怎么办」
1. 是什么
主要是用户信息、使用习惯等问题。
例如,年龄层、职业、使用产品目的、知道产品的渠道、使用频率、使用竞品软件、整体满意度等
2. 怎么样
主要是询问用户原因,比如打这个分数的原因,某功能使用如何等
3. 怎么办
主要是询问用户的建议、期待产品改进的地方
问卷中并不是所有问题都适合问,有一些比较敏感的问题需要去避免,以免激起用户的负面情绪
1. 敏感性问题
个人信息类的问题比较容易会有敏感信息存在,就像你问用户工资区间,和在问卷最后告知用户参与问卷都有奖品,需要填写收货地址。很明显收货地址的准确性会比工资更高。
2. 措辞严谨
3. 问卷的顺序
先简单后复杂,并注意整体逻辑性的表达。循序渐进,如果一开头就是很难的问题,用户很容易放弃答题
4. 问题长度
尽量保持所有问题在一个差不多的长度呢,保持一样的节奏。避免时长时短
5. 避免专业词汇
很多时候,我们会用一些所谓的“行话”来表达,但是在问卷当中,无法保证用户同样是理解的,而且也会让用户产生距离感,非必要情况下,不要使用专业词汇
6. 选择题枚举要穷尽
题目数最好不多于 7 个,太多也会造成用户选择困难,最后记得加个其他并提供文本框输入
7. 避免互斥、重复、相似
问题避免前后矛盾,造成用户困扰,也不要重复或相似度极高的问题,除非这个问题是陷阱题,为了检验用户是否认真答题。但是在数量有限的问题中,一般比较少使用陷阱题
8. 保持开放性
为所有选择的选项,加入「其他——」「以上都不是」「不知道」,用户可能会觉得问题或答案不匹配,而不知道选什么,这时需要给用户一个出口,避免产生无效数据
9. 避免询问引导性的问题
大部分用户认为 XX 功能,很好用,你觉得呢?
如果看到这样问题,大概可以从中读出两个信息,1. 大家都觉得好用 2. 平台希望我说好用。
这个问题所传达出来的隐藏含义会引导用户做出不真实的反馈,这是没有意义的问题
10. 避免让用户选择「 是/否」「真/假」「好/坏」
强制选择非黑即白,大部分情况下没什么意思,因为用户可能不确定。这个问题本身也没有太大价值,也会错过用户一些比较有趣的回答。
所以如果这个问题的目的,是一定要知道的,可以更改提问的方式。
对于用户的问题,答案要可以量化表达,来产生数据,才便于后续数据的分析
11. 避免问用户将来的事,或回忆许久前的事
当人们将自己的行为投射到未来时,通常会过于简单化和理想化,人们更擅于解释当下进行的内容。
所以,如果要知道特定环境下用户的操作,则要配合合适的场景预设,并且是用户熟悉的场景。或者可以直接问,今天你会如何如何
所以可以通过询问今天的行为来,确定将来会不会使用。当然这不是绝对的,毕竟未来存在太多变数。
对于许久前的用户的操作行为,也尽量不询问,因为会忘记,而当强迫他去思考时,他可能自己脑补,产生不准确的记忆,进而对研究结果产生偏差。
12. 其他
问卷中存在多选题,必选题,选填题,记得预览问卷时,注意问题平台有无自动添加文字说明。
不要用 checkbox, radio 来区别多选和单选,这是不能准确的传达,也有可能用户没有注意到,或者就不清楚,而使用文字的表述会更清晰,不会产生歧义。
必选题,选填题,如果问卷平台,也只是用*号来表达必选时,建议在文字上也加上这样的说明
整体问卷的过程需要时间,所以也需要的具体的日程安排,以便整体问卷的进行是井然有序。
日程安排中,要包括:
调查问卷从准备到产出报告,需要一个过程,建议与其他设计师或 PD 来一起配搭工作,更高效的完成,一个人去做,总是会有一些盲点,并且会比较大的压力。
如果你在问卷方面是新手,也建议找个有经验的设计师或 PD 来做你顾问,减少一些不必要的坑。
文章来源:优设网 作者:箴盐设计
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务
JS学习笔记
js和java的异同点
变量声明
函数声明
js中的变量提升和函数提升
为什么有变量提升
总结
js和java的异同点
首先,js的语法和kottlin的语法有些相似。比如var,方法声明用
function 方法名称 (参数名称...){
//方法内部逻辑
}
还有变量类型声明 :
数据类型 : 变量名=值
区别:一:js的数据类型和java类似。只不过js中的数据类型number将java中的int,double,float整合了。
二:js中可以不用声明变量类型。变量不声明数据类型的话,那么他的类型取决于当前的值是什么数据类型。举例:
var num=0;
num-"lyyyyyyyyyyyyyy";
num=[];
num={};
三:js中的类型判断:
判断基本类型,返回一个字符串
1
console.log(typeof '');//string
console.log(typeof []);//object
console.log(typeof {});//object
console.log(typeof 1);//number
console.log(typeof null);//object
console.log(typeof undefined);//undefined
console.log(typeof true);//boolean
console.log(typeof function(){});//function
console.log(typeof /\d/);//object
检查某个对象属于哪个构造函数,返回true/false
1
function A(){};
function B(){};
let a = new A();
console.log(a instanceof A);
console.log(a instanceof B);
console.log([] instanceof Array);//true
console.log({} instanceof Object);//true
console.log(/\d/ instanceof RegExp);//true
console.log(function(){} instanceof Object);//true
console.log(function(){} instanceof Function);//true
变量声明
js的变量声明其实大体上可以分为三种:var声明、let与const声明和函数声明。
函数声明
doSomething();
function doSomething() {
console.log('doSomething');
}
var foodoSomething= 2;
你觉得上面会输出什么?TypeError吗?其实输出的结果是foo。这就引出了我们的问题了,当函数声明与其他声明一起出现的时候,是以谁为准呢?答案就是,函数声明高于一切,毕竟函数是js的第一公民。
那么,下面的例子呢?
doSomething();
function doSomething() {
console.log('1');
}
function doSomething() {
console.log('2');
}
当出现多个函数声明,那怎么办呢?以上代码输出结果为2。
因为有多个函数声明的时候,是由最后面的函数声明来替代前面的。
domeSomething();
var domeSomething= function() {
console.log('domeSomething');
}
var domeSomething = function() {}这种格式我们叫做函数表达式。
它其实也是分为两部分,一部分是var foo,而一部分是foo = function() {},参照例2,我们可以知道,这道题的结果应该是报了TypeError(因为foo声明但未赋值,因此foo是undefined)。
js中的变量提升和函数提升
在js中对变量进行操作后打印值经常会出现undefined的现象。其实原因是因为js中有一个叫做变量提升的功能。举例:
1
var data="lyyyyy";
getData();
function getData(){
//第一次打印
console.log("data值为: ", data);
var data="yyyyyyy";
//第二次打印
console.log("data值为: ", data);
}
打印的值第一个为undefined,而第二个打印的值为yyyyy.
原因:
在执行getData()方法的时候会在函数内部首先将变量的声明提升到第一步。
然后再声明函数内部的函数(如果函数内部有函数的话)。
之后才会按照方法内部的逻辑先后顺序执行代码。前两步只是声明!!!
看到这里应该就已经知道为什么会有上面那样的结果了。
实际的方法内部代码执行顺序应该是这样的:
function getData(){
//一。声明变量
var data;
//二。声明函数(如果函数内部有函数的话)
//三。按照代码的顺序执行
console.log("data值为: ", data);
data="yyyyyyy";
//第二次打印
console.log("data值为: ", data);
}
看到拆分后的代码执行顺序对结果也就不迷茫了。
为什么有变量提升
那么为什么会出现变量提升这个现象呢?
其实js和其他语言一样,都要经历编译和执行阶段。而js在编译阶段的时候,会搜集所有的变量声明并且提前声明变量,而其他的语句都不会改变他们的顺序,因此,在编译阶段的时候,第一步就已经执行了,而第二步则是在执行阶段执行到该语句的时候才执行。
总结
1.js会将变量的声明提升到js顶部执行,因此对于这种语句:var a = 2;其实上js会将其分为var a;和a = 2;两部分,并且将var a这一步提升到顶部执行。
2.变量提升的本质其实是由于js引擎在编译的时候,就将所有的变量声明了,因此在执行的时候,所有的变量都已经完成声明。
3.当有多个同名变量声明的时候,函数声明会覆盖其他的声明。如果有多个函数声明,则是由最后的一个函数声明覆盖之前所有的声明。
————————————————
版权声明:本文为CSDN博主qq_45272690的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务
5分钟带你了解服务设计的原则、案例及常用方法!
我们常说,现在是体验至上的时代,用户对产品的使用不再是单纯的需求满足,更要获得满意的体验。服务设计的发展为我们改善用户的体验提供了新的思路,从本质出发,任何产品都是在提供某种服务,服务的质量从根本上决定了用户的体验。
什么是服务设计
服务设计一直在我们的生活中,我们无时无刻不在体验着各式各样的服务。荷兰一家专业的服务设计机构31 Volts是这样描述服务设计的:“如果有两家紧挨着的咖啡店,出售同样价格的咖啡时,服务设计是让你走进其中一家而不是另一家的原因。”这个描述很生动,同时也说明了服务设计的作用。
其实服务设计的定义还有很多,行业内不同的专家和学者都有自己的理解和解读,不管定义如何,重要的是服务设计的思维方式,可以帮助我们从全局改善服务体验。
服务设计的原则及案例说明
2010年在《This is Service Design Thinking》一书中,作者首次提出了5个服务设计基本原则,这些原则之后也被广泛使用,但随着服务设计的不断发展,其中的一些原则也需要重新去审视和思考,因此在2017年作者将其更新修订为6项。
a.以人为中心(Human-centered)
以人为中心的设计理念在产品设计、交互设计等领域已经得到了广泛的应用,服务设计当然也没有例外,以人为中心就是要站在用户的角度上看待和思考问题,考虑所有被服务影响的人。
在日本,农产品市场存在这样一个问题,农产品批发商无法及时从种植者处了解农产品的相关状况、收获量等信息,因此他们也就无法与要购买农产品的人进行谈判,这样造成的结果可能是粮食的浪费。日本的一家软件公司NJC(Nippon Jimuki Co. Ltd.)发现了这一问题,他们希望利用自身能力(软件方面的优势)去解决这一问题,因此将目标设定为:创建一个可以提供有用数据而又不给农民或农产品批发商带来负担的系统。
最终的产出的结果是Fudoloop这个应用程序,通过Fudoloop,批发商可以提前一天从农民那里收到信息,进而协调买家的各种要求。Fudoloop的使用者分为两种,一种是需要更新农产品信息的农民,一种是从Fudoloop上获取农产品信息的批发商,Fudoloop分别为两种用户进行了设计。
图片来源:Fudoloop
在设计Fudoloop时存在这样一个问题,农产品市场中的相关从业人员普遍年龄较大、受教育程度低、软件使用经验很少,面对这样的用户,显然通常的软件设计并不符合他们的需求,因此Fudoloop的界面设计非常简单且信息突出,从事农产品相关工作的人员可以轻松的使用Fudoloop完成农产品信息的更新,而不会因为学习产生很大的压力。Fudoloop还在大型农业贸易展览会邀请了一些行业内的人员和用户参与到了产品的体验中,并收集了他们反馈的建议,以改善产品。
图片来源:IDEO
NJC在设计Fudoloop时充分坚持了以人为中心的原则,考虑到服务涉及的不同用户,并根据用户本身的特点和需求进行设计。NJC的CMO佐藤贤一是这样评价Fudoloop的:“当简单、以人为本的思想汇聚在一起时,创新就会发生”。
b.协作(Collaborative)
这条原则说的是,不同背景和职能的利益相关者应该参与到服务设计流程中,收集多方诉求,发现不同看待问题的角度,才会更好的解决问题。
在美国旧金山,有一所学校和Revolution Foods这家餐饮公司合作,为学校内的人员提供丰富的、营养的午餐,但是实际来餐厅就餐的人数与预期相差很大,数据显示,有72%可以承担起午餐费用的人并没有来到食堂吃午餐。经过调查发现其中的原因,很多学生等校内人员并不愿意排长队或者匆忙的吃完午餐,因此他们选择了去校外享受午餐的时间。
为了改善这种情况,这所学校请来了全球顶尖的设计咨询公司IDEO,他们与1300多名学生、父母、营养人员、董事会专员、校长、老师和社区团体等利益相关者一起工作,重新去设计了学校的午餐,并且制定了针对三种年龄的就餐体验的建议,完成了饮食、就餐空间、新技术使用等多方面的优化和设计。
图片来源:IDEO
最终,学校完美的改善了午餐服务的体验,这其中包含了所有利益相关者的想法和工作,因此设计成果也被人们所接受,越来越多的校内人员会选择学校的午餐,之后,这种设计模式也被旧金山的许多学校采纳和推出。
所以,服务中涉及到的利益相关者有很多,多收集他们的想法与建议,甚至让他们参与到服务设计中去,问题会得到更好的解决。
c.迭代(Iterative)
迭代是一个不断接受反馈不断优化的过程,如此重复执行,让产品变得越来越好。服务设计也需要迭代,不要避免犯错误,而是从错误中学习和改变,同时也要不断的收集各方的反馈信息,这些信息是服务进行迭代的核心所在。随着互联网的发展,迭代的思维早已渗透到每一个互联网产品,此处就不再过多解释。
d.有序(Sequential)
服务设计应该是一系列相互关联的活动,并且是按照顺序进行的,精准的把控服务每一个环节的节奏,用户才能获得更愉悦的体验。
以外卖为例,用户的使用过程包含订外卖时的商家选择到下单过程,下单后配送外卖,用户收到外卖和用餐后这几个过程,而服务的提供者主要包括商家、平台和外卖小哥,为了保证用户能够获得流畅的服务体验,需要各个服务提供者在服务展开的不同环节推出优质的服务,如下图。
在订外卖时,平台会为用户推出“超值优惠”“限时秒杀”等优惠活动,商家推荐、订单历史等商家选择渠道,以及不同的筛选条件,以上的目的都在于帮助用户快速找到自己期望的、合适的商家。在用户选定商家后,进入到选择商品并下单的过程,一方面,商家会推出优惠的活动、推荐菜品等,另一方面,平台也会给出自己的优惠。
下单后,用户面临的是一个配送过程中的等待时间,为了缓解用户在等待过程中的焦虑情绪,平台会及时更新和推送外卖小哥的状态,如到达商家、取餐中、与用户的距离等,同时会给出用户预期的送达时间,若超过预期时间用户还可进行催单,商家可以联系用户表达歉意,整个过程用户对配送状态是可视的。
用户收到外卖时首先会与外卖小哥接触,包括与外卖小哥提前确定取餐的时间地点,取外卖时的短暂对话等,这些都会影响用户对服务的印象,因此外卖小哥需要保证服务态度的礼貌和友好。收到外卖后,食品包装首先给到了用户对商家的第一印象,然后是餐品是否符合用户预期,让用户满意。
在用户就餐后,首先平台要提供给用户评价的功能,用户可以分享自己就餐的感受,商家也可以通过平台为用户提供更多的优惠,引导用户能够再次回到商家订餐。
从外卖的案例中我们可以看到,服务是一个过程,是需要有序展开的,每一个环节的体验都会影响到用户对服务的印象,在恰当的环节提供恰当的优质服务,才能确保用户的整体体验。
e.真实(Real)
服务本质上是无形的,应该用“物理元素”来可视化,这样可以用户的服务记忆,增强用户对他们所接受服务的感知。
同样以上述外卖为例,商家为用户提供餐食,这部分是借助美团这个平台和外卖小哥来完成的,用户和商家的接触仅仅是送达的餐食,因此无法通过像到店体验一样,让用户感知到商家提供的更多服务。
为了让服务变得更加“有形化”,商家就需要花费更多的心思,如图,商家为了增强用户对服务的感知,一般会在在包装上花费很多功夫,精致的包装让商家的形象更好且更加值得信任,一些有趣的包装还可能让用户的心情变得愉悦。另外,商家也可以通过一张便利贴的温馨问候或者赠送小礼品等方式让用户更真实的感受到服务,通过这样的手段,即使用户并没有真的接触到商家,体验也会变得很好,商家的形象也会提升很多。
图片来源:古田路9号
f.整体(Holistic)
整体就是要着眼于整个用户旅程,考虑用户与服务的每个触点(触点的概念后文会进行介绍),并兼顾多方利益相关者的需求。也就是所谓的全方位服务体验,考虑服务环境的方方面面,没有任何遗漏。这个原则实施起来并不是那么简单,从整体角度思考问题会使问题变得复杂。不过在服务设计中,是有一些方法和工具是可以帮助我们完成整体思考的,比如服务蓝图。
服务设计的常用方法-服务蓝图
a.服务蓝图简介
服务蓝图是一张图表,通过列出在每个阶段发生的、不同角色执行的所有活动,显示了服务的整个过程。如图所示是一个服务蓝图的简单示例,垂直方向上展示服务中的利益相关者,水平方向上为用户的历程,也就是用户经历的不同阶段。在服务蓝图中有两条线,一条是可见线(line of visibility),可见线上方为用户可与之交互的服务,也可以称之为“前台”,可见线下方代表的是后台进程,用户无法看到但需要给用户提供支持,后台进程还可以存在内部交互线,用来表示内部人员的联系。用户与前台服务之间存在另外一条交互线(line of interaction),用来表示用户与服务之间的接触。
图片来源:Service Design Tools
明确了服务蓝图的大致框架之后,还需要注意服务蓝图中一个非常重要的概念——触点。触点就是在服务的各阶段,用户和产品、服务、后台产生的接触,每个触点也是服务可以进行展开和优化的方向。
b.Uber服务蓝图绘制
为了明确服务蓝图的绘制和分析过程,下面将结合下图所示的Uber服务蓝图进行说明。
图片来源:Medium
(1) 明确用户历程
用户使用Uber打车服务主要可以简单分为以下三个阶段:注册(下载APP - 新用户注册),乘车阶段(下单 - 等待车辆到达 - 乘车 - 到达目的地)、乘车后(付款 - 评价)。
(2) 明确利益相关者
用户与之产生互动的前台服务人员为司机,而设计师、开发人员、项目经理等负责后台的服务支持,以保证Uber按照预期的目标运作。
(3) 明确前后台活动
一方面,需要明确和用户接触的前台活动有哪些,Uber打车服务中和用户产生接触的主要为司机及车辆,因此需要确保司机是合格的、车辆内部的环境是干净舒适的,同时司机在与用户接触的过程中需要提供礼貌的问候和交流,满足用户在乘车过程中的要求,完成乘车费用的收取,提醒用户离开前带好随身物品,以及评价乘客等。
另一方面,用户对后台的流程可能并不了解,但需要明确哪些后台活动和支持会对用户产生影响。比如在用户下单时能够自动获取用户定位,告知用户预期的时间和价格,以及发送给用户司机的状态等。
在明确前后台活动时,我们可以以用户历程为线,分步骤进行分析,确保每个环节中涉及到的前后台活动没有被遗漏。
(4)明确关键触点
在服务蓝图中我们可以标注用户与服务的主要接触点,针对触点进行设计是提升服务体验的一个重要和有效的手段。
在Uber打车服务中还有一些需要注意的触点,一是等待时间,这包括用户发起乘车请求后、付款时以及评价司机时,等待时间是造成用户体验较差的一个原因,因此需要注意标注出这些触点,并想办法优化,在服务设计中需要注意相关环节的应尽量简单,减少用户的等待。另外需要注意的是会对体验影响较大的触点,如司机态度不友好、乘客下车时忘记带随身物品等,可能造成失败的服务体验的触点应该精心地去设计,避免这样的情况发生。
通过以上过程我们完成了Uber服务蓝图的绘制,从中可以获取到Uber打车服务的整体概貌及其相互关系。
///
结语
服务设计的思维能够帮助我们从全局的角度去审视和思考,发现更多改善服务的可能性,从而为用户提供更好的体验。因此对于产品和设计等相关人员来说,不能仅仅把目光放在产品本身,而是要从服务的角度去正确看待产品和用户的关系,以用户为中心,找到用户与产品的每一个接触点来进行服务设计,这样才能保证用户在整个流程中都能得到好的体验。
文章来源:站酷 作者:百度MEUX
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务
用户体验设计就像是一场直面自我的修行,无论是从认知提升、工作能力等维度,都在时间和实践中不断去促进自我对事物的探索,在过程中不断获取对世界的感知和成就感。在学校里所接触的关于交互设计的认知,大部分局限于产品领域与基础交互,而后逐渐过渡到交互体验与设计的结合并且作用于商业,成长过程中也会不断思考,这次想聊聊设计价值,大概分为三点:价值思维、价值判断、价值体现。
我的设计能够给用户/产品产生什么价值?如何体现设计的价值?可能很多朋友也会和我一样有这样的疑惑,假如能够在接触需求后便思考该需求背后的价值,那对应的行动也会有很大差异性。
可能对于大部分的设计师而言,作为主要的执行力,需要肩负起项目的责任,所以会把大部分时间都投身在项目需求和日常沟通来提升自身能力,很少有剩余时间去沉淀已做完的设计,只有在产品体验会或者其他渠道的反馈中获取最后的问题,久而久之就像是打补丁,既无法体现设计价值,自身能力也无法得到完整的提高。然而促使设计师进步的往往不是技能的熟练,而是对业务需求思考的广度和深度。因此需要树立起价值的概念,价值可以驱使行动产生改变。
价值观因人而异,而价值观会影响一个人的行为引导其做出选择,对价值的思考取决于思维上升空间有多大。因此需要有一个思维模型能够帮助我们更好的建立起价值思维,可以帮到我们更加有逻辑的思考。相信许多朋友都听过「Why-How-What」即黄金圈法则,个人认为可以从日常需求中帮助设计师建立起一套价值思维。黄金圈解析:
△ 图片来自网上
了解黄金法则后,我们看看如何把黄金圈的思维模型运用到工作中。
假设我们接到一个「商城系统」的设计需求,可以尝试这样拆分:
WHY:我为什么做
关注点:站在产品角度,对产品真正的帮助和提升
HOW:我要怎么做:
关注点:需求做的更好,超出玩家预期
WHAT:需要做什么
关注点:让玩家使用更加高效,满足多种场景
综上所述,设计师处于不同的阶段,所关注的价值层面对应的行动也会不同,不仅要求设计师在需求之外还需要全局思维的思考延伸,了解当前产品阶段最需要的是什么,更多需要设计师自我审视,建立价值思维的思考模型,不仅仅停留在行动层的思考。
(我为什么要做)价值观——(我要怎么做)能力——(我要做什么)行动
「黄金圈」法则可以帮助我们建立起价值思维,然而每个设计师有各自的价值衡量,以下是我认为的一些价值维度:
1. 层次与目标
日常我们总会接受到大大小小的需求,简单和复杂会掺杂混合,从工作角度而言需求是都要做的,但是从设计价值的角度而言,需求是有轻重缓急之分。那如何进行价值判断呢,一般的设计需求从目标上可分为三个层次:
2. 二八法则分配
当有了一个基础划分后,就可以对需求进行合理评估,考虑到现实情况下通常会面临这些情况:
时间紧迫:日常需要大量的时间进行协作沟通和跟进
精力有限:任务重加班多,无法长时间保持高效的工作状态
所以可尝试根据二八法则对时间精力进行分配,对于一些价值较低的需求,可以和需求方充分沟通,过滤无效信息后快速处理;对于价值较高的需求,投入大量时间与精力设计与打磨。对于初中级的设计师来说,满足「可用性」和「易用性」是仍需要多加锤炼的基础能力,对于高级以上的设计师来说,有了一定的经验下达成前两者较为容易,可以把更多的时间精力投入在「愉悦感」的设计上。
前面讲了价值与判断,但设计无论是赋能或者是驱动,还是需要明确最终目标是什么,我的理解是最终服务于产品解决问题。那如何体现设计价值就显得尤为重要,以下简单抛出两点:
1. 提升体验和口碑
虽然不能直接为产品带来实际收益,但是带来体验提升,而口碑的增长相当于为长线运营打下基础,也为后续进入的产品矩阵留下增长空间,例如最近大火的《天地劫》,相信后续的出品也会让玩家更加期待。
像这类的例子有许多,例如《王者荣耀》的公众号还有专门的 UI 迭代日记,即便是运营多年的产品仍然在不断的打磨和提升体验,为产品带来正面影响。
△ 图片来自王者荣耀公众号
2. 带来商业利润,促进社交、消费增长
这类体现通常是商业化/社交相关,《阴阳师》众所周知的抽卡系统和「画符咒」的交互方式也带来了大量的社交互动和用户增长,还有《Pokémon GO》捕捉宝可梦和「投掷精灵球」,促进了玩家大量的线下的互动场景,我认为这些都是设计价值的体现。
这些设计相对于大部分玩家是一种「隐形」的存在,不像角色、场景设计等容易被感知,对于设计的价值体现一定不只是给产品锦上添花,是能够通过对用户/玩家群体的理解去塑造和满足需求。
文章来源:优设 作者:阿泽与设计
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务
先看目录!
1.什么是流量分发
2.为什么要做流量分发
3.首页中流量分发的类型
4.流量转化模型
5.流量如何分配的
6.设计案例与流量分发
7.如何衡量流量的效果
相信大家对流量并不陌生,我们在运营的口中经常会听到这个词:流量。运营通过各种手段和策略吸引用户来接触、使用我们的产品,从而吸引到了许多的流量,流量越多机会也就越多,比如一家奶茶店门店选址要考虑的最关键因素就是人流量。
流量分发的本质其实就是用户需求分发,我们设计师的价值就在于如何让这些流量发挥出更大的价值,让流量价值和用户价值相匹配。流量就像是一片海,海水通过不同的分支流入大陆形成了江、河,如果没有这些分支,那么这些水永远无法被利用,发挥出它们的价值。流量分发我们最常见的方式有:搜索分发、算法分发、社交分发、人工分发、付费分发
举一个比较典型的例子:海底捞在进行流量转化之前,并不是单纯的在店门口给用户一排座位让用户去等待,因为这部分用户就像没有被分流的海水是死的,这时候的用户其实也有自己的目标,就是消磨时间,那么海底捞就提供了一系列服务让这部分用户活动起来,比如给零食、玩具、做指甲等等,于是这部分用户其实就相当于进入了就餐流程的分支,提前享受服务和餐厅提供的福利,除了提升用户体验以外,也消化了大部分的流量。试想一下如果一下来了许多客户,但你只有十几张椅子让用户等待,势必造成更多的损失。
流量是无序混乱的,只有到它应该去的地方,它才会有价值。产品与用户双方都需要有清晰的目标,产品提供解决方案和导流不同的场景,用户负责完成目标给业务带来价值。
流量分发最典型的就是电商产品,因为业务目标非常明确,就是实现gmv的提升,但同时其用户的需求场景也是相对来说很复杂的。那么一个好的流量分发策略,可以大大的减少用户完成目标的时间和精力,也让产品可以准确的掌握用户的需求流向。
流量不分发或者错误分发就会造成更多的消耗,什么意思呢?我们举个例子,譬如下方的模坑app首页,首页中虽然提供了搜索、分类和标签栏不同模块,但是核心的内容显示区域则只有一张预售产品的大图。我们知道用户类型非常多,这样的布局对于小白和第一次用此款产品的小白来说会十分迷茫,因为最显眼的内容中并没有他们想要获取的信息。我们不求满足所有用户,但至少需要覆盖大部分用户和核心用户,此外,这样的形式就像一个漏斗,只靠一个出口漏水,效率自然不高。
同时为了达到最大化,流量的分发并不是单向的,而是并行、串联的。比如你可以在通过搜索找到某件商品,参与活动、运营板块、商品分类、网红直播等等区域都可以发现这个商品,同理,你想要购买视频app的会员,不仅仅可以去个人中心,你还可以去详情。所以流量就像一个大网格,单纯的给漏斗戳几个洞还不够,甚至要把这些洞用很多根管子串起来。
流量分发可以帮助盘活新业务以及寻找新的价值,例如我们之前的电商产品在前期是以时间轴为核心的消化方式,商品以单品列表平铺的形式展示,在产品发展过程中形态会发生变化,单纯以这样的形态承载用户需求肯定是不够的,所以更多运营板块和推荐可以分担这部分“旧”流量。
我们在移动端的首页可以常看见的类型有:搜索、宫格型板块、信息流、banner、fab等。
搜索给有明确需求的用户提供了入口,同时在搜索这个显性场景中我们也可以细化出更多的场景给流量提供更有效的支持
例如搜索场景下除了热门搜索、搜素历史以外还可以提供不同的分类内容推荐。
逐渐走下神坛的banner,曾经可是在UI界叱咤风云,在当时由于他是首页占比一哥,很多产品在首页规划中都认为banner会承载大部分的流量,尤其是像淘宝等电商产品,banner不仅仅可以靠图片吸引用户,在做一些大促活动时候还可以变成氛围担当,和导航栏上下呼应。我们说首页是寸土寸金的,但是大家发现没有,banner的流量和他本身的价值可能不相匹配。也就是说虽然他面积很大,但是用户点击率相比于其他板块并没有什么优势,甚至还低。所以淘宝目前的首页已经看不到banner了,这个区域可以放下更多的运营区块和流量入口,当需要它的时候再配置起来就可以了。
这个板块除了业务分类的“金刚区”以外还有运营活动的配置区域,我们先来说以业务划来划分的流量入口,以这样的形式来分配流量是常规的手段,当然他也是有利弊的,有利的地方在于几乎每个业务板块雨露均沾,至少是在同一屏幕中呈现,还可以左右滑动切换更多。弊端的话就是层级深,并且用户浏览效率低不聚焦,对于那些泛浏览型的用户并不友好,因为你进入一个业务板块后发现内容自己 不感兴趣需要就需要再返回。所以这样的分流更适合深度使用产品的用户
那有没有另外一种形式可以分配流量给不同业务板块呢?当然是有的,比如tab标签,有了tab标签,泛浏览的型的用户会更喜欢,他们能更快的找到自己喜欢的内容,比如bilibili、腾讯视频的首页,这个当然也和产品目标有关,他们希望让用户看到更多的内容,让产品更扁平化。
那么你即想扁平又想让用户直观的看到业务板块分类怎么办呢,你可以这么做,就像大众点评一样上边是宫格,下面是tab标签
Fab和cta可以说是比较另类的存在了,几乎就是你想让用户去点,那你就放,所以这样的入口流量路径就比较单一,无法沉淀和升级流量,是短期目标的形态。fab的这样的悬浮入口会一直在首页显示,通常产品为了吸引用户会将其设计的比较吸引人,比如添加动效等,但是fab也会干扰用户正常浏览界面,所以一般可以用透明、伸缩的方式解决,不过伸缩要考虑用户实际操作,避免频繁的伸缩造成的更多干扰。
大部分产品对于泛浏览用户的匹配场景都是提供信息流,但是单纯的给信息流依然无法让用户深入沉淀,所以需要在信息流中穿插一些分流入口,譬如品牌、话题、活动、排行等,让用户有更深入的浏览,这样才能促成转化。
流量获取很容易,但是我们的目标并不是让用户进来逛一圈就走,所以流量的转化我把他以这样的模型展示,也就是说流量从获取到沉淀再到最后的进化过程。
获取新流量的方式很多,例如社交分发、线下活动引流等等,内部流量也可以通过打通多个板块进行流量互换。但是这些流量是表面的,不做进一步整合也就没有实际价值,所以我们需要将其沉淀下来。
流量就像过江之鲫,如果你想让这条江里有更多鱼,你首先需要有个兜来留住这些用户,为了不让这些鱼继续游走,你可以给更多丰富的食物、创造更好的环境。如何让鱼更好的在这里生存呢,要让他们熟悉你的一切,要让这些鱼在其中发展、繁衍,所以当我们用内容吸引住用户后,要让用户留下来成为深度用户,这个前提就是让用户更长时间的使用产品,如何提升产品使用时长呢?譬如通过智能算法在很多断流的板块提供偏好推荐、帮助用户预判场景、社交互动、让用户有成就感、积分体系、个人成长系统、个人品牌塑造等。
之前两步依然是在存量市场里盘流量,这是对的,从十四五国家发展规划来看,我们能看到一个关键的变化,就是从“速度”到“质量”的变化,如果你的流量已经完成沉淀,那么可以不着急找增量,而是找进化的方法。当然以下是我个人的一些思考,仅供参考。从浅层到深入,从深入到高效,从高效到创造,所以当你的流量已经比较成熟的时候,可能更多需要让这些用户再创造新的内容,他们可以利用你提供的产品创造自己的玩法,即便你不提供任何的帮助也可以形成生态,甚至还可以帮你引入增量市场。
譬如玩社群的都知道,引流简单,但是要维持社群的热度和培养超级粉丝是很难的,但是一旦你做到了,那么这些人就是帮你创造更多的价值,所以你需要一个庞大且智能的基建,还有更好的服务。
判断流量分配是否合理的标准不在于多和广,而在于核心价值与目标是否达成。譬如内容型电商(抖音、快手)和传统型电商(淘宝、京东),内容型电商的流量是依靠内容带动电商去转化,更多的是依靠内容的质量,而传统型电商依靠的是商品,那么在这两个产品中,前者的流量更多还是要流向内容而非商品。
再举个例子,在首页的板块中,我们默认流量从大到小是板块越靠上的越多,越靠下的越少是吗?也不是,板块的分配是需要结合用户需求的,比如你规划的板块视觉上很明显但是从数据上看流量很低,那么这个板块就是有问题的,或者板块不明显但流量很高,这些都不是正常表现。
所以流量分发之前就要确定好,分发的目的和希望达成的目标。是能够让新用户更快了解产品,还是让成熟用户在使用时更高效,或者大力宣传新业务等等,不是一股脑儿随大流的把蛋糕切成几块。
不知道有没有在做抖音的小伙伴,抖音的流量分发让很多人搞不明白,其实抖音属于一个强运营平台,当用户制作一个视频发布后,他的流量并不是全部来自于已经关注你的粉丝,一部分是通过判断你的视频内容和质量分发给相应标签、可能会喜欢的用户。但是快手和抖音不同,快手的社交分发策略更重,用户发布的视频,已经关注的粉丝分发到的比例会更高,这样用户的互动也会更强。
通过一些设计案例我们来看看设计在流量分发中起到的作用。
流量与曝光是有关系的,为了争取更多的曝光我们可以采用这样的方式进行设计,通常我们可以看到横向滚动结束后进入下一级界面需要点击更多,但点击的成本就高于滑动,所以在这里可以让用户直接通过滑动进入下一级界面,增加曝光。同时滑动是承接上一步手势操作,很连贯,相比点击的效率也会越高。
我们经常在用产品的时候能看到同一个界面可以从多个不同的入口进来,比如像小鹿茶app点击下单跳转到商品列表,也可以直接点击底部第二个tab切换过来。比如你可以在夜宵板块和品牌板块都能找到kfc,让一个区域的流量不仅仅从单独的方向流入,这样可以满足更多用户的场景需求。像淘宝的商品流量来自多个不同的层级
还有我们可以将更深层级的业务板块提到上一层级,提高子业务板块的点击率和曝光,譬如贝壳在下方的tab板块中除了信息流内容外还嵌入了精选、人气、热门三个分类。还有类似像德邦app这样的工具型首页其实版面利用率太低,本身产品功能不多其实不需要划分出这么多板块,让每个板块流量这么分散,可以直接在首页中加入查单号的功能,并且将寄件收件历史平铺在首页。
淘宝商品详情中会有店铺和店铺推荐内容,方便用户查看更多偏好商品,提高客单价。具有电商属性的社交产品在用户图文中可以添加商品链接、标签、话题等等。还有淘宝在首页的feed流中点击商品会进入另一个feed流,这里的商品又进行了算法权重的加持,会更加准确与多样,由于本身处于逛场景的用户,在这一步再次帮助用户进行准确选择,可以提高转化,当然了,这样中心化的分流方式对于商家而言不太友好。
衡量流量分发的效果,我们可以查看板块的点击率(UV/PV)和预期。比如在某个周期中,有100个人进入这个界面,而这个界面中的banner最终点击量为1000次,那么这个banner的点击率为1000/100=10,平均每人点击了10次。点击率越高,该入口的流量自然更大。
每个产品对于活跃的标准不同,比如一个商场衡量活跃用户数会算那些进来蹭空调的大伯大妈吗?还是衡量那些有消费行为的顾客,同理一个产品计算活跃不是单纯看每天有多少人登录浏览就算活跃的。
那么观察活跃度有什么用呢?比如我们之前做一个大促活动,每个板块都有活动,但是大促结束后,只有童装类板块的日活流量在持续下降,于是我们通过相关调研,发现是因为童装类的品类太少,用户没有逛和再次购买的兴趣。
一波流量进入后,我们不仅要看他们去了哪里,还要查看这波流量在这里做了什么,于是我们通过查看页面停留时长可以判断一些问题,比如
1. 如果用户在本该停留时长长的页面反而停留时间短可能是当前内容不感兴趣、看不懂、闪退、临时有事等等
2.反之,在本该停留时间短但是用户停留时间长,说明可能文案排版或者解释的不清楚、用户可能在思考、临时有事等等
一波流量进入后,可能进入更深级界面也可能停留原地,那么还有一部分可能就直接离开了,查看流量的流失可以帮助我们判断以下问题
1.如果用户在进行某个多步骤任务,当我们发现其在即将完成时退出了,或者在中间步骤退出了,那说明可能出现了某些问题让用户进行不下去
2.用户可能对当前流程没有预期,也可能觉得有风险也可能是对某个地方产生不满
流量就像是一群被标记过的小白鼠,从哪里来到哪里去,中间做了什么,都被我们记录了下来,那么页面访问路径也是我们查看这些流量去向的关键指标,例如cctalk在冷启动后默认打开发现页面,我们进行了一些用户的调研,发现90%以上的同学在进入后都会切换到上课这个界面,这里可以思考的是作为产品我们发现用户有这样的行为,需不需要对产品进行优化,产品这样的设计是否考虑到的是新用户和培养用户习惯让更多课程有曝光。其实这里可以做一些判断,如果用户近期有购课、上课的记录和行为,默认打开上课板块。若新用户或者长期没有上课行为的用户则默认打开发现界面。这样就可以起到更精准的分流。
8.总结
流量诚可贵,流失就白费。
今天分享就到这里,你学废了吗?
文章来源:站酷 作者:应骏
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务
文章目录
原文链接:https://blog.csdn.net/zy1281539626/article/details/114934551
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务
SpringBoot与Web开发(超详细)
一、简介
二、SpringBoot对静态资源的映射规则
1、所有 /webjars/ ,都去 classpath:/META-INF/resources/webjars/ 找资源
2、"/" 访问当前项目的任何资源,都去静态资源的文件夹找映射
3、欢迎页: 静态资源文件夹下的所有index.html页面,被"/"映射
三、模板引擎
1、引入Thymeleaf
2、Thymeleaf的使用
1、导入thymeleaf的名称空间
2、使用thymeleaf语法
3、Thymeleaf的语法规则
四、SpringMVC自动配置
1、Spring MVC auto-configuration
2、扩展SpringMVC
原理
3、全面接管SpringMVC
原理
五、如何修改SpringBoot的默认配置
一、简介
使用SpringBoot的步骤:
1、创建SpringBoot应用,选中我们需要的模块。
2、SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运行起来。
3、自己编写业务代码。
自动配置原理:
xxxxAutoConfiguration:帮我们给容器中自动配置组件
xxxxProperties:配置类来封装配置文件的内容
1
2
二、SpringBoot对静态资源的映射规则
@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties implements ResourceLoaderAware {
//可以设置和静态资源有关的参数,缓存时间等
1
2
3
WebMvcAuotConfiguration:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
Integer cachePeriod = this.resourceProperties.getCachePeriod();
if (!registry.hasMappingForPattern("/webjars/")) {
customizeResourceHandlerRegistration(
registry.addResourceHandler("/webjars/**")
.addResourceLocations(
"classpath:/META-INF/resources/webjars/")
.setCachePeriod(cachePeriod));
}
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
//静态资源文件夹映射
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(
registry.addResourceHandler(staticPathPattern)
.addResourceLocations(
this.resourceProperties.getStaticLocations())
.setCachePeriod(cachePeriod));
}
}
//配置欢迎页映射
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(
ResourceProperties resourceProperties) {
return new WelcomePageHandlerMapping(resourceProperties.getWelcomePage(),
this.mvcProperties.getStaticPathPattern());
}
//配置喜欢的图标
@Configuration
@ConditionalOnProperty(value = "spring.mvc.favicon.enabled", matchIfMissing = true)
public static class FaviconConfiguration {
private final ResourceProperties resourceProperties;
public FaviconConfiguration(ResourceProperties resourceProperties) {
this.resourceProperties = resourceProperties;
}
@Bean
public SimpleUrlHandlerMapping faviconHandlerMapping() {
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
//所有 /favicon.ico
mapping.setUrlMap(Collections.singletonMap("/favicon.ico",
faviconRequestHandler()));
return mapping;
}
@Bean
public ResourceHttpRequestHandler faviconRequestHandler() {
ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
requestHandler
.setLocations(this.resourceProperties.getFaviconLocations());
return requestHandler;
}
}
1、所有 /webjars/ ,都去 classpath:/META-INF/resources/webjars/ 找资源
webjars:以jar包的方式引入静态资源。WebJars
访问localhost:8080/webjars/jquery/3.3.1/jquery.js的结果:
2、"/" 访问当前项目的任何资源,都去静态资源的文件夹找映射
"classpath:/META-INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/"
"/":当前项目的根路径
例子:访问localhost:8080/abc 就是去静态资源文件夹里面找abc
例如我们访问js文件夹下的Chart.min.js:
访问结果:
3、欢迎页: 静态资源文件夹下的所有index.html页面,被"/"映射
编写index.html文件。
访问结果:
三、模板引擎
常见的模板引擎:JSP、Velocity、Freemarker、Thymeleaf(springboot推荐,语法更简单,功能更强大)
1、引入Thymeleaf
Thymeleaf官网
在pom.xml中添加以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2、Thymeleaf的使用
@ConfigurationProperties(prefix = "spring.thymeleaf")
public class ThymeleafProperties {
private static final Charset DEFAULT_ENCODING = Charset.forName("UTF-8");
private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf("text/html");
public static final String DEFAULT_PREFIX = "classpath:/templates/";
public static final String DEFAULT_SUFFIX = ".html";
1
只要我们把HTML页面放在classpath:/templates/,thymeleaf就能自动渲染。
success.html:
HelloController:
package com.keafmd.springboot.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/
Keafmd
@ClassName: HelloController
@Description:
@author: 牛哄哄的柯南
@date: 2021-03-04 19:54
*/
@Controller
public class HelloController {
@ResponseBody
@RequestMapping("/hello")
public String hello(){
return "Hello World";
}
@RequestMapping("/success")
public String success() {
return "success";
}
}
访问success的结果:
1、导入thymeleaf的名称空间
<html lang="en" xmlns:th="http://www.thymeleaf.org">
1
2、使用thymeleaf语法
HelloController:
package com.keafmd.springboot.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Map;
/*
Keafmd
@ClassName: HelloController
@Description:
@author: 牛哄哄的柯南
@date: 2021-03-04 19:54
/
@Controller
public class HelloController {
@ResponseBody
@RequestMapping("/hello")
public String hello(){
return "Hello World";
}
/*
查出一些数据在页面显示
@param map
@return
*/
@RequestMapping("/success")
public String success(Map<String,Object> map) {
map.put("hello","你好");
return "success";
}
}
success.html:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>成功</h1>
<!--th:text 将div里面的文本内容设置为-->
<div th:text="${hello}"></div>
</body>
</html>
运行结果:
3、Thymeleaf的语法规则
1、th:任意html属性,来替换原生属性的值
th:text — 改变当前元素里面的文本内容
更多参考下图:
2、表达式
Simple expressions:(表达式语法)
Variable Expressions: ${...}:获取变量值;OGNL;
1)、获取对象的属性、调用方法
2)、使用内置的基本对象:
#ctx : the context object.
#vars: the context variables.
#locale : the context locale.
#request : (only in Web Contexts) the HttpServletRequest object.
#response : (only in Web Contexts) the HttpServletResponse object.
#session : (only in Web Contexts) the HttpSession object.
#servletContext : (only in Web Contexts) the ServletContext object.
${session.foo}
3)、内置的一些工具对象:
Selection Variable Expressions: {...}:选择表达式:和${}在功能上是一样;
补充:配合 th:object="${session.user}:
<div th:object="${session.user}">
<p>Name: <span th:text="{firstName}">Sebastian</span>.</p>
<p>Surname: <span th:text="{lastName}">Pepper</span>.</p>
<p>Nationality: <span th:text="{nationality}">Saturn</span>.</p>
</div>
Message Expressions: #{...}:获取国际化内容
Link URL Expressions: @{...}:定义URL;
@{/order/process(execId=${execId},execType='FAST')}
Fragment Expressions: ~{...}:片段引用表达式
<div th:insert="~{commons :: main}">...</div>
Literals(字面量)
Text literals: 'one text' , 'Another one!' ,…
Number literals: 0 , 34 , 3.0 , 12.3 ,…
Boolean literals: true , false
Null literal: null
Literal tokens: one , sometext , main ,…
Text operations:(文本操作)
String concatenation: +
Literal substitutions: |The name is ${name}|
Arithmetic operations:(数学运算)
Binary operators: + , - , * , / , %
Minus sign (unary operator): -
Boolean operations:(布尔运算)
Binary operators: and , or
Boolean negation (unary operator): ! , not
Comparisons and equality:(比较运算)
Comparators: > , < , >= , <= ( gt , lt , ge , le )
Equality operators: == , != ( eq , ne )
Conditional operators:条件运算(三元运算符)
If-then: (if) ? (then)
If-then-else: (if) ? (then) : (else)
Default: (value) ?: (defaultvalue)
Special tokens:
No-Operation: _
注意:内容过多,详细内容参考官方文档。
示例:↓
HelloController:
package com.keafmd.springboot.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Arrays;
import java.util.Map;
/*
Keafmd
@ClassName: HelloController
@Description:
@author: 牛哄哄的柯南
@date: 2021-03-04 19:54
/
@Controller
public class HelloController {
@ResponseBody
@RequestMapping("/hello")
public String hello(){
return "Hello World";
}
/*
查出一些数据在页面显示
@param map
@return
*/
@RequestMapping("/success")
public String success(Map<String,Object> map) {
map.put("hello","你好");
map.put("hello1","<h1>你好</h1>");
map.put("users", Arrays.asList("柯南","小兰","基德"));
return "success";
}
}
success.html:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>成功</h1>
<!--th:text 将div里面的文本内容设置为-->
<div id="div01" class="myDiv" th:id="${hello}" th:class="${hello}" th:text="${hello}">这里的内容被覆盖</div>
<hr/>
<div th:text="${hello1}"></div>
<div th:utext="${hello1}"></div>
<hr/>
<!--th:each 每次遍历都会生成当前这个标签-->
<h4 th:text="${user}" th:each="user:${users}"></h4>
<hr/>
<h4>
<span th:each="user:${users}"> [[${user}]] </span>
</h4>
</body>
</html>
效果:
四、SpringMVC自动配置
1、Spring MVC auto-configuration
参考官方文档:点这里
Spring Boot 自动配置好了SpringMVC
以下是SpringBoot对SpringMVC的默认配置:(WebMvcAutoConfiguration)
Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
自动配置了ViewResolver(视图解析器:根据方法的返回值得到视图对象(View),视图对象决定如何渲染(转发?重定向?))
ContentNegotiatingViewResolver:组合所有的视图解析器的。
如何定制:我们可以自己给容器中添加一个视图解析器;自动的将其组合进来。
Support for serving static resources, including support for WebJars (see below).静态资源文件夹路径,webjars
Static index.html support. 静态首页访问
Custom Favicon support (see below). favicon.ico
自动注册了 of Converter, GenericConverter, Formatter beans.
Converter:转换器; public String hello(User user):类型转换使用Converter
Formatter :格式化器; 2017.12.17===Date
@Bean
@ConditionalOnProperty(prefix = "spring.mvc", name = "date-format")//在文件中配置日期格式化的规则
public Formatter<Date> dateFormatter() {
return new DateFormatter(this.mvcProperties.getDateFormat());//日期格式化组件
}
1
2
3
4
5
自己添加的格式化器转换器,我们只需要放在容器中即可
Support for HttpMessageConverters (see below).
HttpMessageConverter:SpringMVC用来转换Http请求和响应的;User—Json
HttpMessageConverters 是从容器中确定;获取所有的HttpMessageConverter
自己给容器中添加HttpMessageConverter,只需要将自己的组件注册容器中(@Bean,@Component)
Automatic registration of MessageCodesResolver (see below):定义错误代码生成规则
Automatic use of a ConfigurableWebBindingInitializer bean (see below).
我们可以配置一个ConfigurableWebBindingInitializer来替换默认的(添加到容器)
初始化WebDataBinder
请求数据=====JavaBean
1
2
org.springframework.boot.autoconfigure.web:web的所有自动场景
If you want to keep Spring Boot MVC features, and you just want to add additional MVC configuration (interceptors, formatters, view controllers etc.) you can add your own @Configuration class of type WebMvcConfigurerAdapter, but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter or ExceptionHandlerExceptionResolver you can declare a WebMvcRegistrationsAdapter instance providing such components.
如果你想保持Spring Boot MVC 功能,你只是想添加额外的(MVC配置)(https://docs.spring.io/spring/docs/4.3.14.RELEASE/spring-framework-reference/htmlsingle MVC)(拦截器,格式器,视图控制器等)您可以添加自己的@ configuration类WebMvcConfigurerAdapter类型,但没有@EnableWebMvc。如果你想提供RequestMappingHandlerMapping, RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver的自定义实例,你可以声明一个WebMvcRegistrationsAdapter实例来提供这样的组件。
If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.
如果你想完全控制Spring MVC,你可以添加你自己的@Configuration注解@EnableWebMvc。
2、扩展SpringMVC
实现如下功能:
<mvc:view-controller path="/hello" view-name="success"></mvc:view-controller>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/hello"/>
<bean></bean>
</mvc:interceptor>
</mvc:interceptors>
做法:编写一个配置类(@Configuration),是WebMvcConfigurerAdapter类型;不能标注@EnableWebMvc
特点:既保留了所有的自动配置,也能用我们扩展的配置。
在config包下创建个MyMvcConfig。
代码实现:
package com.keafmd.springboot.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/*
Keafmd
@ClassName: MyMvcConfig
@Description:
@author: 牛哄哄的柯南
@date: 2021-03-17 20:26
/
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//浏览器发送 /keafmd 请求 来到success页面
registry.addViewController("/keafmd").setViewName("success");
}
}
原理
1、WebMvcAutoConfiguration是SpringMVC的自动配置类。
2、在做其他自动配置时会导入,@Import(EnableWebMvcConfiguration.class)。
@Configuration
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration {
private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
//从容器中获取所有的WebMvcConfigurer
@Autowired(required = false)
public void setConfigurers(List<WebMvcConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addWebMvcConfigurers(configurers);
//一个参考实现;将所有的WebMvcConfigurer相关配置都来一起调用;
@Override
// public void addViewControllers(ViewControllerRegistry registry) {
// for (WebMvcConfigurer delegate : this.delegates) {
// delegate.addViewControllers(registry);
// }
}
}
}
3、容器中所有的WebMvcConfigurer都会一起起作用。
4、我们的配置类也会被调用。
效果:SpringMVC的自动配置和我们的扩展配置都会起作用。
3、全面接管SpringMVC
SpringBoot对SpringMVC的自动配置不需要了,所有都是我们自己配置,所有的SpringMVC的自动配置都失效了。
做法:我们需要在配置类中添加@EnableWebMvc即可。
@EnableWebMvc
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//浏览器发送 /keafmd 请求 来到success页面
registry.addViewController("/keafmd").setViewName("success");
}
}
全面接管后,静态资源失效。
不推荐这样全面接管。
原理
加了@EnableWebMvc自动配置就失效了。
1、@EnableWebMvc的核心:
@Import({DelegatingWebMvcConfiguration.class})
public @interface EnableWebMvc {
2、DelegatingWebMvcConfiguration
@Configuration(
proxyBeanMethods = false
)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
3、WebMvcAutoConfiguration
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnWebApplication(
type = Type.SERVLET
)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
//容器中没有这个组件的时候,这个自动配置类才生效
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration {
4、@EnableWebMvc将WebMvcConfigurationSupport组件导入进来,自动配置类失效了。
5、导入的WebMvcConfigurationSupport只是SpringMVC最基本的功能。
五、如何修改SpringBoot的默认配置
1、SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(@Bean、@Component)如果有就用用户配置的,如果没有,才自动配置;如果有些组件可以有多个(ViewResolver)将用户配置的和自己默认的组合起来。
2、在SpringBoot中会有非常多的xxxConfigurer帮助我们进行扩展配置。
3、在SpringBoot中会有很多的xxxCustomizer帮助我们进行定制配置。
以上就是SpringBoot与Web开发(超详细)篇一的全部内容。
————————————————
版权声明:本文为CSDN博主「牛哄哄的柯南」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43883917/article/details/114375472
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务
越来越多的产品引入会员系统,如何做好一个会员系统,是当下设计师需要解答的一个命题。
会员的本质是建立用户分层,便于形成用户的差异化营销,通过这种差异化的营销达到以下四种目的:
提高用户留存率(增加用户粘性);
提升用户价值;
得到会费收益;
建立流量桥梁;
目的:筛选出高价值用户(高留存+消费力强),精细化运营
手段:收会员费,建立用户层之间的壁垒
结果:用户自发分层,愿意掏钱的那批人成为会员用户
原则:给会员用户提供卓越的服务,给普通用户提供好用的服务(反例:某网盘限速机制,约等于强卖会员,严重伤害普通用户的使用体验)
价格优势:会员专享低价(电商产品有会员专享价、外卖产品有会员红包)
资源优势:增值内容(影视、音乐版权)
体验优势:更好的服务(更快响应、专属客服、无广告等)
心理优势:身份认同(尊贵感标识,与普通用户形成差异。对社交、游戏尤其关键)
短期价值:通过收取会员费,提高营收
长期价值:增加用户粘性、巩固并提升市场占比
体验角度:更好的服务、专属福利
心理层面:身份认同、沉没成本(已经花了会员费,越多使用越合算,不然就亏了)
UI界面设计环节,一般的会员体系会涉及到的界面、视觉元素有:
会员触点/前置曝光
会员中心
会员身份等级
所有将用户引导至会员中心页面的入口都可以算作会员触点,触点越多,用户被引入会员中心的可能性越大。但触点也不是越多越好,过多触点会引起用户反感,将触点置于合适位置,能更自然高效地提高转化率。
2.1.1 个人中心:露出会员板块,通常是视觉强调中心。
个人中心是曝光率较高的页面,其中整合了许多重要和必要功能入口。利用个人中心页面,可以很好增加会员信息的曝光。该方式也是最常见且最通用的触点形式,不局限于产品类型。
2.1.2 内容卡点:体验完免费部分之后,会员内容收费,触点卡于两者之间。
增加用户沉没成本:用户已经在早期投入大量时间和精力阅读免费内容;
利用用户好奇心:有前文做铺垫,用户行至卡点处,对剩余内容的好奇远超过一般内容;
需求明确(制造问题):用户开会员就是为了解决剩余内容无法观看这一具体问题,用户总是倾向于解决问题而不是在原有基础上提高要求。
2.1.3 会员专区:建立专享感,将会员内容与普通内容进行区隔。
将付费内容集中在一个区块内,制造差异化,不论是内容质量或者商品价位,本质都是让用户形成会员价值很高的感觉。
2.1.4 会员频道
常见于电商产品,同样是起到区分内容,建立壁垒的作用。
2.1.5 底部提示
使用较为轻量的底部提示,引导用户关注会员信息。该视觉样式还常被用作登录提醒。
2.1.6 小banner
见缝插针式的视觉提示,占用流量最大的首页空间,此时文案的利益刺激尤其重要。
2.1.7 会员专页
使用一个底部tab的权重来承载会员相关信息,可见会员体系的重要性。
会员中心是展示会员权益,以吸引用户开通会员的页面。是用户全面了解会员相关信息的窗口,氛围营造、权益展示、行动点突出,是设计会员中心需要考虑的要点。
2.2.1 会员中心的常见页面结构
不同产品有不同的会员中心布局,有差异性也有共性。
氛围感、套餐选择(多套餐情况)、行动点、会员权益,是多数会员中心页面共有的模块,模块之间位置并不固定。
本质上越重要的模块,应该被分配越醒目的视觉表达方式。通过调整位置、面积、视觉对比度等,都可以调整不同模块之间的权重,达到产品想要呈现的优先级效果。
2.2.2 会员中心_氛围感
打造氛围感的方式多样,常见的有以下几种方式:
2.2.3 会员中心_套餐选择
部分产品不存在套餐选择,只有一种套餐,如盒马。在用户体系中,将用户分为两层,用户会员与非用户会员。部分产品在会员中又进一步分类,推出了多种会员套餐。
常见套餐以时间区分,如包月会员、季度会员、包年会员、连续包年会员等。除此之外,也有以权限范围为区分,如百度网盘的会员VIP和超级会员SVIP,超级会员享受更多特权。还有垂类会员,如视频产品中单独开辟出体育分类,对应设立专门的体育VIP卡。
上方案例中的套餐选择均以卡片的样式展示,除了该种方式,还有可以以列表形式展示。
列表形式的好处在于,套餐在垂直方向铺开,延展性强,当套餐数量改变时,不会影响展示效率,而卡片式的展示形式会造成部分套餐被挤出屏幕,用户需要左右滑动才能浏览全部,交互成本略高。同时,卡片式套餐需要点击选中套餐,再点击行动点,才能触发支付,而列表式模型,直接点击对应套餐项上的按钮即可呼出支付,交互更加简洁。
多套餐模型下,产品往往会重点突出一到两项套餐,从商业层面讲,通常希望用户选择价格更高的套餐,从体验层面讲,将附加值最高的套餐用角标突出,辅助用户决策。
2.2.4 会员中心_行动点
行动点是一个页面中最醒目的元素,往往是由按钮充当。按钮的点击数据也可以直接反映页面的设计是否合理。对于会员中心页面来说,提升关键性按钮点击,往往是改版的目标和方向。
最常见的行动点布局方式有4种:
购买按钮常驻于底部工具栏
购买按钮紧邻套餐选择模块,位于页面中部
页面同时有多个购买按钮
界面始终存在一个购买按钮
符合一般操作习惯,关键行动点常驻于页面底部,已经被普遍接受。
购买按钮紧邻套餐选择模块,从操作的角度上来说,更加合理,套餐选择完毕之后,购买按钮含义类似“确定”,两个步骤紧密相关,符合格式塔的远近亲疏原则。同时,页面中心相比于页面底部更加容易视觉聚焦,用户能更加容易注意到。这也解释了,为什么居中的对话框常用于警示,需要引起用户高度关注,而底部半弹窗往往承载不那么关键的内容,一般承载无破坏性的操作。
购买按钮意味着支付入口,头部卡片上增加支付入口,不妨通过数据观察,测试不同位置的点击效果如何。
随着页面上划,界面中第一个行动点(页面中部)被推出视图,此时底部工具栏浮出,保证页面不管在何位置,始终可见至少一个行动点,让用户随时可以进行支付。
2.2.5 会员中心_权益
会员权益是决定用户是否购买会员的重要因素。有些权益相当实在,如会员折扣、专属红包等,而有些权益的诱惑力相对较弱,不同的权益强度决定了不同的视觉呈现方式。
会员权益细节介绍
会员权益从交互上,可分为两类,可点击和不可点击。不可点击的权益往往在会员中心页面是以宫格图标的形式呈现。而可点击的权益,往往内容详实,需要更多的空间来解释和说明权益的具体内容。
从视觉形式上,也可以分为两类:
弹窗呈现
子页面呈现
除了购买会员之外,部分产品引入了“身份等级”的概念来将用户进行分层。划分的维度可以是用户的活跃度、裂变能力等,可以依此,设计一系列的会员任务。会员身份等级机制利用了用户的攀比、自我实现等心理,进一步增加用户与产品之间的粘性。
会员身份等级一般集中在4-7个之间,其中梯度理论上呈递增趋势。作为设计师,需要将低等级到高等级这种“越来越高端”的氛围烘托出来。不同类型的产品有自己的特色和局限,金融类产品在整体视觉属性上趋于稳定内敛,而娱乐性强的产品则在视觉上限制较少。
随着梯度的增加,设计难度也在增加,如何在不同等级之间拉开合适的视觉感知差距,是一个难点。如上图中的“黑金会员”和“黑金PLUS会员”在视觉上比较雷同,差异较小。当静态视觉发挥空间有限时,可以考虑加入动态元素,增加区分。
徽章系统
与会员等级的本质一样,徽章系统将用户分层,制造不同的用户群,拥有更多、更高级徽章的用户对于产品来说,自然是价值更高的用户,这类用户是产品需要重点关注的对象。他们是产品的深度体验者,他们的意见反馈相比于普通用户更加准确和反映问题。
随着产品本身的日渐成熟,越来越多的产品选择加入会员体系。会员体系无论对产品的短期或者长期利益都至关重要,从短期来讲,直接增加营收,从长期规划来讲,对于增加用户粘性、提高市场份额也有着重要意义。作为设计师,如何把用户对于会员期待的“价值感”、“尊享感”用体验的形式呈现出来,至关重要。
会员体系涉及到的相关设计细节很多,小到一个会员标签,大到一级页面,其中的设计细节更是不胜枚举。将庞大的概念不断拆解为一个个细小的可控的模块,加以分析和总结,始终是沉淀设计经验的方法之一。高大上的观念理论,需要一个个见微知著的细节支撑。
文章来源:站酷 作者:doo_W
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务
蓝蓝设计的小编 http://www.lanlanwork.com