首页

UI 工作流程指南:需求分析

涛涛

如果您想订阅本博客内容,每天自动发到您的邮箱中, 请点这里

完整的 UI 设计流程到底是怎样的?从需求到产品上线,要经历多少个阶段,每个阶段有哪些应该掌握的基础知识,本次优设独家专题为你从零开始梳理出 UI 工作流程,适合新手阅读学习。

本篇工作流程第一节:需求分析。

UI 设计工作,包括 APP 设计、网页设计、小程序设计等方面。而一个产品完整的 UI 设计流程,是指拿到一个新的项目需求后,从设计思考开始,产品前期分析,设计产品,设计评审,用户测试,直至产品上线。

我们的工作流程如下:

以上的流程都是与设计师密切相关的内容,我们的关注点不能只有视觉效果,孤立的设计容易脱离产品,反复修改,因此前期分析与后期支持都值得我们重视。

产品立项后的第一阶段是需求分析阶段,当我们拿到一个新的需求时,首先要了解的就是产品的需求是什么,了解市场背景、产品定位、概念,客户的需求是什么。

一般来说,我们接到的需求分为三类:全新产品、现有产品新增功能、产品改版。

需求文档类型

前期分析阶段中,需求方主要是与产品经理进行沟通,产出文档有三种:

  • BRD文档(Business Requirement Document):商业需求文档,基于商业目标或价值所描述的产品需求内容文档(报告)。
  • MRD文档(Market Requirement Document):市场需求文档,该文档在产品项目过程中属于「过程性」文档,由产品经理或者市场经理编写的一个产品说明需求的文档。
  • PRD文档(Product Requirement Document):产品需求文档是将商业需求文档(BRD)和市场需求文档(MRD)用更加专业的语言进行描述。

分析类网站推荐

产品分析纬度

有了数据参考来源后,我们就能从五个纬度分析产品。

1. 产品分析

市场背景、产品业务、现有产品各项数据。

2. 用户画像

  • 显性画像:即用户群体的可视化的特征描述。如目标用户的年龄、性别、职业、地域、兴趣爱好等特征。
  • 隐性画像:用户内在的深层次的特征描述。包含了用户的产品使用目的、用户偏好、用户需求、产品的使用场景、产品的使用频次等。

3. 需求确认

产品需求主要是为了满足用户或企业价值,所以一定要确认重要且紧要的需求内容是什么,什么功能和内容暂时不需要做,什么功能和内容放在后期做,因此设计时也要考虑产品未来的扩展性。

4. 逻辑流程

  • 逻辑流程,整个产品的逻辑、内部流程;
  • 用户路径,描述用户在产品内部的路径。

5. 竞品分析

和国内外同类产品进行比较分析,知己知彼。

竞品选择,从两个方向出发:

  • 从产品类型出发:比如我们需要设计的产品是财务类,选择的方向也是同类财务类产品;
  • 从产品功能出发:比如说财务产品中有着支付购买的功能板块,选择的竞品也包括了购物、生活类产品。

相关教程:《视觉设计师如何做竞品分析?来看这份超全面的指南!》

最后,比起产品经理来说,设计师在这个阶段能获三个信息:

  • 自己需要完成什么;
  • 要做到什么程度;
  • 扩展性的考虑,可以在设计时预留位置。

文档整理工具

语雀:https://www.yuque.com

蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计  cs界面设计  ipad界面设计  包装设计  图标定制  用户体验 、交互设计、 网站建设 平面设计服务

产品设计之「取消按钮」的使用详解 | 细节分析

涛涛


如果您想订阅本博客内容,每天自动发到您的邮箱中, 请点这里

通过对「取消按钮」的分析,指导各位正确的进行对于「按钮」的设计。


按钮,无论是在 Web 还是 App 上都被广泛地使用,而很少有设计师会注意到按钮当中的细节,导致在设计过程中出现一些低级的错误,使得用户在完成任务的过程中产生阻碍,无法顺利达成目的。


在许多优秀的产品中,关于按钮的设计已经有了一套相应的规范去执行。作为设计师,应该总结这些规范,并产出一套适用于自家产品的设计规则。这也是我写「按钮规范」系列文章的目的。


今天主要先与各位聊聊「取消按钮」的设计思路。


关于「取消」,大多数人对其理解还停留在 PC 端,认为「取消」的目的就是让用户停止操作上的流程。但时至今日,「取消按钮」的设计已经有许多解法与思路,如果不仔细研究与分析,可能会忽略一些用户行为上的细节。


所以我们从下面三个大点来聊聊「取消按钮」的设计:

  1. 按钮中的「召唤行为」(理清按钮设计的概念)

  2. 其背后的控制权(关于按钮的权重信息)

  3. 「取消按钮」的正确解法(重点)



按钮中的「召唤行为」


通常,我们在产品中会为了达成某种指标,需要在界面上引导用户去完成我们希望其完成的操作。且这类操作是可以达成某种目的的,我们把这类操作称为「召唤行为」,即从元素的角度引导用户完成任务。


这类「召唤行为」最常出现的,是在按钮设计的过程中。


用户如何将元素理解为按钮?就是通过对形状和颜色的控制,使该元素看起来像一个按钮。



它唯一的作用就是让用户点击,并且是主动让用户点击

我们经常在各类设计中见到这样的按钮设计,或许还有更多样式,如:



它们的目的一致,都是召唤用户进行点击,至于类型的选择一般根据功能界面的上下文情况进行判断。


其重要程度也是以此顺序排列:凸起 > 扁平 > 边框 > 文本。


这类设计的结果就是:无需让用户思考要点哪里,而是直接判断下一步是否进行。帮助用户简化一个思考点。


注:因为判断是否进行的操作还取决于功能本身以及文案的提示,与我们今天要聊的不是一回事。所以我们跳过这块,直接聊「召唤行为」与「取消按钮」的关系。


这段内容各位只要记住:按钮的行进与回退,基本遵循「召唤行为」的思路来设计。


这个概念知道了,我们就可以对后面的内容继续进行拆解了。



背后的控制权


接下来我们从多个角度来挖一下「取消按钮」的设计,分析其不同地位。


a. 安全性后退


「取消」在多数情况下,意为安全性地后退,并将界面恢复到原有的内容上,不对界面与功能本身造成破坏,防止对系统进行不必要地更改的「安全措施」。


所以正常来说,「取消按钮」不是「召唤行为」。以至于通常在设计上会被弱化,以表示该按钮在功能的流程中,不是主要的,且是提供给用户作为回退余地的操作。


如:



在这张图里,「登录」是「召唤行为」,所以突出显示。根据风格定义,用了扁平按钮。而取消在这个场景里属于「安全性后退」的操作,于是将其弱化。


这是多数产品采用的设计方式。


比如美团的这个页面:



产品希望用户登录,就会强化「登录」行为的按钮,弱化「回退」行为的按钮。


同样,我们在微信朋友圈的设计里也能见到这样的设计:



我们总是希望用户持续操作下去,但也要给用户提供回退的行为,所以在这些设计中,「取消按钮」会被弱化,「行进按钮」会被强化,因为「取消按钮」在这里不是产品人员期望的「召唤行为」。


这是一直以来的设计共识,但如今也发生了些许变化。「取消按钮」也开始具备「召唤行为」的属性。


b. 强化「取消按钮」


当我们不希望用户退出某个界面,或停止某个流程时,往往会选择将「取消按钮」强化。


如:



或:



通过对字体的加粗,以暗示用户不要轻易退出。在这个流程里,「取消按钮」具备了「召唤行为」属性。


也有产品通过改变「取消按钮」的文案,让其具备「召唤行为」的属性,使得用户在此过程中轻易不要退出该流程:



这里的「继续选座」就是「取消」,因为这里的「取消」成了「召唤行为」,所以通过改变文案的方式,确保用户留下来继续进行流程中的任务。


但是不可取的是,这里的「返回」反而给了用户一种需要思考的压力。返回?是留在这里,还是退出去?思考几秒后,反应过来,是退出去。这样的文案与只有在看到「继续选座」后进行对比,才能反应过来具体是什么意思,除非是用户具备操作习惯,知道「右边」是「行进」操作,才能很快理解。(当然还有个问题,我们在第三各模块来说明)


但是多数用户还是得思考一下,所以要改,最好两者文案都能改了,否则思考的「停顿」会让用户产生厌恶感。


且在一些产品界面里,为了避免用户在流程中终止行为,甚至会转移「取消」与「行进」两者的位置,如:



之前截图了某个产品的界面,写文这天发现已经改回来,这里就没放了。


各位谨记,最好不要这样进行设计,因为用户在 App 的操作上已经习惯左边取消,右边行进,调换位置虽然能暂时解决用户的退出行为,但容易产生误操作,与用户的期望不同,导致在产品体验上会被用户排斥。


所以到这里,先给一个结论,即在 App 的设计上,行进操作在右,回退操作在左,召唤属性根据场景对按钮做突出处理。


但是「取消按钮」真的应该具备召唤属性么?不着急,我们第三模块再细聊。下面我们先聊聊 Web 与 App 的之间的差异。


c. Web 与 App 的位置差异


我们现在见到越来越多的 Web 端产品,也开始遵循 App 产品的设计,把「取消按钮」放在左边,「召唤行为」按钮放在右边。


但在早期,Web 的「取消按钮」基本是放在右边,原因是鼠标的移动路径是根据眼动规则来,我们的视线会首先与文案聚焦到「召唤行为」的按钮上,也就是左边,这时候鼠标轻而易举地随之而来。


而手指行为的操作,会以右为前进导向,且右手手势因为便捷性,也会以右为确认操作。否则单手持机,且行进路径长的话,用户想进行确认操作会相对比较吃力。



这就是 Web 与 App 在按钮位置上的主要区别。


那会有同学问到说 Web 的「取消」到底是放在左边还是右边?这里我说点自己的想法。


如果根据眼动规则与鼠标的操作模式来说,Web 「取消按钮」当然是放在右边更为合适。但如今人们已经习惯了移动产品的「右行进,左取消」属性,且在界面上的视觉终点一般是在右边,能引导用户进行召唤行为。


但这不具备指导性原则,如果要拆开说,里面还有很多说法。


比如 windows 和 macOS 的设计规范里「取消按钮」的位置完全是相反的。win 的取消在右,macOS 的取消在左。



两套体系的按钮位置相互矛盾。这件事本身也说明,只要你在你的 Web 产品里规范好自己的设计体系,就没有对错之分。不要一会儿这个「取消」在左边,一会儿那个「取消」又在右边,给用户造成认知障碍即可。


但是!我更推崇 macOS 的设计规范。原因在于成熟度与一致性。


主观因素:众所周知,苹果是更擅长做设计的公司,体验过 Mac 的朋友应该能理解我说的这句话。一般来说,我只听过从 Win 切换到 Mac 的,没有说从 Mac 切换到 Win 的,除了少部分因为工作需求需要同步使用的。


客观因素:移动产品的普及,已经有相当成熟的设计体系支持行进按钮右侧化设计,统一 Web 或 PC 产品只会让用户的操作行为更方便。


这就是我本小节想聊的,关于 Web 与 App 按钮设计的差异。



「取消按钮」的正确解法


我相信,只要是平时稍微有认真观察的同学,都能知道我上述聊的内容。我个人也不认为这些内容具备任何需要总结的价值。但是如果不写出来,就没办法说明我接下来要聊的内容,也是我这篇文章的重点部分。


通过上述内容,我以不同类型的按钮案例来解释「取消按钮」的控制权。各位可以看出,即使是不同类型的「取消按钮」,在权重上的道理也都是一样的。


但我上面举的所有产品功能的例子,都不是最佳设计方案,包括微信。


那如何设计才是最佳方式呢?取消按钮真的具备召唤行为?


a. 界面层与弹框层


其实严谨点来说,界面层的「取消按钮」与弹框层的「取消按钮」的意义是不同的。


虽然都是安全性后退,但是前者多了一层含义:放弃属性。


还是微信朋友圈的界面:



这里的「取消按钮」有两个状态,一是用户刚点进来,无任何操作,点击取消,解散该页面;二是进来之后,附带操作行为,这时候点击取消,不仅仅是解散当前页面,还包括「放弃当前编辑的状态」。


所以会弹出第二层弹窗:



这时候无论点击「保留」还是「不保留」都是取消,退出当前编辑页面,不对系统产生变更行为,但都属于放弃了当前操作。

无非就是微信通过加粗「保留」来告诉用户,这里的召唤行为是它而已。


所以这层「取消」的含义,不仅仅是取消,还多了一步是否把你放弃的内容保留下来的逻辑。


因此在这层含义上,「取消按钮」也需要特殊处理。


如果说微信这里的「取消按钮」在设计上没有突出其特殊性,那 Twitter 同样的例子,就比微信高明很多:



同样是发布行为,Twitter 在「取消按钮」上选用了品牌色。因为在其编辑状态下点击取消,会出现与微信同样的情况:




而 Twitter 的高明之处不仅仅在其对于「取消按钮」的样式处理,还在于其对是否「保留」做了明确的设计区分:微信的保留等于 Twitter 的保存草稿,不保留等于删除。而在通用型设计规范里,删除内容在样式上应该区别于发布以及取消。


更甚者是,其弹出的这个弹框中,还保留了真正意义上的「取消」,即解散行为。在 Twitter 的这个设计上,两个取消虽然都叫取消,但是通过颜色进行区分,来表示它们之间在逻辑上的差异,这才是我说的高明之处 —— 对每个按钮的处理都恰到好处。


类似的还有微博,但是微博对于「取消按钮」的类型差异没有做出区分,原因在于它为了弱化界面层的取消,与弹框层的取消样式保持了一致。



虽然没什么太大问题,但从严格的逻辑上来说,这两者取消是存在歧义的。只是用户已经习惯且理解了,所以没要造成使用的负担。


微信的弹框虽然避免了这层歧义,但在操作上还是不够直观,我每次发微信朋友圈,点取消弹出「保留」与「不保留」我都要停顿一下谨慎地进行选择,生怕自己点错。


当然,这里面还有关于颜色的说法。


这时候再对比 Twitter 的界面就能看出设计师之间的差距了。


b. 弹框层「取消」颜色的差异


上面提到的许多例子中,还存在一个类似的问题:它们大多选用 iOS 自带的弹框直接做为操作对象。


我始终觉得在 iOS 提供的弹框中,两个操作的按钮颜色保持一致是不对的。


粗细有时候很难被直观感受,而颜色可以在第一时间被感知。


比如前面提到的这个案例:



理想情况下,即使用户知道右边是行进,左边是取消,但弹出这个弹框的时候,不免还是需要再次阅读一遍进行确认。


但如果改个颜色,好像就更好理解(当然文案也是问题,但优先级弱于颜色),毕竟弹框也是设计的一部分:



需要注意的是,用户既然已经选择取消,就尽量明确的告知用户,不要为了留存而留存,以至于模糊化该弹窗的选择结果。

所以召唤行为,并不是强迫用户去做,而是遵循用户的「旨意」去提供选择。这里的「返回」才是真正的召唤行为,而「取消」并不具备召唤属性。硬生生的给「取消」附上召唤属性,只会让用户在操作时摸不着头脑。


包括下图,我常常因为在使用 App 时,弹出这样的弹框,而不能在第一时间进行正确的点击,选择退出当前的 App。



这样例子还有很多。


但是我觉得做得好的,应该是这样的:



或:



这就是刻板印象造成的结果。我们应该学会适当地使用控件,并根据自己的产品对其进行优化。而不是一味跟风。


综上所述:界面层的取消,为了表示其作用性的不同,且界面元素众多,突出颜色是没问题的;但弹框层的取消与确认在颜色上没做区分,直接用不太明显的粗细效果让用户聚焦于这两个内容的选择上,其实是不友好的设计。


如果对 iOS 设计规范有足够的了解的同学就能知道:它们在弹框控件上给出的两个选择都不是真正意义上的召唤行为按钮,只是常规内容,且更适用于产品开发,而不是设计指导。


如果你仔细观察 macOS 的设计,就能发现他们为具备召唤行为的按钮位置与颜色都做了特殊处理,并不是简单的同色系,或用粗细表示。如图:



虽然用 macOS 来反驳 iOS 似乎不太合理,但我只是想说明在设计结果上,我们应该有自己的思考。


就这个问题,我在 Twitter 上咨询了前 Apple,后创办了 UXM 的产品设计师 Anthony。原因是,他曾经也就「取消按钮」的颜色提出过一些个人看法。


在我说了这些内容之后,他跟我说的第一句话是:

Hi Dai — While Apple is very good at design, they are not perfect.(Apple 非常擅长设计,但它们并不完美。) 

接着他继续说道:你这套理论非常棒,所以你完全可以按它去给自己的产品构建一套设计规范,并不一定要遵循 Apple。


借着这个机会,我还跟他聊了许多其他内容。而这件事本身再一次验证了我的想法:越牛逼的人越谦虚,且平易近人。


哦,不是,跑题了,应该是:不存在完美的设计规范,设计师在成长过程中并不一定要循规蹈矩,受到规则的限制,认为设计就该如此。而是学会独立思考,突破屏障,去挖掘更深层次的内容。


看完这篇文章,再去翻一翻 Google Material Design Guidelines,就会有一种「哇哦!原来如此!」的感触了。



小结


所以我这篇文章的内容结论是:

  1. 位置固定,左回退,右行进;

  2. 颜色区分,左浅色,右深色;

  3. 召唤行为不是用户想做的事,而是我们应该要让用户做的事,但不是强迫,所以正常情况下,「取消按钮」通常不具备召唤属性。


可能有人会觉得,这么一个小问题,不至于用这么长一篇文章来说明,不过人么,就是存在这样那样的区别。我认为需要就可以了。


本来这篇文章还有一段关于「手势按钮尺寸」的内容,不过到目前为止,文章内容太长了,所以我暂时去掉了,会在之后的文章里分享给大家。


当然,到此为止,我聊的内容基本适用于通用场景,且适用于大部分的产品设计,但在一些特殊场景下的按钮位置、颜色,也会有不同设计方式,这就要根据具体问题来具体分析。


我这里只是把「取消按钮」的设计差异、细节提供给大家,以便帮助各位在工作中有更深入的思考,而不是想当然的说就是放左边或右边,或者就应该是什么颜色等等。包括对待其他内容也一样。

蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计  cs界面设计  ipad界面设计  包装设计  图标定制  用户体验 、交互设计、 网站建设 平面设计服务


vue 移动端弹出键盘导致页面fixed布局错乱

seo达人

如果您想订阅本博客内容,每天自动发到您的邮箱中, 请点这里

话不多说,直接上问题图片


这里确认按钮是fixed布局 bottom:0 弹出键盘之后按钮被顶到了键盘上面

网上搜到的解决方案有两种,

一种是监听页面高度(我采用的这种)

一种是监听软键盘事件(ios和安卓实现方式不同,未采用)

下面是实现代码

data() {
    return {
        docmHeight: document.documentElement.clientHeight ||document.body.clientHeight,
        showHeight: document.documentElement.clientHeight ||document.body.clientHeight,
        hideshow:true  //显示或者隐藏footer
    }
  },
watch: {
        //监听显示高度
      showHeight:function() {
          if(this.docmHeight > this.showHeight){
            //隐藏
              this.hideshow=false
          }else{
            //显示
              this.hideshow=true
          }
      }
  },
mounted() {
      //监听事件
      window.onresize = ()=>{
          return(()=>{
              this.showHeight = document.documentElement.clientHeight || document.body.clientHeight;
      })()
      }
 
  },
<div class="bottom" v-show="hideshow">
    <div class="btn">
      确认操作
    </div>
  </div>
我这里使用的是方法是:当键盘弹出时,将按钮隐藏。如果必须出现按钮的话,可以修改按钮回归到正常的流中。
蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、网站建设 平面设计服务

【Vue原理】Watch - 白话版

seo达人

如果您想订阅本博客内容,每天自动发到您的邮箱中, 请点这里

【Vue原理】Watch - 白话版
简述 响应式
监听的数据改变的时,watch 如何工作
设置 immediate 时,watch 如何工作
设置了 deep 时, watch 如何工作
举栗子
结论
没有设置 deep
设置了 deep
实际证明
专注 Vue 源码分享,为了方便大家理解,分为了白话版和 源码版,白话版可以轻松理解工作原理和设计思想,源码版可以更清楚内部操作和 Vue的美,喜欢我就关注我的公众号,公众号的文章,排版更好看

如果你觉得排版难看,请点击下面公众号链接

【Vue原理】Watch - 白话版


今天我们用白话文解读 watch 的工作原理,轻松快速理解 watch 内部工作原理。你说,你只懂怎么用的,却不懂他内部是怎么工作的,这样能有什么用?

近期有篇 《停止学习框架》很火,其实本意不是让我们不要学框架,而是让我们不要只停留在框架表面,我们要学会深入,以一敌十,让我们也要学会框架的抽象能力

watch 想必大家用得应该也挺多的,用得也很顺,如果你顺便花一点点时间了解一下内部的工作原理,相信肯定会对你的工作有事半功倍的效果

watch 的工作原理其实挺简单的,如果你有看过我之前讲解其他选项的文章,你可以一下子就明白 watch 是如何工作的,所以这边文章我也✍得很快

根据 watch 的 api,我们需要了解三个地方

1、监听的数据改变的时,watch 如何工作

2、设置 immediate 时,watch 如何工作

3、设置了 deep 时,watch 如何工作



简述 响应式
Vue 会把数据设置响应式,既是设置他的 get 和 set

当 数据被读取,get 被触发,然后收集到读取他的东西,保存到依赖收集器

当 数据被改变,set 被触发,然后通知曾经读取他的东西进行更新

如果你不了解,可以查看下 以前的文章

【Vue原理】响应式原理 - 白话版



监听的数据改变的时,watch 如何工作
watch 在一开始初始化的时候,会 读取 一遍 监听的数据的值,于是,此时 那个数据就收集到 watch 的 watcher 了

然后 你给 watch 设置的 handler ,watch 会放入 watcher 的更新函数中

当 数据改变时,通知 watch 的 watcher 进行更新,于是 你设置的 handler 就被调用了



设置 immediate 时,watch 如何工作
当你设置了 immediate 时,就不需要在 数据改变的时候 才会触发。

而是在 初始化 watch 时,在读取了 监听的数据的值 之后,便立即调用一遍你设置的监听回调,然后传入刚读取的值



设置了 deep 时, watch 如何工作
我们都知道 watch 有一个 deep 选项,是用来深度监听的。什么是深度监听呢?就是当你监听的属性的值是一个对象的时候,如果你没有设置深度监听,当对象内部变化时,你监听的回调是不会被触发的

在说明这个之前,请大家先了解一下

当你使用 Object.defineProperty 给 【值是对象的属性】 设置 set 和 get 的时候

1如果你直接改变或读取这个属性 ( 直接赋值 ),可以触发这个属性的设置的 set 和 get

2但是你改变或读取它内部的属性,get 和 set 不会被触发的

举栗子
var inner = { first:1111 }
var test={    name:inner  }

Object.defineProperty(test,"name",{
    get(){         
        console.log("name get被触发")         
        return inner
    },
    set(){        
        console.log("name set被触发")
    }
})

// 访问 test.name 第一次,触发 name 的 get
Object.defineProperty(test.name,"first",{
    get(){        
        return console.log("first get被触发")
    },
    set(){        
        console.log("first set被触发")
    }
})

// 访问 test.name 第二次,触发 name 的 get
var a = test.name
// 独立访问 first 第一次
var b= a.first 
// 独立访问 first 第二次
b= a.first
// 独立改变 first
a.first = 5


能看到除了有两次需要访问到 name,必不可少会触发到 name 的 get

之后,当我们独立访问 name 内部的 first 的时,只会触发 first 的 get 函数,而 name 设置的 get 并不会被触发

结论
看上面的例子后,所以当你的 data 属性值是对象,比如下面的 info

data(){    

    return {        

        info:{ name:1 }

    }

}


此时,Vue在设置响应式数据的时候, 遇到值是对象的,会递归遍历,把对象内所有的属性都设置为响应式,就是每个属性都设置 get 和 set,于是每个属性都有自己的一个依赖收集器

首先,再次说明,watch初始化的时候,会先读取一遍监听数据的值

没有设置 deep
1、因为读取了监听的 data 的属性,watch 的 watcher 被收集在 这个属性的 收集器中

设置了 deep
1、因为读取了监听的data 的属性,watch 的 watcher 被收集在 这个属性的 收集器中

2、在读取 data 属性的时候,发现设置了 deep 而且值是一个对象,会递归遍历这个值,把内部所有属性逐个读取一遍,于是 属性和 它的对象值内每一个属性 都会收集到 watch 的 watcher

于是,无论对象嵌套多深的属性,只要改变了,会通知 相应的 watch 的 watcher 去更新,于是 你设置的 watch 回调就被触发了

实际证明
证明 watch 的 watcher 深度监听时是否被内部每个属性都收集

我在 Vue 内部给 watch 的 watcher 加了一个 属性,标识他是 watch 的 watcher,并且去掉了多余的属性,为了截图短一点
蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、网站建设 平面设计服务

FY品牌官网/移动端视觉设计

涛涛

如果您想订阅本博客内容,每天自动发到您的邮箱中, 请点这里

Fucking Young(简称 FY) 是一家专注于男性半球的年轻美学,我们自由使用和支配模特及艺术家合作,从而帮助自己与合作方达到合理的业务需求,建立一个拥有创造力的社区,赞助和发布这些惊艳的作品在我们的官网甚至手机产品上。

带来的作品有FY品牌官网与移动端设计,展示部分界面与交互动效,Gif输出存在色差,实际情况以高保真视觉界面为准。

FY品牌官网/移动端视觉设计FY品牌官网/移动端视觉设计FY品牌官网/移动端视觉设计FY品牌官网/移动端视觉设计FY品牌官网/移动端视觉设计FY品牌官网/移动端视觉设计FY品牌官网/移动端视觉设计FY品牌官网/移动端视觉设计FY品牌官网/移动端视觉设计FY品牌官网/移动端视觉设计FY品牌官网/移动端视觉设计FY品牌官网/移动端视觉设计FY品牌官网/移动端视觉设计FY品牌官网/移动端视觉设计FY品牌官网/移动端视觉设计FY品牌官网/移动端视觉设计

文章来源:UI中国

蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计  cs界面设计  ipad界面设计  包装设计  图标定制  用户体验 、交互设计、 网站建设 平面设计服务

【Web前端笔记07】列表与超链接

seo达人

如果您想订阅本博客内容,每天自动发到您的邮箱中, 请点这里

1.无序列表
无序列表是网页中最常用的列表,之所以称为“无序列表”,是因为其各个列表项之间为并列关系,没有顺序级别之分,列如:

<ul>
<li>列表1</li>
<li>列表2</li>
<li>列表3</li>
</ul>

2.有序列表
有序列表即为有顺序的列表,其各个列表项会按照一定的顺序排列,列如:

<ol>
<li>列表1</li>
<li>列表2</li>
<li>列表3</li>
</ol>


注:列表可以嵌套。

3.超链接标记< a>
1.超链接
一个网站通常由多个页面构成,进入网站时首先看到的是其首页,如果想从首页跳转到其子页面,就需要在首页相应的位置添加超链接。其基本语法格式为:

<a href="跳转目标" target=“目标窗口的弹出方式”>文本或者图像</a>
1
其中,target有两种取值方式:

–blank (在新窗口中打开)-self(默认在本窗口打开)

2.伪类
超链接标记< a >的伪类 含义
a:link{ CSS样式规则; } 未访问时超链接的状态
a:visited{ CSS样式规则;} 访问之后超链接的状态
a:hover{ CSS样式规则;} 鼠标经过,悬停时超链接的状态
a:active{ CSS样式规则;} 鼠标单击不动时超链接的状态
--------------------- 
蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、网站建设 平面设计服务

Tab Bar 图标动效设计类型总结

涛涛

如果您想订阅本博客内容,每天自动发到您的邮箱中, 请点这里

Tab bar 作为整个 APP 的第一触点,给用户传递的理念及信息在整个 APP 中具有不可替代的重要性。我们的第一感受是粗糙或是精致,都会通过这个简单的操作切换而感知。因此 tab bar 的设计,往往也是检验整个 APP 设计是否精致的标准。

Tab bar 设计中,有一个很重要但却常常会被设计师们遗漏的关键点──tab 切换时的 「图标动画设计」。如这些 APP 的底部 tab 设计都使用了这一种方式(以下视频):

Tab bars图标动画的作用

精彩的图标动画,对整体的设计具有画龙点睛的作用,降低 tab 切换时的枯燥感,提升操作的愉悦度和期待感。甚至可以通过 tab 的动画设计给用户传达出整个 APP 设计的品牌及理念。

1. 动静对比

动态的设计丰富了图标更多可能性的表达,结合不同的动态效果表达出不同的情绪或情感。而除了情感的表达之外,最基础的作用在于动态比静态更加吸引眼球,增加视觉关注度,因此在切换 tab 时具有更强的视觉冲击力。

2. 柔和与生硬

缓动的动效过渡,相比于无动效的设计,在 tab 切换时整体的视觉感受会更加柔和、轻量。过渡直接的反馈,容易造成生硬而不具美感。

3. 趣味的表达

由于动效的加入,我们在设计 tab 切换时会变得更加多元化,而不是单纯的设计一个动作的反馈。在过渡的时间差中,可以进行很多趣味的表达。

3. 情绪代入

图标结合表情的设计,运用动效的设计,让整体的情绪感受更加直观。如下图案例,默认态与选中态通过前后的差异对比,点击后出现的表情惊喜,具有不一样的情绪变化。

Tab bar图标动画的基础类型

动画的设计是多样化的,Tab bar 图标动画的类型实际上并没有明确的划分,这里主要列举的是自己在日常浏览设计网站时的收集,以及个人认为比较常见的一些类型。我们可以基于这些常见类型的设计,对我们的设计进行再升华,从而提高整体设计的质感和趣味。

1. 缩放动画

点击后通过一定的比例 「缩放」 反馈,突出 tab 之前的变化,从而强化了 tab 操作的感知,提升对于操作区域的视觉聚焦。结合不同的缩放效果,可以呈现出不同的视觉感知,缩放动画大致分为线性和弹性两种类型。

线性缩放

图标在放大或缩小的过程中,使用了匀速的动画效果,整体动画一步到位、干净利落。整体视觉感知较为柔和。

弹性缩放

带有弹性缩放的 tab 反馈,让整体的设计更加具有趣味性,相比线性缩放也更有视觉冲击力。图标的运动规则:先从 0 放大到最大(数值根据实际情况设定),然后再回弹至正常大小。

2. 透明度自然过渡

让 tab 切换之间的过渡更加自然、柔和。相比于纯静态切换只多了一层透明度变化,但却具有完全不一样的视觉感受。

3. 位移

位移出现的图标会产生一定的速度感,但需要控制位移的速度,过快容易忽略中间的运动轨迹,而影响自然过渡的效果。

4. 抖动

通过图标的左右、上下快速位移或旋转形成,整体的动画效果节奏较快,具有一定的速度感。情绪表达上较为俏皮。

左右抖动

点击后,图标反馈进行上下快速位移。建议来回位移次数不宜太多,控制在 1-2 次左右,次数太多容易显得拖沓。

跳动的图标

点击切换后,图标从底部弹起再回到初始位置,整体视觉感受具有跳动的韵律感。

晃动的图标

旋转抖动的图标比上下或左右会更加具有趣味感。设定图标的中心点或角点为旋转轴,通过来回晃动而形成的效果。

5. 填充

切换时,默认 tab 由线性向面性的转变。填充类型的动画效果整体简单、直接,直观地表达出图标切换前后的对应关系。关键点在于处理好线性与面性图标的细节转换。

中心填充

使用某种几何图形(可以是圆形或其他)通过发散放大的设计方式,结合一定的节奏韵律扩展至填满整个图标。

扫描填充

动画效果从图标的一侧,通过划动变化至填满。

6. 画线-线性轨迹

以线性图标或线面图标中的线运动为主,在设计整套图标时,运动轨迹需要保持统一(线的初始与结束的位置/方向等)。轨迹不一致,容易导致图标的一致性被破坏。

局部细节画线

选择图标的关键细节或图标的特征进行画线设计,增强图标的特征细节,提高图标的记忆点。

整体画线

与局部细节画线基本一致,差别的点在于表达了不同的视觉感受。整体画线从视觉感受上会相对更加饱满。但需要根据图标的复杂程度而定,图标过渡复杂,可能容易造成拖沓的动画效果。

7. 结合容器

结合不同的几何形作为选中图标的当前态的背景,在背景上设计出现的动画效果。既强化了选中当前态,整体的 tab 切换的一致性也较高。

8. 元素介质

设计上结合某种图形元素作为当前选中态,在切换时通过元素的位移、跳动等方式来达到 tab 切换的动画效果。

Tab图标动画的组合形

除了以上单种类型的动画方式外,还可以尝试多种方式结合。通过不同的方式结合可以产生出更多的可能性,让你的设计更加具有创意和打破常规。

1. 填充+画线

2. 填充+抖动

3. 弹性缩放+填充

4. 元素介质+抖动

5. 位移+透明度

更多案例(来自dribbble)

总结

tab bar 的图标动画最大的作用在于解决切换时的枯燥与单调,我们在设计时除了单纯追求动画的变化及多样性之外,更多需要思考的是什么样的动画更符合我们的设计。

本文的主旨是分享自己日常看到的一些动画效果,以及对收集的内容进行的分析。实际的动画样式或者效果肯定远远不只这些,我们可以通过基础的方法再结合自己的创意发挥出更多满足自我设计的表达方式。

蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计  cs界面设计  ipad界面设计  包装设计  图标定制  用户体验 、交互设计、 网站建设 平面设计服务

HTML 盒子模型div

seo达人

如果您想订阅本博客内容,每天自动发到您的邮箱中, 请点这里

HTML 中的div定义:

可定义文档中的分区或节(division/section)。

标签可以把文档分割为独立的、不同的部分。它可以用作严格的组织工具,并且不使用任何格式与其关联。

如果用 id 或 class 来标记 div,那么该标签的作用会变得更加有效。
用法

div是一个块级元素。这意味着它的内容自动地开始一个新行。实际上,换行是

固有的唯一格式表现。可以通过 div的 class 或 id 应用额外的样式。
不必为每一个 div都加上类或 id,虽然这样做也有一定的好处。

可以对同一个 div 元素应用 class 或 id 属性,但是更常见的情况是只应用其中一种。这两者的主要差异是,class 用于元素组(类似的元素,或者可以理解为某一类元素),而 id 用于标识单独的唯一的元素。

实例
<div id = " text"><div> <div class = " text1"><div> <div class = " text1"><div>
//div 中可以设置id属性,通过引用id属性来为div设置一些样式

//在style标签中,可以对你写的代码进行样式的设计,样式设计可以通过以下几种方法来写
1.通过引用id来设置样式,在id名称前加上# 格式: #id名称{ }
#text{ }
2.通过class来设置样式,class后面的名字可以是一样的,而id取名唯一,因此在需要设置同类型的样式时可以使用class来设置 格式: .class名称{ }
.text1{ }
3.通过标签名称来设置样式 格式: div{ }
div{ }

样式:
1.width :50px; // 宽度
2.height :50px;//高度
3.border : 1px solid red; //边框,border可以设置三个属性,分别是边框宽度,边框样式(实线,虚线等),边框颜色
4.margin:属性定义及使用说明

margin简写属性在一个声明中设置所有外边距属性。该属性可以有1到4个值。

实例:

margin:10px 5px 15px 20px;
    上边距是 10px
    右边距是 5px
    下边距是 15px
    左边距是 20px

margin:10px 5px 15px;
    上边距是 10px
    右边距和左边距是 5px
    下边距是 15px

margin:10px 5px;
    上边距和下边距是 10px
    右边距和左边距是 5px

margin:10px;
    所有四个边距都是 10px
蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、网站建设 平面设计服务

|学会版式的N个Tips|—线要怎样用,才能让你的设计更加分

涛涛

如果您想订阅本博客内容,每天自动发到您的邮箱中, 请点这里

线往往会被设计师忽略,或许对线的理解有局限性,因而不常使用。那么线要怎样用才能让设计更加分呢?下面给大家分享关于线的文章

文章来源:站酷

蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计  cs界面设计  ipad界面设计  包装设计  图标定制  用户体验 、交互设计、 网站建设 平面设计服务

7个有用的Vue开发技巧

seo达人

如果您想订阅本博客内容,每天自动发到您的邮箱中, 请点这里

1 状态共享

随着组件的细化,就会遇到多组件状态共享的情况,Vuex当然可以解决这类问题,不过就像Vuex官方文档所说的,如果应用不够大,为避免代码繁琐冗余,最好不要使用它,今天我们介绍的是vue.js 2.6新增加的Observable API ,通过使用这个api我们可以应对一些简单的跨组件数据状态共享的情况。


如下这个例子,我们将在组件外创建一个store,然后在App.vue组件里面使用store.js提供的store和mutation方法,同理其它组件也可以这样使用,从而实现多个组件共享数据状态。


首先创建一个store.js,包含一个store和一个mutations,分别用来指向数据和处理方法。



import Vue from "vue";

export const store = Vue.observable({ count: 0 });

export const mutations = {

setCount(count) {

store.count = count;

}

};

复制代码

然后在App.vue里面引入这个store.js,在组件里面使用引入的数据和方法



<template>

<div id="app">

<img width="25%" src="./assets/logo.png">

<p>count:{{count}}</p>

<button @click="setCount(count+1)">+1</button>

<button @click="setCount(count-1)">-1</button>

</div>

</template>

<script>

import { store, mutations } from "./store";

export default {

name: "App",

computed: {

count() {

return store.count;

}

},

methods: {

setCount: mutations.setCount

}

};

</script>

<style>

复制代码

你可以点击在线DEMO查看最终效果


2 长列表性能优化

我们应该都知道vue会通过object.defineProperty对数据进行劫持,来实现视图响应数据的变化,然而有些时候我们的组件就是纯粹的数据展示,不会有任何改变,我们就不需要vue来劫持我们的数据,在大量数据展示的情况下,这能够很明显的减少组件初始化的时间,那如何禁止vue劫持我们的数据呢?可以通过object.freeze方法来冻结一个对象,一旦被冻结的对象就再也不能被修改了。



export default {

data: () => ({

users: {}

}),

async created() {

const users = await axios.get("/api/users");

this.users = Object.freeze(users);

}

};

复制代码

另外需要说明的是,这里只是冻结了users的值,引用不会被冻结,当我们需要reactive数据的时候,我们可以重新给users赋值。



export default {

data: () => ({

users: []

}),

async created() {

const users = await axios.get("/api/users");

this.users = Object.freeze(users);

},

methods:{

// 改变值不会触发视图响应

this.users[0] = newValue

// 改变引用依然会触发视图响应

this.users = newArray

}

};

复制代码

3 去除多余的样式

随着项目越来越大,书写的不注意,不自然的就会产生一些多余的css,小项目还好,一旦项目大了以后,多余的css会越来越多,导致包越来越大,从而影响项目运行性能,所以有必要在正式环境去除掉这些多余的css,这里推荐一个库purgecss,支持CLI、JavascriptApi、Webpack等多种方式使用,通过这个库,我们可以很容易的去除掉多余的css。


我做了一个测试,在线DEMO



<h1>Hello Vanilla!</h1>

<div>

We use Parcel to bundle this sandbox, you can find more info about Parcel

<a href="https://parceljs.org" target="_blank" rel="noopener noreferrer">here</a>.

</div>

复制代码


body {

font-family: sans-serif;

}

a {

color: red;

}

ul {

li {

list-style: none;

}

} import Purgecss from "purgecss";

const purgecss = new Purgecss({

content: ["**/*.html"],

css: ["**/*.css"]

});

const purgecssResult = purgecss.purge();


终产生的purgecssResult结果如下,可以看到多余的a和ul标签的样式都没了


4 作用域插槽

利用好作用域插槽可以做一些很有意思的事情,比如定义一个基础布局组件A,只负责布局,不管数据逻辑,然后另外定义一个组件B负责数据处理,布局组件A需要数据的时候就去B里面去取。假设,某一天我们的布局变了,我们只需要去修改组件A就行,而不用去修改组件B,从而就能充分复用组件B的数据处理逻辑,关于这块我之前写过一篇实际案例,可以点击这里查看。


这里涉及到的一个最重要的点就是父组件要去获取子组件里面的数据,之前是利用slot-scope,自vue 2.6.0起,提供了更好的支持 slot和 slot-scope 特性的 API 替代方案。


比如,我们定一个名为current-user的组件:



<span>

<slot>{{ user.lastName }}</slot>

</span>

复制代码

父组件引用current-user的组件,但想用名替代姓(老外名字第一个单词是名,后一个单词是姓):



<current-user>

{{ user.firstName }}

</current-user>

复制代码

这种方式不会生效,因为user对象是子组件的数据,在父组件里面我们获取不到,这个时候我们就可以通过v-slot 来实现。


首先在子组件里面,将user作为一个<slot>元素的特性绑定上去:



<span>

<slot v-bind:user="user">

{{ user.lastName }}

</slot>

</span>

复制代码

之后,我们就可以在父组件引用的时候,给v-slot带一个值来定义我们提供的插槽 prop 的名字:



<current-user>

<template v-slot:default="slotProps">

{{ slotProps.user.firstName }}

</template>

</current-user>

复制代码

这种方式还有缩写语法,可以查看独占默认插槽的缩写语法,最终我们引用的方式如下:



<current-user v-slot="slotProps">

{{ slotProps.user.firstName }}

</current-user>

复制代码

相比之前slot-scope代码更清晰,更好理解。


5 属性事件传递

写过高阶组件的童鞋可能都会碰到过将加工过的属性向下传递的情况,如果碰到属性较多时,需要一个个去传递,非常不友好并且费时,有没有一次性传递的呢(比如react里面的{...this.props})?答案就是v-bind和v-on。


举个例子,假如有一个基础组件BaseList,只有基础的列表展示功能,现在我们想在这基础上增加排序功能,这个时候我们就可以创建一个高阶组件SortList。



<!-- SortList  -->

<template>

<BaseList v-bind="$props" v-on="$listeners"> <!-- ... --> </BaseList>

</template>

<script>

import BaseList from "./BaseList";

// 包含了基础的属性定义

import BaseListMixin from "./BaseListMixin";

// 封装了排序的逻辑

import sort from "./sort.js";

export default {

props: BaseListMixin.props,

components: {

BaseList

}

};

</script>

复制代码

可以看到传递属性和事件的方便性,而不用一个个去传递


6 函数式组件

函数式组件,即无状态,无法实例化,内部没有任何生命周期处理方法,非常轻量,因而渲染性能高,特别适合用来只依赖外部数据传递而变化的组件。


写法如下:


在template标签里面标明functional

只接受props值

不需要script标签


<!-- App.vue -->

<template>

<div id="app">

<List

:items="['Wonderwoman', 'Ironman']"

:item-click="item => (clicked = item)"

/>

<p>Clicked hero: {{ clicked }}</p>

</div>

</template>

<script>

import List from "./List";

export default {

name: "App",

data: () => ({ clicked: "" }),

components: { List }

};

</script>

复制代码


<!-- List.vue 函数式组件 -->

<template functional>

<div>

<p v-for="item in props.items" @click="props.itemClick(item);">

{{ item }}

</p>

</div>

</template>

复制代码

7 监听组件的生命周期

比如有父组件Parent和子组件Child,如果父组件监听到子组件挂载mounted就做一些逻辑处理,常规的写法可能如下:



// Parent.vue

<Child @mounted="doSomething"/>

// Child.vue

mounted() {

this.$emit("mounted");

}

复制代码

这里提供一种特别简单的方式,子组件不需要任何处理,只需要在父组件引用的时候通过@hook来监听即可,代码重写如下:



<Child @hook:mounted="doSomething"/>

复制代码

当然这里不仅仅是可以监听mounted,其它的生命周期事件,例如:created,updated等都可以,是不是特别方便~


参考链接:


vueTips

vuePost


蓝蓝设计www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 平面设计服务


日历

链接

个人资料

蓝蓝设计的小编 http://www.lanlanwork.com

存档