首页

Vue的防抖和节流(接口频繁调用如何处理)

前端达人

首先描述一下我所使用的业务场景:系统有一个批量审批的功能,每个审批的流程需要根据提交的用户实时的反馈回去进去用户页面的刷新,如果一个用户同时有多个流程被审批通过,前端会向服务端频繁的多次调用同一个接口,造成服务器压力过大和页面卡顿,非常影响用户体验。
目标:需要短时间内向服务端频繁调用接口时只去调用最后一次的接口。(防抖)

防抖和节流的区别:主要体现在执行次数上的区别,比如我们写一个200ms的延迟时间,节流就是每200ms执行一次,而抖动是只有在最后一次事件的200ms内调用一次回调函数。
防抖和节流都可以用于 mousemove、scroll、resize、input、click等事件,他们的区别在于防抖只会在连续的事件周期结束时执行一次,而节流会在事件周期内按间隔时间有规律的执行多次。

防抖 debounce

当事件被频繁触发时,在一定的时间内再去执行回调函数,如果在等待期间再次被触发,则重新计时,直至整个等待期间没有新的事件被触发,执行回调函数。

举个例子:一个点击事件,为了防止用户重复发起请求,如果用户在三秒内多次发生点击事件,点击事件将只执行一次,第一次和第二次点击的间隔只要在三秒钟内就会重置这个等待时间,第二次和第三次之间的最大等待时间也是三秒,如果第二次点击事件发生后的三秒内没有新的点击事件产生,第二次点击后的三秒就会调用回调函数。

可以直接引用loadsh的debounce方法来实现函数防抖,也可以自己写一个防抖函数(利用定时器)

  1. 引用loadsh

这里先给一个中文文档的地址:https://www.lodashjs.com/docs/lodash.debounce
在vue3.x中也推荐了这种方式:https://v3.vuejs.org/guide/data-methods.html#methods
有多种引用方式,这里我直接采用npm的方式

npm i --save lodash 
  • 1

使用loadsh的debounce方法

<el-button id="myBtn" type="goon" icon="el-icon-search" @click="test">点击事件</el-button> 
  • 1
let _ = require('lodash'); _.debounce(fun,ms,options) fun: 回调函数
ms:等待时间,毫秒
options:选项对象 
  • 1
  • 2
  • 3
  • 4
  • 5

注意:这里点击事件要写成test: 的形式,test()这样是不生效的

import debounce from 'lodash/debounce' methods:{ test:debounce(()=>{ console.log("防抖函数执行",) },3000) } //或者下面这种写法 document.getElementById("myBtn").addEventListener('click', debounce(function (event) { console.log("防抖函数执行",) }, 3000)) 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  1. 自定义防抖函数
<el-button type="goon" icon="el-icon-search" @click="test">点击事件</el-button> 
  • 1
data:{ timer:null }, methods:{ //在最后一次点击三秒后才会触发一次点击事件 test(){ clearTimeout(this.timer) //自定义个定时器三秒后执行,一旦有新的事件发生会将这个定时器清除重新创建一个,只有三秒内不出现事件这个定时器才不会被销毁重构 this.timer = setTimeout(()=>{ console.log("防抖执行,这里就是你需要执行的操作") },3000) } } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

节流 throttle

在规定的时间内只触发一次回调函数,在规定时间内多次触发函数,只会执行一次

举个例子:一个点击事件,你设定了节流的延迟时间为一秒钟,那么在你一直点击的情况下,每隔一秒会触发一次这个事件,直到你的点击停止,这个不会累积,比如一秒钟内点击了五次,然后不再点击时,事件也只会触发一次而不会累积到触发五次,这种累积的可以采用定时器实现。

节流一般多用于监听输入框和滚动条,同样的在我们的loadsh中也有写好的节流的函数throttle,使用方法和上面防抖类似,这里就不详细写了,主要写一下 自定义的节流函数。

throttle(fun, ms,options) fun:需要节流的回调函数
ms:等待时间
options:额外配置项 
  • 1
  • 2
  • 3
  • 4

自定义节流函数:
原理就是用时间戳判断是否到了回调的执行时间,记录上次执行的时间戳,然后每次触发 事件执行回调,回调里边判断当前时间戳距离上一次执行时间戳的间隔是否已经到达规定的时间,如果是就执行,并且会更新上次执行的时间戳。
下面是我写的一个简单的例子,可以根据自己需求进行修改

data:{ //这里我直接页面创建时定义了一个初始的变量,保存上一次函数执行的时间 lastTime:new Date() }, methods:{ //fun 代表要执行的函数,需要被节流的函数 throttle(fun){ //函数执行时的时间 let now = new Date() console.log("now",now) console.log("lastTime",this.lastTime) //两次调用的时间差 if (now - this.lastTime > 1000){ fun() //调用成功,上一次调用时间值修改 this.lastTime = now } }, test(){ this.throttle(function (){ //1000ms内无论点击多少下,只会调用一次 console.log("节流函数调用,时间1000ms") }) }, } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

image.png

如果项目多次用到可以将以上的方法封装成一个工具类。

参考文章:https://www.jb51.net/article/161713.htm














蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请扫码蓝小助,报下信息,蓝小助会请您入群。欢迎您加入噢~~希望得到建议咨询、商务合作,也请与我们联系。

分享此文一切功德,皆悉回向给文章原作者及众读者.

转自:csdn
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。

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

ES6——数组扩展 ... Array.from() Array.of() flat() reduce()

前端达人

1.扩展运算符…

ES6——扩展运算符…

2.Array.from()

将两类对象转为真正的数组:类数组(querrySelectAll)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)

类数组

1.赋给length属性的对象

 //将类数组转化为真正的数组 let k={ 0:'a', 1:'b', length:2 //没有length属性就不行 } console.log(Array.from(k)); //['a', 'b'] 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

2.字符串也有length属性,它也是类数组

 let str='hello'; console.log(Array.from(str)); // ['h', 'e', 'l', 'l', 'o'] 
  • 1
  • 2

3.参数如果是真正的数组 则返回一个全新数组

 let s1=[1,2,3]; let s2=Array.from(s1); console.log(s2==s1); //false 
  • 1
  • 2
  • 3

3.Array.of()

一组值,转换为数组

Array.of(3, 11, 8) // [3,11,8] Array.of(3) // [3] Array.of(3).length // 1 
  • 1
  • 2
  • 3

这个方法的主要目的,是弥补数组构造函数Array()的不足。因为参数个数的不同,会导致Array()的行为有差异。

只有当参数个数不少于 2 个时,Array()才会返回由参数组成的新数组

Array() // [] Array(3) // [, , ,] Array(3, 11, 8) // [3, 11, 8] 
  • 1
  • 2
  • 3

4.find() 和 findIndex()

find方法,用于找出第一个符合条件的数组成员

 var result1=[1,2,3,4].find(function (item) { return item%2==0; }) console.log(result1); //2 
  • 1
  • 2
  • 3
  • 4

findIndex方法,返回第一个符合条件的数组成员的位置。
如果所有成员都不符合条件,则返回-1

 var result1=[1,2,3,4].findIndex(function (item) { return item%2==0; }) console.log(result1); //1 
  • 1
  • 2
  • 3
  • 4

5.fill() 填充数组

使用给定值,填充一个数组

console.log(new Array(5).fill('a')); //['a', 'a', 'a', 'a', 'a'] 
  • 1

fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置。

['a', 'b', 'c'].fill(7, 1, 2) // ['a', 7, 'c'] 
  • 1

6.数组实例的 entries(),keys() 和 values()

Set,Map,Object中都有这些方法

entries(),keys()和values()——用于遍历数组。
它们都返回一个遍历器对象,可以用for…of循环进行遍历
唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。

 let yes=[1,2,3,4]; console.log(yes.keys()); //Array Iterator {} console.log(yes.values()); //Array Iterator {} console.log(yes.entries()); //Array Iterator {} 
  • 1
  • 2
  • 3
  • 4
 let yes=[1,2,3,4]; for(let key of yes.keys()){ console.log(key); //0 1 2 3 } for(let key of yes.values()){ console.log(key); //1 2 3 4 } for(let [key,value] of yes.entries()){ console.log(key,value); //0 1 //1 2 //2 3 //3 4 } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

7.includes()

console.log([1, 2, 3].includes(1)); //true console.log([1, 2, 3].includes(1,1)); //false 从1号索引开始找 
  • 1
  • 2

8.flat()

将嵌套的数组“拉平”,变成一维的数组。
该方法返回一个新数组,对原数据没有影响

//默认只能拉平一层 console.log([1, 2, [3, 4]].flat()); //[1, 2, 3, 4] //如果拉平多层 设置层数 console.log([1, 2, [3, [4, 5]]].flat(2)); // [1, 2, 3, 4, 5] //如果层数太多 设置Infinity console.log([1, 2, [3, 4, [5, 6, [7, 8]]]].flat(Infinity)); //[1, 2, 3, 4, 5, 6, 7, 8] 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

9.reduce()

reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。对空数组是不会执行回调函数的。

1.计算数组总和

var num = [1,2,3,4,5]; var res = num.reduce(function(total,num){ return total+num; //return total + Math.round(num);//对数组元素四舍五入并计算总和 },0); console.log(res); //15 //num.reduce((total,num) => total += num, 0); //没有初始值initialValue(即上面例子中的0),当数组为0时会抛出异常提示reduce函数没有初始值,所以为兼容性一般加上initialValue 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

2.合并二维数组

var red = [[0, 1], [2, 3], [4, 5]].reduce(function(a, b) { return a.concat(b); }, []); console.log(red); //[0, 1, 2, 3, 4, 5] 
  • 1
  • 2
  • 3
  • 4

3.统计一个数组中有多少个不重复的单词
reduce()函数










蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请扫码蓝小助,报下信息,蓝小助会请您入群。欢迎您加入噢~~希望得到建议咨询、商务合作,也请与我们联系。

分享此文一切功德,皆悉回向给文章原作者及众读者.

转自:csdn
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。

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

Vue的设计理念

前端达人

目录

Mvvm模型

Vue中的Mvvm实现原理

自己实现双向数据绑定的示例

Vue与模板引Thymeleaf擎对比

显示变量值(Vue)

 显示变量值(Thymeleaf)

替换Html(Vue)

替换Html(Thymeleaf)

绑定属性(Vue)

绑定属性(Thymeleaf)

隐藏显示区块(Vue)

隐藏显示区块(Thymeleaf)

遍历列表数据-带索引(Vue)

 遍历列表数据-带索引(Thymeleaf)

引入其他文件内容(vue)

引入其他文件内容(Thymeleaf)

Vue的页面定义基石-Options API

Vue中的代理运用

nginx反向代理

vue代理(正向代理)

Vue特性能力-filter


Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合

Mvvm模型

MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核心是提供对View 和 ViewModel 的双向数据绑定,这使得ViewModel 的状态改变可以自动传递给 View,即所谓的数据双向绑定。
Vue.js 是一个提供了 MVVM 风格的双向数据绑定的 Javascript 库,专注于View 层。它的核心是 MVVM 中的 VM,也就是 ViewModel。 ViewModel负责连接 View 和 Model,保证视图和数据的一致性,这种轻量级的架构让前端开发更加高效、便捷。

Vue中的Mvvm实现原理

Vue.js的实现方式,对数据(Model)进行劫持,当数据变动时,数据会出发劫持时绑定的方法,对视图进行更新。

这里有两个方向: 

1、数据流向视图:数据变动时,能自动更新Dom节点的内容。此功能是通过数据劫持实现的,对数据(Model)进行劫持,当数据变动时,会调用劫持时绑定的方法,对视图进行更新。

2、视图流向数据:如输入框input内容发生变动时,input对应的数据也会发生变动。此功能是通过监听Dom事件实现的。当用户在输入框中输入文字(即inputkeyup事件发生时),vue会监听到这个事件,找到对应的数据模型变量,修改变量值。

vue中双向数据绑定的示例


  1. <div id="app-6">
  2. <p>{{ message }}</p>
  3. <input v-model="message">
  4. </div>

  1. var app6 = new Vue({
  2. el: '#app-6',
  3. data: {
  4. message: 'Hello Vue!'
  5. }
  6. })

自己实现双向数据绑定的示例


  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <title>双向绑定demoo</title>
  5. <meta charset="UTF-8">
  6. </head>
  7. <body>
  8. <div id="app">
  9. <input type="text" id="txt">
  10. <p id="show-txt"></p>
  11. </div>
  12. </body>
  13. <script>
  14. var model={}
  15. Object.defineProperty(model,'txt',{
  16. _txt: "",
  17. get:function(){
  18. return _txt
  19. },
  20. set:function(newValue){
  21. _txt = newValue
  22. document.getElementById('txt').value = newValue
  23. document.getElementById('show-txt').innerHTML = newValue
  24. }
  25. })
  26. document.addEventListener('keyup',function(e){
  27. model.txt = e.target.value
  28. })
  29. </script>
  30. </html>

这里要讲到一个关键函数

Object.defineProperty 

Object.defineProperty 需要三个参数(object , propName , descriptor)

1 object 对象 => 给谁加
2 propName 属性名 => 要加的属性的名字 【类型:String】
3 descriptor 属性描述 => 加的这个属性有什么样的特性【类型:Object】

descriptor 属性描述

get一个给属性提供getter的方法,如果没有getter则为undefined。该方法返回值被用作属性值。默认为undefined
set一个给属性提供setter的方法,如果没有setter则为undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认值为undefined

Vue与模板引Thymeleaf擎对比

显示变量值(Vue)


  1. <div id="app">
  2. {{ message }}
  3. </div>

 显示变量值(Thymeleaf)


  1. <div id="app" th:text="${message}">
  2. </div>

替换Html(Vue)


  1. <div id="app" v-html="content">
  2. </div>

替换Html(Thymeleaf)


  1. <div id="app" th:html="${content}">
  2. </div>

绑定属性(Vue)

<img :src="imgUrl" :id="newId"/>

绑定属性(Thymeleaf)

<img th:attr="id=${newId},src=${imgUrl}"/>

隐藏显示区块(Vue)


  1. <div id="app" v-if="show">
  2. 这是一个区块
  3. </div>

隐藏显示区块(Thymeleaf)


  1. <div id="app" th:if="${show}">
  2. 这是一个区块
  3. </div>

遍历列表数据-带索引(Vue)


  1. <ul id="app">
  2. <li v-for="(item, index) in dataList">
  3. {{ index }} - {{ item.message }}
  4. </li>
  5. </ul>

 遍历列表数据-带索引(Thymeleaf)


  1. <ul id="app">
  2. <li th:each="item, stat: ${dataList}">
  3. {{ stat.index }} - {{ item.message }}
  4. </li>
  5. </ul>

引入其他文件内容(vue)

在vue中,可复用的单元块被称为组件,定义组件


  1. <template>
  2. <button v-on:click="count++">You clicked me {{ count }} times.</button>
  3. </template>
  4. <script>
  5. export default {
  6. name: "button-counter"
  7. data(){
  8. count: 0
  9. }
  10. }
  11. </script>

 引入组件


  1. <div id="components-demo">
  2. <button-counter></button-counter>
  3. </div>

引入其他文件内容(Thymeleaf)

被导入模块index.html:


  1. <div th:fragment="head">
  2. 这是网页头
  3. </div>

在其它页面导入index.html中的head模块:

<div th:include="index::head"></div>

由此可见在Html层面上来讲,vue和后台的模板引擎,整个设计方向是一样。都是使用特定属性标签,来描述如何把数据映射到视图上。

Vue的页面定义基石-Options API

Options API,即大家常说的选项API,即以vue为后缀的文件,通过定义methodscomputedwatchdata等属性与方法,共同处理页面逻辑

可以看到Options代码编写方式,如果是组件状态,则写在data属性上,如果是方法,则写在methods属性上...

这种形式的页面定义类似一个配置文件,定义了页面的数据模型和行为

Vue中的代理运用

代理服务器:所谓代理服务器就是位于发起请求的客户端与原始服务器端之间的一台跳板服务器,是以正向代理可以隐藏客户端,反向代理可以隐藏原始服务器。

代理分为正向代理和反向代理,下面就以我们实际使用中的示例讲解下这两种代理方式的区别。

nginx反向代理

这样对于浏览器而言,浏览器只需要访问代理服务器,就可以达到同时访问两个网站的目的

 

我们看下实际场景下的nginx的配置 


  1. server {
  2. listen 4503;
  3. server_name vue.izkml.com;
  4. access_log "pipe:rollback logs/gov-manage-new-vue/access_log interval=1d baknum=7 maxsize=2G" main;
  5. # 接口代理
  6. location /api {
  7. #去除 /api前缀
  8. rewrite ^.+api/?(.*)$ /$1 break;
  9. # 转发到 117.71.53.199:50020端口上
  10. proxy_pass http://117.71.53.199:50020;
  11. proxy_buffering off;
  12. }
  13. # 页面文件代理
  14. location / {
  15. # 直接去本地文件读取文件路径
  16. root html/gov-task-supervison;
  17. index index.html index.htm;
  18. if (!-e $request_filename) {
  19. rewrite ^/(.*) /index.html last;
  20. break;
  21. }
  22. }
  23. }

其中可以看到,主要分为接口代理和页面代理两部分
1. 如果是/api前缀的请求,则去除/api前缀,转发到后台网关端口上
2. 其他情况下,请求的为页面内容,在html/gov-task-supervison文件夹中读取文件内容

vue代理(正向代理)

 


  1. devServer: { // 支持webPack-dev-server的所有选项
  2. port: 8888, // 端口号
  3. host: '0.0.0.0',
  4. https: false,
  5. open: true, //配置自动启动浏览器
  6. proxy: {
  7. '/api': {
  8. // 转发地址
  9. target: 'http://117.71.53.199:50020', //测试环境
  10. changeOrigin: true,
  11. ws: true,
  12. // 去除/api前缀
  13. pathRewrite: {
  14. '^/api': ''
  15. }
  16. }
  17. }
  18. }

这里主要看的是proxy字段,其中定义了规则

1. 如果是/api前缀的请求,则去除/api前缀,转发到后台网关端口上
2. 其他情况下,请求的为页面内容,直接读取本地项目路径下面的页面内容 **(隐式包含)**

Vue特性能力-filter

Vue.js 允许你自定义过滤器,可被用于一些常见的文本格式化

应用场景: 前端常量翻译


  1. <el-tag v-if="scope.row.status" class="round" size="small" >
  2. {{scope.row.status | CodeMaster('TASK_STATUS')}}
  3. </el-tag>

  1. Vue.filter('CodeMaster', function (value, type) {
  2. return Vue.prototype.$codeMaster.getCodeValue(type, value);
  3. })

在上面的代码中,我们在模板html中,添加了filter的调用,并传入了一个参数。
在vue进行html生成的过程中,会调用相应的filter,根据自定义的规则,完成文本格式化操作。




蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请扫码蓝小助,报下信息,蓝小助会请您入群。欢迎您加入噢~~希望得到建议咨询、商务合作,也请与我们联系。

分享此文一切功德,皆悉回向给文章原作者及众读者.

转自:csdn
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。

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

JavaScript防抖与节流,深入浅出,一本正经讲透彻

前端达人

目录

一、函数防抖(debounce)

1. 什么是防抖?

二.、函数节流

2.1 定时器实现

2.2 时间戳实现

2.3 时间戳+定时器

最后 


一、函数防抖(debounce)

1. 什么是防抖?

函数防抖在频繁触发某一个事件时,一段时间内不再触发该事件后才会去调用对应的回调函数,在设定间隔时间内如果下一次事件被触发, 那么就重新开始定时器,直到事件触发结束。

规定时间内没有继续触发事件的前提下,再去调用事件处理函数;

具体如下面的例子所示:


  1. /*定义防抖函数
  2. * func:传入一个函数,事件不再持续触发时会调用该函数
  3. * delay:定义持续多久后执行传入的回调函数
  4. * */
  5. function debounce(func,delay) {
  6. let timer = null // 用于保存定时器
  7. return function (...args) {
  8. // 如果定时器存在,清除定时器,随后重新设置timer
  9. if(timer !== null) clearTimeout(timer)
  10. timer = setTimeout(func, delay) // 超过delay为接收到事件会调用这里的func 必要的额时候可以修改func的this指向 由于timer对外部存在引用,因此不会被销毁
  11. }
  12. }
  13. /*事件处理函数*/
  14. function testDeBounce(){
  15. console.log('你看我执行了几次??')
  16. }
  17. // 接收debounce返回的函数
  18. const temp = debounce(testDeBounce(),1000)
  19. /*绑定事件,测试防抖函数*/
  20. window.addEventListener('scroll',()=>{
  21. temp()
  22. }); // 这样写最少调用一次事件处理函数,最多也不会多余下面的写法执行的次数
  23. window.addEventListener('scroll', testDeBounce); // 如果这样写的话,每当页面滚动就会调用事件处理函数
  • 总结一下思路

    1.定义一个节流函数

    2.函数内部使用一个变量保存定时器

    3.返回一个函数,函数内部定义:如果定时器已经存在就清除定时器,重新设置定时器

    4.定义一个变量来接收debounce返回的函数

    5.在事件的回调函数中直接调用上一步的变量接收的方法


二.、函数节流

函数节流在事件持续触发的前提下,保证一定时间段内只调用一次事件处理函数,就是函数节流;

函数节流实现的方式定时器、时间戳、定时器+时间戳;

2.1 定时器实现

思路

1.定义节流函数throttle

2.定义timer保存定时器

3.返回一个函数。函数内部定义:如果定时器不存在,设置定时器,间隔某一时间后将timer设置为null,如果在这之前事件再次触发,则定时器中的回调无效

<button>这是一个孤独的按钮</button> 

  1. /*
  2. * 定义定时器节流函数
  3. * func:传入事件处理函数
  4. * delay:在delay指定的时间内定时器回调无效
  5. * */
  6. function throttle(func,delay) {
  7. let timer = null
  8. const context = this
  9. return function(...args){
  10. // 如果定时器不存在
  11. if(!timer){
  12. timer = setTimeout(()=>{
  13. func.apply(context,args) // 考虑返回的函数调用的环境,因此这里不直接使用this
  14. timer = null // delay之后清除定时器
  15. },delay)
  16. }
  17. }
  18. }
  19. function test() {
  20. console.log('啊啊啊!')
  21. }
  22. const temp = throttle(test,1000)
  23. document.querySelector('button').addEventListener('click',()=>{
  24. temp()
  25. })

2.2 时间戳实现


  1. var throttle = function(func, delay) {
  2. var prev = Date.now();
  3. return function() {
  4. var context = this;
  5. var args = arguments;
  6. var now = Date.now();
  7. if (now - prev >= delay) {
  8. func.apply(context, args);
  9. prev = Date.now();
  10. }
  11. }
  12. }
  13. function handle() {
  14. console.log(Math.random());
  15. }
  16. window.addEventListener('scroll', throttle(handle, 1000));

2.3 时间戳+定时器


  1. // 节流throttle代码(时间戳+定时器):
  2. var throttle = function(func, delay) {
  3. var timer = null;
  4. var startTime = Date.now();
  5. return function() {
  6. var curTime = Date.now();
  7. var remaining = delay - (curTime - startTime);
  8. var context = this;
  9. var args = arguments;
  10. clearTimeout(timer);
  11. if (remaining <= 0) {
  12. func.apply(context, args);
  13. startTime = Date.now();
  14. } else {
  15. timer = setTimeout(func, remaining);
  16. }
  17. }
  18. }
  19. function handle() {
  20. console.log(Math.random());
  21. }
  22. window.addEventListener('scroll', throttle(handle, 1000));

最后 

想跟博主交朋友的可以查找,公_号❤:前端老实人,跟博主一起探讨学习哦❤


蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请扫码蓝小助,报下信息,蓝小助会请您入群。欢迎您加入噢~~希望得到建议咨询、商务合作,也请与我们联系。

分享此文一切功德,皆悉回向给文章原作者及众读者.

转自:csdn
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。

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

重新设计东南亚头部在线超市的真实案例

lanlanwork


I. 发现

客户访谈

由于这位甲方的合作态度良好,所以设计师有机会与 SESA 的创始人和产品经理进行了 2-3 次会议。

借此了解了业务目标、用户需求和技术限制等关键问题:

图片

主要问题:

  • 低转化率:杂乱的界面使用户很难浏览商品。
  • 手机端体验不友好:几乎 90% 的用户是通过手机访问网站,但手机版的设计不够理想。
  • 手机端糟糕的界面和体验:目前他们使用的是现有的网站模板,根据目标用户的反馈,缺乏优化而且加载速度很慢。

客户需求

  • 一键式购物
  • 轻松的界面和体验
  • 无缝的商品搜索
  • 折扣和优惠更容易被看到
  • 使用网站时能感觉熟悉而简便

成功指标

  • 增加客单价
  • 增强人们的对品牌的认知感
  • 增加用户和订单数量
  • 无缝的体验
  • 让健康的生活方式更加受欢迎、评价、容易取得,更加有趣而美好
  • 提供并教育用户健康的生活方式,并转化为愉快美好的生活

 

目标人群

根据产品团队提供的数据,整理出了目标人群的特征:

图片

 

II. 构思

人物角色

根据以上信息,整理出了两个完全不同的人物角色:

图片图片

 

故事版

没有区分人物角色的故事版:

图片

目标用户的故事版:

图片

 

体验地图

思考分析用户旅程的五个阶段(探索网站、比较商品、确认下单、完成购买和接收配送)和用户感知的三个方面(行为、思考和感知),制作了体验地图:

图片

将当中的关键信息挑选出来:

图片

 

竞品分析

设计师找到了三家主要竞品,先大概了解他们的特色和优势:

图片图片图片

然后从 Google Play 的评论中寻找竞品的问题,这样就可以思考如何战胜他们:

图片图片

P.S. 评论分析是一种简单有效的竞品分析利器(也可以用来分析自己的产品),具体方法我之前有分享过:别总想着数据分析/用户调研,先把评论分析做了吧!

 

III. 设计

信息导航

先把大致的用户流程确定下来,这样对整个产品就有了一个整体构思:

图片

 

线框图

然后用手画出线框图,定下页面的整体布局:

图片

 

低保真

将线框图手稿用绘图软件细化,制作成低保真方案,用来向客户展示和做用户测试:

图片

图片

 

IV. 完成

可用性测试

找用户做测试时,用的是低保真可交互原型。

根据测试发现的问题,设计师直接将优化方案运用到了高保真方案上,所以下面整理的问题都用高保真方案来配图展示:

  • 1. 自动定位:测试之前用户必须手动搜索位置。
  • 2. 属性选择:由于客户想要一键式购物,所以当用户点击熟悉(通常是重量)右侧的箭头时,可以反转卡片进行详细选择。

图片

  • 3. 促销展示:原本设计了三个促销区,但是测试中发现用户面对大量的信息无法充分理解,所以移除了一部分,只保留了头图和分类优惠。

  • 4. 商品导航:为了避免用户迷路,将商品分类导航放在了所有页面顶部,并且悬停时展示子分类和相关文章。

 

高保真

图片

 

响应式

这个网站需要具备很高的响应式能力,不论在 PC 端还是手机端,都能轻松使用。

但由于 PC 端和手机端的尺寸相差太大了,所以不得不使用断点(Breakpoint)来判断用户当前处在哪个端,并展示相应的界面。

这个断点的概念在栅格系统很常用到,指的是当界面尺寸缩小或增大到某个(或几个)零界点时,间距大小或其它界面元素发生突变。

图片

上图来源:三种最主流的响应式栅格

 

这个方案的对于移动端的特殊处理包括:

  • 确保商品分类的位置,方便用户记忆
  • 使用汉堡菜单
  • 提供模仿原生 APP 的吸底导航

图片

 

Before&After

最后对比一下优化前后的方案:

图片

图片
图片
图片

图片

 

原文地址:体验进阶(公众号)

作者:设计师ZoeYZ

转载请注明:学UI网》重新设计东南亚头部在线超市的真实案例

蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请扫码蓝小助,报下信息,蓝小助会请您入群。欢迎您加入噢~~希望得到建议咨询、商务合作,也请与我们联系。

截屏2021-05-13 上午11.41.03.png

分享此文一切功德,皆悉回向给文章原作者及众读者.
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。

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




UI&UE实用方法论 | 一直被错用的米勒法则(7±2)

lanlanwork


因为「米勒法则」研究的是人类大脑的短期记忆量,而导航菜单、金刚区这些场景,是侧重用户识别,而不是侧重用户记忆。试想你作为用户的时候,你会去记导航菜单的名称吗,哪怕是短暂地记下来(就像我们记短信中的验证码,然后到另一个应用中输入的场景一样,短暂地记住)?我想大部分的人在这些场景中,应该都是所见所得、过眼云烟的吧。

并且“导航菜单的设计旨在用户识别而不是用户记忆”这个观点,在UX研究咨询公司 Nielsen Norman Group(NN/g 尼尔森诺曼集团)的“web可用性”一文中也有指出。

所以以上导航菜单、金刚区的案例,产品可能确实也是有在控制菜单项目的数量,但更多应该是出于对「希克定律」的考量,而不是「米勒法则」(我之前也有在《交互四策略实现希克定律》一文中说过:用户的决策能力会跟随选项数量的增长而降低,给用户非常多的选择,约等于没给用户选择)。

这些案例完全是强行反推,给套了个「米勒法则」的结论…实属不妥…那我就来谈谈,我对「米勒法则」的理解以及它在产品设计中的用途。

 

01、「米勒定律」在研究什么

米勒在1956年《心理学评论》刊中的《神奇的数字7±2:我们处理信息能力的一些限制(The Magical Number Seven, Plus or Minus Two: Some Limits on Our Capacity for Processing Information)》一文中,首次提出「米勒定律」。但该文只算是一篇阐述学术观点的文章,不算严格意义上的论文。

米勒在文中引用了实验者记忆变化音调的实验,发现人们在短时间内可以很好地记忆并复述5~6位的信息,随着收到的信息位数增多,记忆出错的概率也在不断增加。但因为实验者存在个体差异,最终的信息记忆量基本都能在该基础上再浮动2~3位。所以得出了“人的大脑在短期记忆中最多可以记住大约7±2个信息团”的结论。

但因为该实验与文章不属于正式的科研研究和论文,所以后来的科研学者又对“人类短期记忆上限”进行了更多的实验研究,最后形成了很多种学说。有坚持7±2的守旧派;有认为最佳短期记忆信息团为4±1的创新派;也有认为“人类的最佳短期记忆不应该被束缚于一个固定数值区间”的不站队派(确实 NN/g 尼尔森诺曼集团也说过,用户的短期记忆能力存在较大的个体差异,前25%的人群比尾部25%的人群会好大约2.4倍)。

但不论怎么说,这些实验都明确表明了:人的短期记忆存在上限,只是对具体能记住的信息团数量存在分歧。

基于这个结论,我们在设计产品时,该如何加以运用呢?

 

02、在人机交互中的运用

NN/g 尼尔森诺曼集团基于「米勒法则」,提出了以下几则设计指南参考:

  • · 响应时间必须足够快,以便用户在等待下一页加载时不会忘记他们正在做什么;(体验侧)
  • · 更改访问链接的颜色,以便用户不会忘记他们已经单击过哪里;(UI+交互侧)
  • · 不要让用户去记优惠券代码,而是该将优惠信息置入短信或邮件中的链接,通过链接自动将优惠券转移到用户的购物车中。这样可以让计算机承担记住晦涩代码的负担;(交互侧)
  • · 在用户可能需要帮助的场景显示“用户帮助”功能,这样他们就不必前往单独的帮助功能区去记步骤,然后再回来解决手头的问题。(交互侧)

你会发现,实际上专业团队对「米勒法则」的理解,基本都在于如何解决“人的短期记忆上限”问题,并没有去纠结,到底是7±2,还是4±1…

并且我在 NN/g 团队每一条设计指南的后面都标注了该条指南作用的侧重向,发现大多都体现在交互侧。因为「米勒法则」研究的是人的短期记忆极限,在视觉表现层其实很少会运用到。视觉更多强调的是“从识别到操作”,这并不是「米勒法则」的研究内容。

举一些切实的例子吧,基于「米勒法则」而诞生的产品交互中,我们最常接触到的就是移动设备自动获取短信验证码,方便用户一键填充;通过图像识别用户的银行卡号,减轻用户记忆负担。

这一类有关用户短时记忆的场景,为减轻用户记忆负担而诞生的交互形式,才是真正的基于「米勒法则」。

现在你明白了吗?因为「米勒法则」中提到了短时记忆极限量为7±2个信息团,让许多人都去关注数字了,而忽略了「米勒法则」到底在研究什么。然而这个数值,迄今为止,在科研领域依然还存在着分歧。

 

03、关于「米勒定律」的拓展与延伸

3.1 拆解与再组合  

米勒在他发表的文章中也提到了:虽然短时记忆存在上限,但是人们的大脑也总是在努力寻找其他方式拓宽这个极限,例如拆解与再组合。

在前面米勒让实验者记忆变化音调的实验中,就有人通过自主拆解、再组合信息形成信息团的形式,来增加自己最终记住的单位信息数。

基于此,前面图像识别用户的银行卡号的示例,如果因为技术受限而无法实现,我们也可以通过拆解卡号为“4位一个信息团”的方式,来方便用户记忆、输入与校验。这样在体验方面也是一种弥补。

 

3.2 让用户放弃记忆  

要将用户的记忆负担减轻到极限,那就干脆让用户放弃记忆。

例如苹果基于自己的云管理与密钥技术,在识别到用户在创建密码时,会自动填充强密码,强密码复杂混乱到很难被人脑记忆。

一方面加强了密码的安全性;另一方面,搭载其他技术手段来减轻用户的记忆负担,不再纠结于用户究竟能记住多少个、多少位的密码,直接将用户需要记忆的内容减轻至0,这也许才是真正基于「米勒定律」而创造出来的产品设计吧。

 

04、写在最后

其实这篇文章我认为更多是写给交互和体验设计师看的,如果你着手的功能有涉及到用户记忆的场景,不防可以参考一下这些减轻用户记忆负担的案例,还有NN/g的设计指南。

但好像现在「米勒定律」被很多UI设计师用成套路了…然而你发现了吗,文中「米勒定律」的案例,与视觉、与“7±2”很少存在关联。

如果文章开头导航菜单、金刚区的例子,你硬要说是参考了神奇数字7±2,我认为勉强也算行吧(嗯…勉强算)。

因为虽然我认为其设计理论更多是建立于「希克定律」之上的,但「希克定律」告诉我们要减少展示给用户的选项数量,却并没有给出一个建议值。如果你希望在某些场合给你的设计一些立足点(大家懂的),你如果说结合了「希克定律」与神奇数字7±2,我认为比直接说基于「米勒定律」要更内行一些。

 

原文地址:UCD耍家(公众号)

作者:Howiet

转载请注明:学UI网》UI&UE实用方法论 | 一直被错用的米勒法则(7±2)

蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请扫码蓝小助,报下信息,蓝小助会请您入群。欢迎您加入噢~~希望得到建议咨询、商务合作,也请与我们联系。

截屏2021-05-13 上午11.41.03.png

分享此文一切功德,皆悉回向给文章原作者及众读者.
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。

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



v-for的键值key

前端达人

我们现在在使用v-for的时候、都必须会加上一个必要的key值,并且很多人会使用index来作为key,其实这样是不太妥当的一种做法。那么v-for中的键值key到底有什么作用呢。请看:

官方给出的解答

当 Vue 正在更新使用 v-for 渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。这个类似 Vue 1.x 的 track-by="$index"。

这个默认的模式是高效的,但是只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出。

为了给 Vue 一个提示,以便它能跟踪每个节点的身份,从而重用和重新排序现有元素,你需要为每项提供一个唯一 key attribute:


  1. <div v-for="item in items" v-bind:key="item.id">
  2. <!-- 内容 -->
  3. </div>

建议尽可能在使用 v-for 时提供 key attribute,除非遍历输出的 DOM 内容非常简单,或者是刻意依赖默认行为以获取性能上的提升。

举例


  1. <div v-for="(item,index) in list" :key="index"> {{item.name}}</div>
  2. list: [
  3. {
  4. id: 1,
  5. name: "name1",
  6. },
  7. {
  8. id: 2,
  9. name: "name2",
  10. },
  11. {
  12. id: 3,
  13. name: "name3",
  14. }
  15. ]

这个场景如何我们不佳key vue 回直接报错,所以大部分人都会使用index作为key的值

如果我们在添加一个数据


  1. list: [
  2. {
  3. id: 1,
  4. name: "name1",
  5. },
  6. {
  7. id: 2,
  8. name: "name2",
  9. },
  10. {
  11. id: 3,
  12. name: "name3",
  13. },
  14. {
  15. id: 4,
  16. name: "last",
  17. },
  18. ]

此时前面3条数据直接服用之前的,新渲染最后一条数据,此时index作为key没有任何问题

如何我们在中间添加一条


  1. list: [
  2. {
  3. id: 1,
  4. name: "name1",
  5. },
  6. {
  7. id: 2,
  8. name: "name2",
  9. }, {
  10. id: 4,
  11. name: "last",
  12. },
  13. {
  14. id: 3,
  15. name: "name3",
  16. }
  17. ]

此时我们更新渲染的数据 通过index 定义key 进行数据对比一下

之前的数据:

中间插入之后的数据 :

由此可以发现除了第一条数据可以复用以为其余的3条数据都是需要重新渲染,因为key的值发生了变化。

这个时候就可以体现出一个效率的问题,只插入一条数据,却要从新渲染3条数据

所以我们需要可以想办法让数组中不会变化的数据的key值也不变,所以不能通过index来设置key值,应该设置一个唯一的id来标识数据的唯一性;我们修改之后再来对比一下渲染的效率:

之前的数据:

<div v-for="(item,index) in list" :key="item.id"> {{item.name}}</div>

中间插入之后的数据:

 对此对比发现,只有一条数据发生改变,因为其他数据的id 都没有变、所以对应的key也没有发生改变。我们只需要渲染这一条新的数据就可以。 所以一般推荐使用id作为key值配合v-for使用

总结:

Vue很大的一个特点就是双向数据绑定,数据一旦改变,那么页面就渲染新的数据呈现在页面上。但是对于用v-for渲染的列表数据来说,数据量可能一般很庞大,而且我们经常还要对这个数据进行一些增删改操作,而key的出现就是尽可能的回避这个问题,提高效率,如果我们给列表增加了一条数据,页面只渲染了这数据。




蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请扫码蓝小助,报下信息,蓝小助会请您入群。欢迎您加入噢~~希望得到建议咨询、商务合作,也请与我们联系。

分享此文一切功德,皆悉回向给文章原作者及众读者.

转自:csdn
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。

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

JS数组去重的几种方法

前端达人

数组去重

1 双层for循环(类似冒泡排序的双层循环写法)

var arr = [2,3,4,2,34,21,1,12,3,4,1] for(var i =0;i<arr.length;i++){ //第一层:每次循环拿到arr中一个元素 for(var j=i+1;j<arr.length;j++){ //第二层:每次拿到的元素再和每次拿到的元素后边的元素依次进行比对(因为第一个要从第二个开始比,第二个要从第三个比以此类推,所以这里的j应比i大1为j=i+1) if(arr[i] === arr[j]){ //如果相同就删除后边的元素 arr.splice(j,1) } } } //arr:[1, 2, 3, 4, 12, 21, 34] 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

2 循环和indexof、循环和includes

创建新数组,循环旧数组,看每次循环的元素是否存在于新数组中没有就把当前元素添加到新数组中

//indexof var arr = [2,3,4,2,34,21,1,12,3,4,1] var arr2 = [] arr.forEach((e)=>{ if(arr2.indexOf(e)==-1){ arr2.push(e) } }) console.log(arr2) //arr2:[1, 2, 3, 4, 12, 21, 34] 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
//includes var arr = [2,3,4,2,34,21,1,12,3,4,1] var arr2 = [] arr.forEach((e)=>{ if(!arr2.includes(e)){ arr2.push(e) } }) console.log(arr2) //arr2:[1, 2, 3, 4, 12, 21, 34] 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

3 利用对象属性不能重复去重

var arr = [2,3,4,2,34,21,1,12,3,4,1] var obj = {}; arr.forEach((e,i)=>{ obj[arr[i]] = "abc"; }); var arr2=Object.keys(obj) console.log(arr2) //arr2:["1", "2", "3", "4", "12", "21", "34"] var arr3 = arr2.map(e => ~~e ) //arr3:[1, 2, 3, 4, 12, 21, 34] //注意这种方法不仅给数组重新排列而且还改变了数组中元素的类型 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

~是js里的按位取反操作符,~~就是执行两次按位取反,其实就是保持原值,但是注意虽然是原值,但是对布尔型变量执行这个操作,会转化成相应的数值型变量,也就是 ~~true === 1,~~false === 0。

4 ES6 Set

ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

var arr = [2,3,4,2,34,21,1,12,3,4,1] var arr1 = [...new Set(arr)] console.log(arr1) //arr1:[1, 2, 3, 4, 12, 21, 34] 
  • 1
  • 2
  • 3
  • 4

5 ES6 Array. prototype.filter()

注:indexOf在数组中找元素的时候,碰到符合条件的第一个就会把它的下标返回

var arr = [2,3,4,2,34,21,1,12,3,4,1] var arr2 = arr.filter((e,i)=>{ //看每次循环的元素在数组中出现的第一个下标位置(indexOf返回的位置),和每次循环的元素的下标(filter循环每次的i)是否一致,一致就说明他就是第一个符合条件,不会被过滤掉。 return arr.indexOf(e)==i; }) console.log(arr2) //arr2:[1, 2, 3, 4, 12, 21, 34] 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

6 ES6 Array. prototype.reduce()

var arr = [2,3,4,2,34,21,1,12,3,4,1] var arr2 = arr.reduce((pre,e)=>{ //这里当然也可以用indexOf来判断是否存在 pre.includes(e)?pre:pre.push(e); return pre },[]) console.log(arr2) //arr2:[1, 2, 3, 4, 12, 21, 34]

蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请扫码蓝小助,报下信息,蓝小助会请您入群。欢迎您加入噢~~希望得到建议咨询、商务合作,也请与我们联系。

分享此文一切功德,皆悉回向给文章原作者及众读者.

转自:csdn 免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。

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

单色配色你真的会用吗?(实操篇)

lanlanwork


01 单色配色实操

图片

选择基色“H:255 S:100 B:100”的深蓝色为背景。

然后绘制两个正圆,调整底对齐:

图片

图片

图片

大圆颜色调整为和背景相同的颜色,透明度降低至0;调整小圆的颜色,色相(H)和亮度(B)保持不变,降低饱和度(S)为80%。

图片

为了让颜色混合更融洽,给主体执行“效果—模糊—高斯模糊”;再执行“效果—纹理—颗粒”添加质感。

图片

最后添加文案排版,方案一就设计好了。

可以看到本案例精简了色彩层级,色调干净统一且稳定。利用两款同色相颜色的渐变层次变化,产生了低对比度的和谐美感。

图片

使用同样的方法还可以设计出其他方案:

图片

图片

 

02 单色配色实操

第二个方案把英文作为主体。从“视图”菜单中打开“符号”面板,选择英文点击“新建”按钮,把英文设置为新符号。

图片

接着画出圆形外框,执行“效果—3D—凸出与斜角”命令,设定旋转角度和凸出深度:

图片

点击“贴图”进入贴图视窗,勾选“三维模型不可见”,表面选择“4/4”,符号找到新建的英文符号,勾选“缩放以适合”将文字缩放成适合的大小:

图片

背景选择“H:255 S:100 H:100”的深蓝色作为基色。把英文图形执行“对象-扩展外观”,双击进入图形中分别给文字和背景填色,保持色相(H)不变,调整饱和度(S)和亮度(B)的数值。

图片

使用相同的方法制作出其他英文圆环,并填充颜色:

图片

最后加入文字排版,设计完成。

图片

可以看到此方案虽然选择了多个颜色,但通过单色搭配可以得到统一协调的视觉效果。

图片

使用同样的方法还可以设计出其他方案:

图片

图片

 

原文地址:艺海拾贝Design(公众号)

作者:邓海贝

转载请注明:学UI网》单色配色你真的会用吗?(实操篇)

蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请扫码蓝小助,报下信息,蓝小助会请您入群。欢迎您加入噢~~希望得到建议咨询、商务合作,也请与我们联系。

截屏2021-05-13 上午11.41.03.png

分享此文一切功德,皆悉回向给文章原作者及众读者.
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。

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



金刚区也要考虑交互,不只是画图标而已

lanlanwork


金刚区是什么,想必大家都有所了解。

没有的话看这张图就懂了:

图片

图片来源:淘宝首页

 

我在微信上搜了一下,发现大部分讨论金刚区设计的文章,都是在讲怎么画图标。

但是我自己在使用各大 APP 的过程中,发现很多金刚区并不是那么好用,而且这跟图标好不好看无关。

金刚区设计不好,会对我的使用造成直接影响:

  1. 不够清晰易懂根本不想去看
  2. 首次使用找不到需要的内容
  3. 下次使用记不住图标的样子
  4. 图标设计得怪怪的不好理解

我今天就来总结一下,对于金刚区设计的交互/体验思考:

  • 数量
  • 顺序
  • 颜色
  • 样式

 

数量

金刚区里有多少项比较合适?

这其实是米勒法则(Miller’s Role)的典型运用了。

如果你还不太了解米勒法则,看看下面这张图里的词语:

图片

现在,半分钟回忆一下,你记住了多少个?

……

大部分人能记住 5~9 个。

米勒的研究发现,普通人的工作记忆(Working Memory)只有 7±2 个信息块。

如果给的信息超出了这个数字,大部分人也只能记住这么多。

所以说,金刚区里的图标数量,最好也维持在这个数,否则就是对用户的记忆能力要求过高了。

通常来,4 个图标很轻松,说 6 个图标是比较理想的,8~9 个就有点吃力了,10 个就超纲了。

例如支付宝这个就过分了,好在这只是工具类产品,复杂一点也没办法:

图片

 

顺序

人们在看阅读文字时,视线轨迹是之字形:

图片

人们在阅读表格时,视线轨迹是除草机形:

图片

上图来源:这样设计表格,看着真难受!

 

虽然金刚区的眼动图我没有,但第一步肯定是从左上角开始往右扫。

图片

所以,用户最有可能使用的图标,应该从左到右排在最上面一行,最不常用的可以排在右下角。

例如美团外卖这个设计,看着就挺合理。不但把重要内容放在第一行,而且还做了很大的视觉区分:

图片

不过一些不愁流量的 APP 会选择把黄金位置用做商业宣传,难免损失点易用性。

 

颜色

仿真图标

如果追求质感,多半会使用物品本身的颜色,例如每日优鲜这个:

图片

这种图标就没什么颜色好讨论了,注意一下整体和谐就好。

 

数量较少

如果图标数量不多可以使用一个颜色,那么颜色上,同样没什么好讨论的。

例如 QQ 音乐:

图片

 

数量适中

如果图标数量在 7 个左右或以内,那么可以每种颜色的图标都来一个,这样用户也能记住大概什么颜色代表什么。

例如京东这样:

图片

 

数量很多

图标数量远超过 7 时,就不可能每种颜色来一个了,否则颜色都不够用了。

如果还是想要划分颜色,可以将类型作为依据,这样用户在寻找图标时会比较有方向。

当然,其实也可以简单点,干脆都一个颜色,例如联通手机营业厅:

图片

 

样式

底框

一些产品为了统一感,会用圆圈或者圆角矩形,把所有图标都框起来。

这样视觉上是好处理了,但交互上很不推荐,因为会大大降低图标的识别度,眨眼一看都长一样。

这种底框在主流产品里已经很少见了,不过这么做的设计师还是不少,至少站酷上可以找到很多:

图片

这种图标数量少,有颜色区分还好,如果数量多又一个颜色,那就很难辨认了。

 

风格

纵观常见的金刚区图标,通常不外乎四种样式:线条、形状、2D、3D、仿真。

图片

联通手机营业厅

 

图片

QQ音乐

 

图片

京东

 

图片

美团外卖

 

图片

每日优鲜

 

任何样式都能让用户识别和记忆,但是不同的样式给人的感官不同。

真实性越高的视觉样式,就越容易给人高级的感觉;相反真实性越低的视觉样式,越容易给人简单边界的感觉。

 

总结

我发现做设计时,从不同的角度会带来截然不同的思考。

今天这篇分析,算是一个以交互体验为主,融合了一些视觉角度,希望带给大家一些灵感~

如果你还有什么 idea,欢迎在评论区探讨~

 

原文地址:体验进阶(公众号)

作者:设计师ZoeYZ

转载请注明:学UI网》金刚区也要考虑交互,不只是画图标而已

蓝蓝设计建立了UI设计分享群,每天会分享国内外的一些优秀设计,如果有兴趣的话,可以进入一起成长学习,请扫码蓝小助,报下信息,蓝小助会请您入群。欢迎您加入噢~~希望得到建议咨询、商务合作,也请与我们联系。

截屏2021-05-13 上午11.41.03.png

分享此文一切功德,皆悉回向给文章原作者及众读者.
免责声明:蓝蓝设计尊重原作者,文章的版权归原作者。如涉及版权问题,请及时与我们取得联系,我们立即更正或删除。

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


日历

链接

blogger

蓝蓝 http://www.lanlanwork.com

存档