首页

浅入 React 生命周期相关(二)更新生命周期

seo达人

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


更新阶段分为两部分 父组件执行 render 或者调用 this.setState。

componentWillReceiveProps
大部分网上教程为外部 props 发生改变才触发 componentWillReceiveProps,其实不是,当父组件进入 render 时,无论子组件的 props 发没发生改变,都会执行该生命周期函数。 
函数参数有一个,为 nextProps,为将要新的 props。 
值得注意的是,在整个更新阶段的生命周期函数,只有在此函数内可以调用 this.setState 方法,当然其他也可以调用,但是会造成死循环 。

shouldComponentUpdate
该函数需要返回值,如没定义则默认返回 true。当返回值为 true 时,进入 componentWillIpdate ,如为 false ,则什么都不发生。所以说这是一个可以进行 React 性能优化的地方。函数参数有两个 nextProps 和 nextState。我们需用做的就是在 this.props、this.state、nextState、nextProps之间进行对比,来解决重复渲染的目的。

componentWillUpdate
如果 shouldComponentUpdate 返回值为 true 的话,生命周期会进入该函数中。在这个函数中我们可以根据实际情况做一些事情,但是不能调用 this.setState。

render
在更新阶段的 render 来讲一讲 调和 过程。 render 返回的 JSX 标签会保存在内存中,react 会通过 diff 算法来计算出最小化改动完成差异的更新。diff 是逐层递归比较,首先比较类型是否一样。如果发现 <div>和 <span> 的差别的话,react 会选择直接放弃之前的 dom 元素, 重新渲染。所以说即使是更新阶段的调和过程,也会触发组件的挂载、卸载阶段。

componentDidUpdate
在这个时候已经更新完 dom 结构,可以重新使用 dom 操作。

总结
总体来说更新的生命周期要做的最重要的事情就是性能优化,减少重复渲染次数。 
在这个方面已经有很多成熟的解决方法了,在我的博客中也会介绍如何定制更新阶段的生命周期函数。 
在使用上,最最重要的一点就是不要在除了 componentWillReceiveProps 之外的其他更新阶段生命周期函数内调用 this.setState。

相关链接:

浅入 React 生命周期相关(一)挂载生命周期
--------------------- 

重新学习 React (一) 生命周期,Fiber 调度和更新机制

seo达人

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

前几天面试问道 react 的相关知识,对我打击比较大,感觉对 react 认识非常肤浅,所以在这里重新梳理一下,想想之前没有仔细思考过的东西。

另外有说的不对的地方还请帮我指正一下,先谢谢各位啦。

目录索引:

什么是生命周期和调度?

React 有一套合理的运行机制去控制程序在指定的时刻该做什么事,当一个生命周期钩子被触发后,紧接着会有下一个钩子,直到整个生命周期结束。

生命周期

生命周期代表着每个执行阶段,比如组件初始化,更新完成,马上要卸载等等,React 会在指定的时机执行相关的生命周期钩子,使我们可以有机在程序运行中会插入自己的逻辑。

调度

我们写代码的时候往往会有很多组件以及他们的子组件,各自调用不同的生命周期,这时就要解决谁先谁后的问题,在 react v16 之前是采用了递归调用的方式一个一个执行,而在现在 v16 的版本中则采用了与之完全不同的处理(调度)方式,名叫 Fiber,这个东西 facebook 做了有两年时间,实现非常复杂。

具体 Fiber 它是一个什么东西呢?不要着急,我们先从最基本的生命周期钩子看起。

React 生命周期详解

首先看一下 React V16.4 后的生命周期概况(图片来源

 

 

  • 从横向看,react 分为三个阶段:
    • 创建时
      • constructor() - 类构造器初始化
      • static getDerivedStateFromProps() - 组件初始化时主动触发
      • render() - 递归生成虚拟 DOM
      • componentDidMount() - 完成首次 DOM 渲染
    • 更新时
      • static getDerivedStateFromProps() - 每次 render() 之前执行
      • shouldComponentUpdate() - 校验是否需要执行更新操作
      • render() - 递归生成虚拟 DOM
      • getSnapshotBeforeUpdate() - 在渲染真实 DOM 之前
      • componentDidUpdate() - 完成 DOM 渲染
    • 卸载时
      • componentWillUnmount() - 组件销毁之前被直接调用

一些干货

  • 有三种方式可以触发 React 更新,props 发生改变,调用 setState() 和调用 forceUpdate()
  • static getDerivedStateFromProps() 这个钩子会在每个更新操作之前(即使props没有改变)执行一次,使用时应该保持谨慎。
  • componentDidMount() 和 componentDidUpdate() 执行的时机是差不多的,都在 render 之后,只不过前者只在首次渲染后执行,后者首次渲染不会执行
  • getSnapshotBeforeUpdate() 执行时可以获得只读的新 DOM 树,此函数的返回值为 componentDidUpdate(prevProps, prevState, snapshot) 的第三个参数

尝试理解 Fiber

关于 Fiber,强烈建议听一下知乎上程墨Morgan的 live 《深入理解React v16 新功能》,这里潜水员的例子和图片也是引用于此 live。

背景

我们知道 React 是通过递归的方式来渲染组件的,在 V16 版本之前的版本里,当一个状态发生变更时,react 会从当前组件开始,依次递归调用所有的子组件生命周期钩子,而且这个过程是同步执行的且无法中断的,一旦有很深很深的组件嵌套,就会造成严重的页面卡顿,影响用户体验。

React 在V16版本之前的版本里引入了 Fiber 这样一个东西,它的英文涵义为纤维,在计算机领域它排在在进程和线程的后面,虽然 React 的 Fiber 和计算机调度里的概念不一样,但是可以方便对比理解,我们大概可以想象到 Fiber 可能是一个比线程还短的时间片段。

Fiber 到底做了什么事

Fiber 把当前需要执行的任务分成一个个微任务,安排优先级,然后依次处理,每过一段时间(非常短,毫秒级)就会暂停当前的任务,查看有没有优先级较高的任务,然后暂停(也可能会完全放弃)掉之前的执行结果,跳出到下一个微任务。同时 Fiber 还做了一些优化,可以保持住之前运行的结果以到达复用目的。

举个潜水员的例子

我们可以把调度当成一个潜水员在海底寻宝,v16 之前是通过组件递归的方式进行寻宝,从父组件开始一层一层深入到最里面的子组件,也就是如下图所示。

 

 

 

而替换成了 Fiber 后,海底变成的狭缝(简单理解为递归变成了遍历),潜水员会每隔一小段时间浮出水面,看看有没有其他寻宝任务。注意此时没有寻到宝藏的话,那么之前潜水的时间就浪费了。就这样潜水员会一直下潜和冒泡,具体如下图所示。

 

 

 

引入 Fiber 后带来的三个阶段

从生命周期那张图片纵向来看,Fiber 将整个生命周期分成了三个阶段:

  • render 阶段
    • 由于 Fiber 会时不时跳出任务,然后重新执行,会导致该阶段的生命周期调用多次的现象,所以 React V16 之前 componentWillMount()componentWillUpdate()componentWillReceiveProps() 的三个生命周期钩子被加上了 UNSAFE 标记
    • 这个阶段效率不一定会比之前同步递归来的快,因为会有任务跳出重做的性能损耗,但是从宏观上看,它不断执行了最高优先级(影响用户使用体验)的任务,所以用户使用起来会比以前更加的流畅
    • 这个阶段的生命周期钩子可能会重复调用,建议只写无副作用的代码
  • pre-commit 阶段
    • 该阶段 DOM 已经形成,但还是只读状态
    • 这个阶段组件状态不会再改变
  • commit 阶段
    • 此时的 DOM 可以进行操作
    • 这个阶段组件已经完成更新,可以写一些有副作用的代码和添加其它更新操作。

简而言之:以 render() 为界,之前执行的生命周期都有可能会打断并多次调用,之后的生命周期是不可被打断的且只会调用一次。所以尽量把副作用的代码放在只会执行一次的 commit 阶段。

其它生命周期钩子

除了上面常用的钩子,React 还提供了如下钩子:

  • static getDerivedStateFromError() 在 render 阶段执行,通过返回 state 更新组件状态
  • componentDidCatch() 在 commit 阶段执行,可以放一些有副作用的代码

更新机制

理解了生命周期和三个执行阶段,就可以比较容易理解组件状态的更新机制了。

setState()

这个方法可以让我们更新组件的 state 状态。第一个参数可以是对象,也可以是 updater 函数,如果是函数,则会接受当前的 state 和 props 作为参数。第二个参数为函数,是在 commit 阶段后执行,准确的说是在 componentDidUpdate() 后执行。

setState() 的更新过程是异步的(除非绑定在 DOM 事件中或写在 setTimeout 里),而且会在最后合并所有的更新,如下:

Object.assign( previousState,
  {quantity: state.quantity + 1},
  {quantity: state.quantity + 1},
  ...
)
复制代码

之所以设计成这样,是为了避免在一次生命周期中出现多次的重渲染,影响页面性能。

forceUpdate()

如果我们想强制刷新一个组件,可以直接调用该方法,调用时会直接执行 render() 这个函数而跳过 shouldComponentUpdate()

举个极端例子

function wait() { return new Promise(resolve => {
    setTimeout(() => {
      resolve(); console.log("wait");
    }, 0);
  });
} //......省略组件创建 async componentDidMount() { await wait(); this.setState({ name: "new name" }); console.log("componentDidMount");
}

componentDidUpdate() { console.log("componentDidUpdate");
}

render() { console.log(this.state); return null } //......省略组件创建 // 输出结果如下 // wait // {name: "new name"} // componentDidUpdate // componentDidMount // 注意 componentDidUpdate 的输出位置,一般情况下 // componentDidUpdate 都是在componentDidMount 后面 // 执行的,但是这里因为setState 写在了 await 后面 // 所以情况相反。 复制代码

结语

了解 react 生命周期和更新机制确实有利于编写代码,特别是当代码量越来越大时,错用的 setState 或生命周期钩子都可能埋下越来越多的雷,直到有一天无法维护。。。

我的个人建议如下:

  • 把副作用代码通通放在 commit 阶段,因为这个阶段不会影响页面渲染性能
  • 尽可能不要使用 forceUpdate() 方法,借用 Evan You 的一句话,如果你发现你自己需要在 Vue 中做一次强制更新,99.9% 的情况,是你在某个地方做错了事
  • 只要调用了 setState() 就会进行 render(),无论 state 是否改变
  • 知道 setState() 更新的什么时候是同步的,什么时候是异步的,参见上文
  • 不要把 getDerivedStateFromProps() 当成是 UNSAFE_componentWillReceiveProps() 的替代品,因为 getDerivedStateFromProps() 会在每次 render() 之前执行,即使 props 没有改变




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

移动端和PC端交互设计上的区别

涛涛


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

这篇文章我们来谈谈移动端和PC端交互设计上的区别。



Image title


经常遇到一些设计师,他们之前负责的都是pc端产品,突然改做移动端,会不自觉的把pc端的一些设计理念“移植”到移动端,出现了水土不服。有经验的设计师一看你设计的移动端页面就知道你之前做的都是pc端,这是一件非常尴尬的事情。就好像你说了一句“nice to meet you”,别人就知道你老家是哪里一样。那么移动端和pc端交互设计上的区别究竟在哪呢?



大屏到小屏


开门见山,移动端和pc端最根本的区别就是屏幕的大小。屏幕的大小直接决定了界面信息量,pc端一个页面可以展示完全的信息可能需要移动端好几个页面来承载。


Image title


可能有的设计师觉得,屏幕尺寸不一样做自适应不就行了,移动端页面做长一点,让用户滑动就可以了。这是一个非常简单的处理方案,但是忽略了一个重要前提:用户愿不愿意滑动?根据埋点数据显示,多数移动端页面超过一屏的内容的曝光与点击量会急剧下滑,说明用户很少主动滑动去查看一屏以外的内容。对于移动端产品来说,一些重要的内容必须保证用户在一屏内可以看到。


1)信息架构重构


因此,如果你要为一个pc端网站做一个移动端app,首先要做的就是信息架构的重构。pc端有足够的空间可以把所有的功能直接展示给用户,而移动端只能展示一些主要的功能,一些次要的功能需要放在下一层级。


Image title


例如,appstore中用户是可以评价这条评论对自己是否有帮助的。PC端的处理方式很简单,直接展示给用户。而移动端是需要用户长按这条评论才可以弹出评价列表的,可能很多用户今天看了这篇文章才发现原来还有这个功能。没关系,之前虽然不知道,但是并没有影响你正常使用啊。对次要功能进行适当的降低信息层级是移动端设计师必须要考虑的。


2)一个页面,一个任务


对于上面信息架构重构的观点可能会有人存在异议,对于一些表单类页面来说,例如用户要借钱、转账,有些信息是用户必须要填的。在这些场景中,我们不担心用户不滑动,因为用户不滑动就无法完成操作。那么在这种情况下,是否可以继续延续pc端的布局样式?


Image title


以上面的转账流程为例,pc端是直接在一个页面展示,而移动端是分成了两个页面。为什么这样?把备注/付款说明也放在第一个页面不行吗?


因为移动端用户使用环境更加的复杂多变,更容易受到干扰,所以必须保证界面信息的简单直观。如果在一个页面中展示过多的信息量,容易让用户混乱。这里所说信息量并不是指绝对信息量,更准确的说法应该是用户主观感受上的信息量。同样的几个输入框,可能在pc端只占了页面的1/4,而移动端占了一整个页面,给用户的感观是完全不一样的。页面塞的满满当当,容易让用户焦虑。


一个页面可以完成的任务现在要跳转好几个页面,增加了操作步骤。用户害怕“内容多”,难道不害怕“步骤多”吗?不害怕,因为页面内容量是用户一眼就可以看出来的,用户无法立刻感知这个任务有多少步骤。因为无知,所以无畏。等到用户知道这个任务步骤数的时候,整个任务都已经完成了。


Image title


借呗的这次改版,用户要借钱必须先输入借款金额,其余的借款期限还款方式利息等信息才会展示给用户。这些信息都是跟用户借款金额相关的,用户没有输入借款金额,这些信息展示给用户意义也不大,不如隐藏,让用户的注意力聚焦于完成输入借款金额。


Image title


没有一个放之四海而皆准的设计原则,所有的设计理论都不能罔顾实际的应用场景而机械的套用。如果前后步骤关联性比较强,我建议不要分页展示。例如,目前很多的短信验证码都选择把“输入手机号”“输入短信验证码”放到两个页面,我个人对此持保留意见。设想一个场景,如果用户迟迟没有收到短信验证码,那么他需要确定是手机号输错了、网络故障还是其他什么原因。用户需要返回到上一个页面查看,如果手机号和短信验证码放在同一个页面就简单多了。


3)突出重要信息


前面我们提到的主要是控制移动端页面的信息量。页面信息量少就可以了?当然不是,我们来看一下火车换乘的场景,如果你要从南京去新疆阿克苏,没有直达的车次,只能从西安换乘。我们来看看下面两款产品的处理方式,左边是12306,右边是飞猪。12306还是一股pc端风格迎面扑来,问题出现在哪?12306跟飞猪展示信息量差不多,唯一的区别在于12306展示了两趟车次各自的起止时间,而飞猪只告诉用户整趟旅程的起止时间。


Image title


显然问题不是出现在信息量上,而是对信息的展示形式上。用户更关注的信息,应该让用户更容易发现。对于一趟车次来说,用户更加关注出发/到达站出发/到达时间票价。对飞猪界面进行高斯模糊处理,发现用户的视觉焦点正好落在这些重点信息上。


Image title


12306所有的信息都属于同一层级,让人抓不到主次。而且界面中出现了过多的配色,更增加用户的信息获取成本。


Image title




鼠标到手指


pc端用户与界面进行交互靠的是鼠标,移动端用户靠的是手指。鼠标的操作更加精准,因此移动端界面中元素的尺寸和间距比pc端的大。以下图为例,左边是pc端,右边是移动端。移动端的输入框沿用的还是pc端样式,而且关于利率和手续费的详情icon过小,用户的手指点击的时候容易误操作。


Image title



给你的界面做减法


前面我们主要强调了移动端产品要尽量减少界面中信息量。可不可以在不改变产品信息架构的前提下,通过交互设计上的改动来完成目标呢?我给大家介绍两个方法:场景化关联化


1)场景化


在一个页面中,虽然内容很多,但是用户真正感兴趣并且会与之交互的内容很少。如果我们可以获知用户在特定的场景下对于某个内容诉求很高,那么我们突出展示;反之如果诉求很低的话,我们可以隐藏。


举一个之前说过的例子,知乎中,用户在搜索结果页滑动大概3屏后,会出现“向知友提问”按钮。因为用户滑动了3屏,说明用户可能对当前的搜索结果不满意,这时引导用户去提问,用户的意愿更高。如果我们全程展示这个去提问按钮,反而会减少用户的实际浏览区域,造成干扰。


Image title


上面主要提到了,同一个流程,需要根据用户不同的使用场景提供不同的功能。其实即使是同一个功能,我们也要根据用户不同的使用场景选择不同的展示形式。


Image title


还是知乎,为了方便用户可以快速的查看下一个回答,给用户提供了一个浮动按钮。但是这个浮动按钮,当用户开始滑动页面时候就会改变样式。这个很容易理解,当用户刚进入这个页面,为了降低用户的学习成本,我们需要直接告诉用户这个按钮是干什么的。当用户开始滑动进入阅读答案的状态,缩小按钮的形态避免对界面信息造成遮挡。


2)关联化


我们需要梳理信息之间的关联性,将相互关联的信息整合在一起,进而减少页面中信息量。支付宝账单的月份筛选功能,对入口进行了修改。之前用户需要点击日历图标,现在用户直接点击月份就可以了。用户要筛选的就是月份,那么直接把月份作为入口更加合适。


Image title



总结


以上就是我对移动端和pc端交互设计上区别的简单分析和总结,如果你有不同的建议和看法欢迎留言讨论。

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


react-router快速入门上手

seo达人

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

附Java/C/C++/机器学习/算法与数据结构/前端/安卓/Python/程序员必读书籍书单大全:

书单导航页(点击右侧 极客侠栈 即可打开个人博客):极客侠栈
①【Java】学习之路吐血整理技术书从入门到进阶最全50+本(珍藏版)
②【算法数据结构+acm】从入门到进阶吐血整理书单50+本(珍藏版)
③【数据库】从入门到进阶必读18本技术书籍网盘吐血整理网盘(珍藏版)
④【Web前端】从HTML到JS到AJAX到HTTP从框架到全栈帮你走更少弯路(珍藏版)   
⑤【python】书最全已整理好(从入门到进阶)(珍藏版)
⑥【机器学习】+python整理技术书(从入门到进阶已经整理好)(珍藏版)
⑦【C语言】推荐书籍从入门到进阶带你走上大牛之路(珍藏版)
⑧【安卓】入门到进阶推荐书籍整理pdf书单整理(珍藏版)
⑨【架构师】之路史诗级必读书单吐血整理四个维度系列80+本书(珍藏版)
⑩【C++】吐血整理推荐书单从入门到进阶成神之路100+本(珍藏)
⑪【ios】IOS书单从入门到进阶吐血整理(珍藏版)
--------------------------------------------------------------------------------------------------------------------

如果您已经入门reactjs,请绕道~ 这篇博客只适合初学者,初学reactjs的时候,如果你不会webpack,相信很多人都会被官方的例子绕的晕头转向。 ES6的例子也会搞死一批入门者。之前一直用的gulp,突然换了webpack,我也非常不习惯。在这块也卡住了,对于想学reactjs的朋友,我的学习建议是这样的:

nodejs => webpack => ES6 => reactjs 

官方的很多例子都是ES6语法+webpack打包的,所以在学习reactjs之前,最好是会ES6和webpack,这样能事半功倍!

1、首先来说说nodejs

先安装版本的nodejs,npm一般都是自带的。安装成全局的比较方便构建项目。

npm install -g grunt-cli # 全局安装
npm可安装的插件可以在这里去找找 www.npmjs.com/ 如果不能安装,可以使用淘宝的镜象资源

2、webpack 

webpack是一款打包工具,可以做一些js压缩,sass,less转换,图片处理,js代码合成,ES6转ES5语法等很多功能,如果用过grunt,或者gulp的朋友,webpack也就不陌生了。都是需要写配置文件。

3、ES6

github上很多案例都是用到了ES6的语法,所以,这里我们可以通过webpack的工具 babel ,把ES6的语法转化为ES5的语法,这样我们就可以使用github上面的demo了。

比如:

import '../css/common.scss';
import React from 'react'
import { render } from 'react-dom'
import { Router, Route, Link, IndexRoute } from 'react-router' 
import { browserHistory } from 'react-router'
这里的import 就是ES6的语法,在webpack里面使用babel工具将其转化为 ES5的语法。我这里用了JSX(reactjs 提供的一种简洁的语法)如果对JSX不了解的,可以去百度下。

4、快速开发

每次我们在修改JSX文件,或者SASS文件后,都要执行webpack命令进行打包,这样的开发效率很慢,官方提供了一个很牛X的工具,react-hot-loader + webpack-dev-server 可以帮助你快速开发,自动刷新页面。

5、DEMO小试牛刀

这里我把自己做的一个DEMO分享给大家,如果你已经安装了nodejs,并且npm也是全局的。下载后解压,打开 start.bat,输入 npm install 安装所需的插件,安装成功后执行 npm start ,等项目跑起来后,在浏览器输入 http://127.0.0.1:3000 就可以访问项目了。

这里是一个 react-router 的一个例子。

github 地址:https://github.com/mtsee/react-router-demo

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

VUE进阶篇Part10(使用vue-­cli脚手架一键搭建工 程)

seo达人

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

按照这个来配置就好了,这里相当于是帮你把webpack需要的繁琐的配置给你都弄好了,然后你直接从那里全部下下来就可以

记得先下好nodejs,安装的代码记得全都c v,不要自己敲

安装完nodejs之后再安装淘宝npm镜像,安装完了之后后面的安装速度会快一点

npm install -g cnpm --registry=https://registry.npm.taobao.org
1
然后按照下面的五步流程一个一个来

1、全局安装vue­cli

npm install -g vue-cli
1
2、进入目录–初始化项目

vue init webpack my-project //这个要进入项目目录再用,会创建一个my-project的文件夹
1
3、进入项目

cd my-project
1
4、安装依赖

npm install
1
5、启动项目

npm run dev
1
以上执行完后会出现一个 my-project 项目文件夹,用vscode打开后会看到以下目录

下面解释一下这些文件及目录分别是干什么的

目录结构的分析

1、bind
├── build // 项目构建(webpack)相关代码 记忆:(够贱) 9个
│ ├── build.js // 生产环境构建代码
│ ├── check­versions.js // 检查node&npm等版本
│ ├── dev­client.js // 热加载相关
│ ├── dev­server.js // 构建本地服务器
│ ├── utils.js // 构建配置公用工具
│ ├── vue­loader.conf.js // vue加载器
│ ├── webpack.base.conf.js // webpack基础环境配置
│ ├── webpack.dev.conf.js // webpack开发环境配置
│ └── webpack.prod.conf.js // webpack生产环境配置

2、config
├── config// 项目开发环境配置相关代码 记忆: (环配) 3个
│ ├── dev.env.js // 开发环境变量(看词明意)
│ ├── index.js //项目一些配置变量
│ └── prod.env.js // 生产环境变量

3、node_modules
├──node_modules// 项目依赖的模块 记忆: (依赖) *个

4、src
├── src// 源码目录 5

1
│ ├── assets// 资源目录
│ │ └── logo.png
2
│ ├── components// vue公共组件
│ │ └── Hello.vue
3
│ ├──router// 前端路由
│ │ └── index.js// 路由配置文件
4
│ ├── App.vue// 页面入口文件(根组件)
5
│ └── main.js// 程序入口文件(入口js文件)

5、static
└── static// 静态文件,比如一些图片,json数据等
│ ├── .gitkeep

6、剩余的文件
├── .babelrc// ES6语法编译配置
├── .editorconfig// 定义代码格式
├── .gitignore// git上传需要忽略的文件格式
├── index.html// 入口页面
├── package.json// 项目基本信息
├── README.md// 项目说明
--------------------- 

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

QQ 20周年H5刷屏幕后的设计故事

涛涛

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

项目概述

QQ 20周年,是互联网产品长青的一个传说,就在 20 周年的时间节点,QQ 向用户提供一份关于他自己的、真诚热切的 QQ 数据总结。通过数字,汇集出每个人自己的 QQ 时光历程,从而牵引出每个人对于成长、青春、沟通、时代流动的感知与回忆,引发 2019 年一场集体的情感共鸣。

△ QQ 20年来的一路变迁

项目流程

项目历时两个月,从项目初期,视觉和产品密集沟通,了解需求,进行头脑风暴,输出多个视觉方案纵向对比,最后确定视觉风格,分配视觉工作(插画,动画,3D)。项目后期,包括开发还原,数据调配等众多环节,环环相扣,缺一不可,一路过关斩将,整个 H5 需要不同岗位的高度配合和各专业的高度默契。

△ H5的项目流程图

项目难点

1. 异地合作

本次 H5 联动了动效,3D,插画设计师的共同合作,由于支持 3D 的设计师在韩办公,所以大部分都是在线上全英沟通,包括前期的项目进度同步,还有后期的模型调整等环节都能及时反馈,快速反应,最后如期打磨出五款 spaceQQ。算是一次顺利的异地合作。

△ 五款3D spaceQQ最终效果

2. 3D spaceQQ视觉还原

3D 鹅从设计软件转化为 H5 展示过程中,存在模型文件过大、材质缺失等问题,直接影响用户体验。在开发的过程中同学通过模型减面、重新选择材质,还有模型拆分等解决方法,在视觉观感和性能中建立了平衡的杠杆,最终实现了 15 个 SPACE QQ 的视觉还原。

△ 五款3D spaceQQ最终视觉还原效果

3. 视觉工作的同步进行

由于项目时间比较紧迫,而且 H5 加入了 3D 模型,还有需要大量的动效,所以需要在同一时间线上,同步进行,视觉稿输出,动画制作和 3D 模型打磨。考验设计师的沟通和执行能力。与此同时,需要随时和开发同步动画 demo 以确保动画可实现。和产品密集沟通,及时根据文案调整画面。

设计理念

因为 QQ 是陪伴了大多数用户的一个产品,见证了整个互联网社交的演变过程,容易引起用户的情感共鸣。设计的初期,围绕「个人轨迹」的主题发散了不同方向的视觉概念,在引起客户共鸣感的复古元素和传递不断「探索」未来的概念间寻找平衡点。最后沿用了 20 周年的太空概念贴合「探索」的主题,结合有年代特征的代表性视觉符号来引起「个人轨迹」的这一概念的用户情感共鸣。另外,H5 运用了 3D 打造了 15 只太空鹅,打造「个人轨迹」的专属感,既联动用户温暖的回忆之余,也增添了一些小惊喜。

概念设计

1. H5整体视觉风格

QQ,是陪伴了大多数人成长的一个互联网产品,其本身带有很多高辨识度的视觉元素,例如对话框,提醒上线的音效等。因为 H5 本身是一个大数据总结,专属感非常强的一个产物,所以希望是唤醒用户一些封尘已久的记忆,就像打开时间胶囊般的期待和感动。同时也象征着 QQ 一直陪伴在身边,从而引起用户的共鸣。

设计方面,除了通过一些标志性的视觉元素唤醒用户的回忆之外,也加入 QQ 20周年的太空「探索」主题的元素,响应 20 周年的主题之余,也寓意 QQ 不断地对外探索,从多个维度来看世界,寻找有趣的内容。

对话框,是承载数据的视觉符号,也是贯穿整个 H5 的重要视觉符号之一。寓意着 QQ 一直致力于「沟通」,而且不同时代的 QQ 对话框都各有特点,也是见证 QQ 时代变迁的重要元素,所以提取了三个阶段代表性的对话框样式来承载数据,并且加入有时代特征的视觉元素(如bb机,像素化的小箭头等)作为辅助,增加 H5 的氛围感,也算是视觉上的「小彩蛋」。

△ QQ原始对话框

H5 加入一些趣味感的元素,如笑脸,爱心等元素,背景辅以流动的彩色不规则图案,来增加对话框的玩味。也寓意 QQ 20年来给用户带来源源不断的乐趣,留下了不可取代的时代印记。

△ 重绘对话框

H5 中也加入了很多好玩的元素,不同时代所用的移动设备,融合贴近太空「探索」主题的背景;利用带手套的手和不同的元素进行互动;增加重绘经典头像的互动动画,加入 QQ 空间的植物等怀旧元素,增加 H5 的可玩性和惊喜感。

△ 经典头像的重绘

△ 经典头像穿插在H5中的小彩蛋

△ 带手套的手和有时代标签的元素互动

动画设计

1. 视觉动态化方案

在动画制作前期会出一份详细的动态化分页策划,以及一份尽可能表达完整的动画 demo,能便于设计与开发能准确的估算出制作周期。在开发完成预研测试后,基于动画 demo 共同制定一个大致的动态化方案──对话框等大面积使用代码实现,其他装饰性小元素全部使用序列帧。在观众每滑一页即可触发当前页的动画,且能保证大体动画的流畅度。

2. 动画制作

为了尽可能减少 H5 的运算体积,又保证画面动态的流畅程度,导出的序列必须满足以下所有条件:

  • 全部元素可循环
  • 尽可能少的帧数
  • 可重复使用的素材

△ 设计了4个不同的色块流动loop,方便开发安插在每页合适的位置

3. 导出与同步

在配合开发导出的阶段,为了能明确序列的标记,所有序列文件命名为 xx-in/xx-loop/xx-out。使用同步工具以实现 AE 动画序列导出和开发提取素材能同步进行,并保持实时更新和迭代。

△ 第6页动画导出序列

太空QQ形象设定

创建了四款全新的 spaceQQ,根据用户的 QQ 年龄而设计。根据用户的 QQ 年龄,分了四个款式的鹅:奢华,智能,闪亮和神秘四个概念,一个递进的尊贵程度,刺激用户分享欲。包括基础款的 QQ 在内,共创造了 5 个类型的 spaceQQ。每个设计都基于基本 spaceQQ 的形式,但是套装的颜色和细节根据各自的概念各有特色。

△ spaceQQ总览图

配色方案

用户可以根据自己的喜好更改这 5 款 spaceQQ 的装扮颜色。

关于运营

1. 专属感

整个 H5 始终紧扣 QQ 20周年的太空「探索」主题,整个 H5,除了用数据唤醒用户和 QQ 多年的点点滴滴之外,5 个 spaceQQ 概念设定,既能增加用户的新鲜感,又能刺激用户的分享欲,C4D 建立的 3D 形象丰富了整个 H5 的视觉层次,深化了 QQ 品牌的影响力,寓意鹅厂一直与时俱进,紧贴潮流。

2. 情绪调动

对于当下的运营活动来说,趣味性是引爆转发量的重要元素,H5 结合 QQ 用户创作的背景音乐和能够调动用户情感的设计语言来释放用户的情绪,比如惊喜感(用户结合 QQ 的标志性音效创作的背景音乐),荣誉感(不同 Q 龄获取相应的 spaceQQ)等,让用户产生持续的惊喜感,在怀旧和新鲜感中得到满足,提升用户活跃性。

总结

QQ 20周年 H5 设计,尝试结合了 3D,动画,插画等设计形态,为每一位用户打造专属的「个人轨迹」,通过数字,拼凑出和 QQ 的过往朝夕,引起用户共鸣。鹅厂不断创新探索的同时,也为用户温存属于用户自己的专属回忆,深化 QQ 的品牌价值。

福利

考虑到部分同学想更仔细地查看、保存或收藏高清大图的需求,我们设置了关键词,微信公众号后台以「spaceQQ+序号」的方式回复,例如「spaceQQ1」,即可逐一获取对应的高清头像和壁纸。

扫码领取专属「个人轨迹」:

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

日历

链接

个人资料

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

存档