首页

【一分钟阅读】关于组件化,我有一些小建议

seo达人

随着公司项目多端化,开发所需要注意的细节越来越多。我在会议上提出组件化开发,希望能把业务细节与技术细节区分开来。



 一、组件化流程

首先我们需要找到切入点,我采取的是通过模仿element-ui的组件,先让我们美工小姐姐,照着element的组件库描绘一版我们自己的组件,内容包括 颜色、字体、按钮、图片 等基础UI组件。这就是我们组件化第一步,UI 组件形成。



其次是业务组件的补充,这方面我和项目经理还有其他前端一起商讨,将跨场景跨页面同样效果的部分给抽象成组件。组件化第二步,业务组件形成。



然后就是漫长的更迭与组件补充。



二、组件化细节处理

2.1 全局文件布置

无论是UI组件还是业务组件,都包含着class与css。



变量值我选择存放在两个公共文件内:



一个负责管理class名,诸如 x-btn-s,x-btn-m,x-btn-l,x-pic-s,声明规则:公司名-组件名-尺寸(业务场景)。



另一个负责管理 css 变量值, 诸如 $-font-s: 12px,$-font-m:16px; $-font-l:24px;$-background-warn: #f00;声明规则:$-相关样式-大小(颜色)。



再通过 exports 与 import 对全局文件进行调用。



2.2 组件的多样化使用

通过全局文件的配置,我们对组件的调用从一对一调用变成了一对多调用。如下:



使用全局变量前,我们只能通过以下形式调用



<x-button/>

现在我们可以通过:class的形式调用<x-button/>的多种形态,如下:



<x-button type="$-x-btn-warn' size-'$-x-btn-s'>注册</x-button>

当然,我们还需要在组件内部定义好:class部分,配置如下:



<template>

  <button

    class="x-button"

    :class="[

      type ? 'x-button--' + type : '',

      buttonSize ? 'x-button--' + buttonSize : '',

    ]"

  >

  </button>

</template>

<script>

  export default {

    name: 'XButton',

    props: {

      type: {

        type: String,

        default: 'default'

      },

      size: String,

    },

  };

</script>

2.3 slot 插槽的配置与使用

合理使用 slot 插槽,例如:组件内嵌组件,组件内嵌文字,内嵌 iconfont 等;



三、 组件的配置

在 app.js 中使用 vue.use(components) 对组件进行配置,再在相关页面进行引用。

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

jQuery与Ajax:“特别的”load()方法(筛选文档、传递方法、回调函数)

seo达人

“大名鼎鼎的”jQuery因为其极简的引用方式而在N年前备受追捧,而今“浪潮”过去,还剩下什么?

我认识jQuery,只是在去年接触ajax时了解,从而感兴趣,进而深入探究(其实也没多深入,只是相关的看了一下)。不得不说,jQuery对ajax支持的四个type:post(一般用于发送)、get(一般常用于接收)、put(修改)、delete(删除) 令我非常震撼,太**实用了。

这其中,post和get是最常用的(因为好像说不是所有的浏览器都支持put和delete),具体的我在 这篇文章 中以JS方式提到,这里不再赘述。



load()

load()方法时jQuery中操作上最为简单的Ajax方法,能载入其他的HTML代码并插入到DOM中。其基本格式为:



load(url [,data] [,callback])

1

参数意义:



url: String类型,请求HTML页面的URL地址

data(可选): Object类型,发送至服务器的key/value数据

callback(可选): Function,请求完成时的回调函数,无论请求成功或失败

为什么说它是“特别的”呢?因为它只用于文档流(html)的操作,而且,既可以是get操作,又可以是post操作:



基本示例:



//如果是jsp代码,这里要加一行:

// <%@ page contentType="text/html;charset=UTF-8" language="java" %>

<html>

<head>

    <title>请求的文件</title>

</head>

<body>

    <div class="comment">

        <h6>张三:</h6>

        <p class="para">沙发</p>

    </div>

    <div class="comment">

        <h6>李四:</h6>

        <p class="para">板凳</p>

    </div>

    <div class="comment">

        <h6>王五:</h6>

        <p class="para">地板</p>

    </div>

</body>

</html>



//如果是jsp代码,这里要加一行:

//<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<html>

<head>

    <title>发送ajax的文件</title>

    <script src="js/jquery-2.1.0.js" type="text/javascript"></script>

    //如果是jsp代码,上面这一行要换成:<script src="<%=request.getContextPath()%>/js/jquery-2.1.0.js" type="text/javascript"></script>

    <script type="text/javascript">

        $(function () {

            $("#send").on("click", function () {

                $("#resText").load("test.jsp");

            });

        });

    </script>

</head>

<body>

    <input type="button" id="send" value="Ajax获取">

    <div class="comment">已有评论:</div>

    <div id="resText"></div>

</body>

</html>



上面是“载入文档”,它还可以“筛选载入的文档”:

如果只需要加载某页面内的某些元素,那么可以使用load()方法的URL参数来达到目的。通过为 URL参数 指定选择符,就可以很方便地从加载过来的HTML文档里筛选出所需要的内容。



load()方法的URL参数的语法结构为:“url selector”。注意,URL和选择器之间有一个空格:



$(function () {

    $("#send").on("click", function () {

        $("#resText").load("test.html .para");

    });

});



传递方式:

load()方法的传递方式根据 参数data 来自动指定。如果没有参数传递,则采用GET方式传递;反之,则会自动转换为POST方式:



//无参数传递,GET方式

 $("#resText").load("test.html .para", function(){

//....

});

//有参数传递,POST方式

 $("#resText").load("test.html .para",{name:"tom", age:"18}, function(){

//....

});



回调函数:

对于必须在加载完成后才能继续的操作,load()方法提供了 回调函数 ,该函数 有3个参数 ,分别代表请求返回的内容、请求状态和XMLHttpRequest对象 ,jQuery代码如下:



 $("#resText").load("test.html", function(responseText, textStatus, XMLHttpRequest){

//responseText:请求返回的内容——等同于js-ajax时的“得到服务器响应的文本格式的内容”(注意:js操作中的get、post...都在open()中规定)

//textStatus:请求状态:success、error、notmodified、timeout4种

//XMLHttpRequest:XMLHttpRequest对象——这玩意一般用在判断浏览器适用类型上

});

//注意:在load()方法中,无论Ajax请求是否成功,只要请求完成(complete)后,回调函数就被触发。

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

JS基础知识整理06-函数

seo达人

使用function关键字定义函数

函数声明会被提升(Hoisting),将声明移动到当前作用域顶端的默认行为。



参数:

如果函数调用的参数太多(超过声明),则可以使用函数的内置对象arguments

arguments.length 会返回函数被调用时收到的参数数目

arguments[index]可以得到相应的参数



传递对象的时候是使用引用来传递的,如果函数修改了对象属性,则原始对象也改变了。





调用:

以函数形式调用函数:(这种方式调用默认的是全局对象调用)

function myFunction(a, b) {

return a * b;

}

myFunction(10, 2);



作为方法来调用函数:(这种方式调用属于函数的拥有者myObject)

var myObject = {

firstName:"Bill",

lastName: "Gates",

fullName: function () {

return this.firstName + " " + this.lastName;

}

}

myObject.fullName(); 



通过函数构造器来调用函数:(如果函数调用的前面是 new 关键字,那么这是一个构造函数调用)

function myFunction(arg1, arg2) {

this.firstName = arg1;

this.lastName  = arg2;

}

var x = new myFunction("Bill", "Gates");

x.firstName; 



call()和apply()方法:

var person = {

fullName: function() {

return this.firstName + " " + this.lastName;

}

}

var person1 = {

firstName:"Bill",

lastName: "Gates",

}

var person2 = {

fullName: function(city, country) {

return this.firstName + " " + this.lastName + "," + city + "," + country;

}

}



call() 方法是预定义的 JavaScript 方法。

它可以用来调用所有者对象作为参数的方法。

通过 call(),您能够使用属于另一个对象的方法。

如:

person.fullName.call(person1)// person1来调用person的fullName方法



call()可以带参数,参数对应按顺序的传给方法

person2.fullName.call(person1,"Seattle", "USA")



apply()方法和call()方法类似

区别在于接收参数的方式不一样。

call(obj,"x","y") 方法分别接受参数

apply(obj,["x","y"]) 方法接收数组形式的参数





箭头函数:(ES6)

箭头函数不需要function关键字、return关键字和大括号

var x = function(x, y) {

  return x y;

}



var x = (x, y) => x
y;

两个的作用相同。



箭头函数没有自己的this、如果函数是单个语句,则只能省略 return 关键字和大括号

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

Hibernate--使用离线查询DetachedCriteria完成对列表的筛选

seo达人

User表:





User类:

package pers.zhang.domain;



public class User {



private Long user_id;

private String user_code;

private String user_name;

private String user_password;

private String user_state;

public Long getUser_id() {

return user_id;

}

public void setUser_id(Long user_id) {

this.user_id = user_id;

}

public String getUser_code() {

return user_code;

}

public void setUser_code(String user_code) {

this.user_code = user_code;

}

public String getUser_name() {

return user_name;

}

public void setUser_name(String user_name) {

this.user_name = user_name;

}

public String getUser_password() {

return user_password;

}

public void setUser_password(String user_password) {

this.user_password = user_password;

}

public String getUser_state() {

return user_state;

}

public void setUser_state(String user_state) {

this.user_state = user_state;

}

}



ORM元数据:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC 

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"&gt;

<hibernate-mapping package="pers.zhang.domain" >

<class name="User" table="sys_user" >

<id name="user_id"  >

<generator class="identity"></generator>

</id>

<property name="user_code" column="user_code" ></property>

<property name="user_name" column="user_name" ></property>

<property name="user_password" column="user_password" ></property>

<property name="user_state" column="user_state" ></property>

</class>

</hibernate-mapping>



控制层:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

request.setCharacterEncoding("utf-8");

//获得查询参数

String userIdStr = request.getParameter("userId");

String userName = request.getParameter("userName");

//获得离线查询对象

DetachedCriteria detachedCriteria = DetachedCriteria.forClass(User.class);

//拼装查询条件

if(userIdStr != null && !"".equals(userIdStr)) {

Long userId = (long) Integer.parseInt(userIdStr);

detachedCriteria.add(Restrictions.eq("user_id", userId));

}

if(userName != null && !"".equals(userName)) {

detachedCriteria.add(Restrictions.like("user_name", userName, MatchMode.ANYWHERE));

}



//作为参数传递给service层

UserService userService = new UserService();

List<User> list = userService.findUserByCondition(detachedCriteria);



request.setAttribute("userList", list);

request.getRequestDispatcher("list2.jsp").forward(request, response);

}



Service层:

public List<User> findUserByCondition(DetachedCriteria detachedCriteria) {

//传递给Dao层

UserDao userDao = new UserDao();

return userDao.findUserByCondition(detachedCriteria);

}

1

2

3

4

5

Dao层:

public List<User> findUserByCondition(DetachedCriteria detachedCriteria) {

Session session = HibernateUtils.openSession();

Transaction tx = session.beginTransaction();



//关联session

Criteria criteria = detachedCriteria.getExecutableCriteria(session);

//查询

List<User> list = criteria.list();

return list;



}



前端页面:

忘记写查询数据回显了…



<%@ page language="java" contentType="text/html; charset=utf-8"

    pageEncoding="utf-8"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title></title>

<script type="text/javascript" src="js/jquery-2.1.0.js" ></script>

<script type="text/javascript" src="js/bootstrap.min.js" ></script>

<link rel="stylesheet" href="css/bootstrap.css" />

</head>

<body>

<form class="form-inline" role="form" method="post" action="${pageContext.request.contextPath }/findUserByCondition">

  <div class="form-group">

    <input type="text" class="form-control" id="exampleInputEmail2" placeholder="用户ID" name="userId">

  </div>

  <div class="form-group">

    <input type="text" class="form-control" id="exampleInputPassword2" placeholder="用户名" name="userName">

  </div>

  <button type="submit" class="btn btn-default">筛选</button>

</form>



<div style="text-align: center; width: 600px;">

<table class="table table-hover">

  <tr><td>编号</td><td>用戶ID</td><td>用户名</td><td>昵称</td><td>密码</td></tr>

  <!-- 显示数据 -->

  <c:forEach items="${userList }" var="list">

  <tr><td>${list.user_id }</td><td>${list.user_code }</td><td>${list.user_name }</td><td>${list.user_password }</td><td>${list.user_state }</td></tr>

  </c:forEach>

</table>

</div>





</body>

</html>



测试:



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

聊聊那些拥有“边际效应”的产品

雪涛

讲述边际效应对应不同线上线下产品的不同状态以及优势

现如今对于大多数的互联网产品来说,其实都大致会用到“边际效应”这个概念,在看似华丽渲染的互联网背后,真正支撑着的是对人的深刻认识与理解。当然,现如今的产品很多都有规律可循,包括商业模式、变现方式等等,那么这次我们就来说说那些在互联网中产品的边际成本递减效应的设计。



边际成本

首先呢,在这里我要先为大家解释一下何为边际成本。

从概念性角度解释:边际成本指的是每一个单位新增的产品(或购买的产品)所带来的总成本增量。

( 举例 )

比如说现如今的共享单车,在仅生产第一辆的时候,其公司花费的成本是极大的,它包含:设计费、电话费、路程费、人工费等等等等……但是,在生产第100辆的时候,小车儿的成本就低很多了,再不创新的前提下,只要复制就可以了,而如果在生产第1000辆的时候,那成本就更低了,这就是经济规模带来的效应。那么,同样的复制,为什么越复制越便宜呢?其实,这里面有一个对等的增产量对比,由于小车数量的增多,遍布区域的扩大,所以,也就导致公司的机会成本增高,也就是成本更低,所以,考虑边际成本递减的同时,也要考虑机会的增多。



边际成本递减

刚才说到的其实就是边际效应里成本递减的模式,也是我们这次讨论产品的核心,所谓的边际效应递减,就是指在其他条件不变的情况下,如果一种投入要素连续的等量增加,当增加到一定产值后,所提供的产品增量就会下降,同时可变要素的边际产量就会递减。


我在举个例子:日常的滴滴打车,就是递减的模式,因为滴滴大多数的供给侧平台用户就是私家车出来接单,所以,当平台每多接入一辆车,那么对于滴滴平台来讲边际成本就越趋于零。

其实,类似于滴滴打车这样的线上+线下的资源整合性平台,更加符合互联网的经营模式,这是因为互联网在21世纪,就是以免费为前提的,随着用户的增多,边际成本的下降,无非就是在完善经营的条件下,多开一些服务器和宽带罢了,其他的成本几乎已经可以忽略不计,而这也正是互联网产品成为霸主的必要因素之一。


    注(供给侧:经济学术语的一种,意思是指供给方面,国民经济的平稳发展取决于经济中需求和供给的相对平衡。 供给显示了随着价钱升降而其它因素不变的情况下,某个体在每段时间内所愿意卖出的某货物的数量。在某一价格下,消费者愿意购买的某一货物的总数量称为需求量。在不同价格下,供给量会不同。供给和需求也就是说价格与需求量的关系。若以图像表示,便称为供给曲线。)



边际成本的线下产品案例


奶茶案例

在我们逛街购物时,几乎都会买一杯奶茶饮品,而这里面就运用到了边际效应的负效应模式,他们运用第二杯半价的手段来提升消费者对产品第一次的贪婪程度,也就是“欲望值”,同时也提升了产品的销售,但边际成本不变,当消费者购买后,负效应可能就会产生,因为消费者不一定能喝完。这里就体现的是商品价值取决于人的欲望和欲望被满足的程度比例。



服装案例

再比如商场内大牌服装都写着全场8折,其实仔细想想,8折的价格真的很划算么?他们这么做也同样是在运用了边际效应的同时调取了消费者心理的欲望值,在消费者第一次购买时,单纯考虑的爽点而非负效应,但随着商品购买完的数量,才真正会产生负效应。



电影票案例

还有一个是关于电影票的,我的一个朋友会经常去看电影,之前去看电影的时候是在现场买的票,那次售票员给他推送了一个非常超值的套餐,就是单买一张票是原价48元,但是近期有一个限量套餐,这个套餐里包含:5场电影+1桶爆米花,价格是149元,但是需要一次性消费,听起来是不是非常超值?我的朋友考虑反正也没事,那就多看几场,还便宜。但是如果按照边际成本递减与负效应来讲,这绝对是一件亏本的买卖,谁能一直做着看十几个小时的电影不走?我想电影院也一定有这样的数据才会推出这样的套餐吧。但随着消费者购买人数越多,边际成本递减,其他人也会纷纷模仿,这里面包含一个人类固有的“羊群效应”,也就形成了商业价值,但随着消费者看电影时间的延长,负效应也随之而来。


    注(羊群效应:羊群效应理论,也称羊群行为、从众心理。经济学里经常用“羊群效应”来描述经济个体的从众跟风心理。)



边际成本的线上产品案例


微信

首当其冲的,自然是微信了,这个传奇产品堪称边际成本做的最好的一个,在我们之前都是运用短信电话的时候,每发一条短信,每打一个电话都要考虑不同的费用,但由于微信的出现,极大的解决了用户的这个痛点,微信已最核心的打字聊天、语音/视频通话为主要支点,并赋予各种特色产品辅助。在微信最大化的边际成本趋于零的同时,迅速扩大了用户使用产品的范围区,所以,作为互联网的边际成本,我想微信的在这方面确实做的很好。



GoFun出行

这款产品为共享汽车类型,属于线上+线下产品,Gofun出行的边际成本做的比较合理是,首先是他的供给侧能力较足,因为依托了首汽集团的优势资源,极大的降低了边际成本,并通过对用户的日常作息将碎片打车时间、坐公交时间、出游时间等需求作为整体分析,提供了这一种出行服务,并且现在的产品里还融合了长时间租车服务,这就极大的又一次挖掘了一批潜在用户,在边际成本递减并趋于零的同时,反响的用户群体范围也在逐渐扩大。同时这个产品还在登陆时跳出有广告提示,“分享可得免费时长开车券等优惠”,这种手法也是除了在边际成本递减的同时,运用的用户酬赏机制,目的是通过用户引流用户。



摩拜单车

在文章开篇的时候我拿共享单车举过例子,其实摩拜单车的性质与共享汽车的性质大体一致,主线路相似程度可达到80%,这里我要和大家说一个定律,关于用户的定律。当产品开发者抓区并成功解决掉某几种目标用户的痛点后,其相等模式可无限制复制,并形成范围值生产从而解决掉这几种用户对等的群体用户痛点。

我给大家举个例子应该就彻底明白了,就像医药行业诊断,当医生遇到一种从未遇见过的病毒时,其第一次需要花费的成本是极其昂贵的,但只要一旦得到解决,那么当再次遇到同类型病毒时,就可以快速复制解决,其边际成本迅速降低,反之收益增高,同时同类型病毒则可批量解决。共享汽车和单车产品正是边际成本与复制的这一体现。




总结

边际成本在20世纪时是非常难得的一个概念,因为在20世纪的成本里,几乎都是建立在“原子经济”上的,而直到21世纪互联网形体的出现,边际成本将真实的成倍数下降,这是因为21世纪的成本发生了转移,建立在了“比特经济”上。

所谓原子经济的本质就是需要以大规模生产取胜,它所遵从的是绝对的单一化、标准化、格式化创造。这种创造,并不能形成边际成本的递减,甭别说是趋于零,它需要的是逐渐递增服务,就像和滴滴打车对抗的线下出租车,随着消费者的增多,它能做的不是整合,而是新增出租车和司机进行匹配,如果不加入互联网行业,他们将很难维持下去。


而比特经济,则正好是多元化、个性化、小众化、扁平化的。它所崇尚的就是一种主客一体、多元共生共存的理念、可以使使用者分享满足感和快乐感。这样的好处是在快速扩大用户群体区值的同时还能使边际成本下降。



文章来源:站酷


本质思考是产品创新的基础

雪涛

不知道从什么时候我开始 对“创新”这个词感到些许乏力和恐惧,开始思考为什么有些人能看透问题本质?于是有了本文的探索和总结。

平时我们大部分时间都在做一些“应激反应”的事情,经常处于“被安排”的情况下,大脑逐渐懒得去思考背后的东西,通常根据自己的主观意愿做出一些反应。慢慢依赖一些“道听途说”而来的方法论来做一些事情,“套用”效果也不理想。

有一定履历的产品经理多数也会迷上“经验论”。

  • 迷上自己过往的经验,“我以前做这活动就是用这个策略的,效果很不错”。
  • 迷上他人的经验,“那天和老同学吃饭,他们这个裂变做得不错,我们也搞一个”
  • 迷上竞争对手的经验,“它们的狙击枪也有这个功能,我们也加一个”。

种种行为都是没有通过本质思考的行为表现,都是一些脉冲式的思考。别人做什么 ,我们也跟着去做,只能在这个行业里面产生细微的迭代,无法实现真正的创新。

关于创新,埃隆马斯克引爆了一个概念,回归到事物本质,看透问题本源的思维叫“第一性原理”,它不是一个定律也不是真理,而是一种思维模式。

我先不解释到底什么是第一性原理,因为本来就处于蒙圈的情况下再去看一些专业的解释就会更加蒙圈。

下面分享一个故事,一起来了解一下本质思考这种思考方式,抛开哲学、生命、宇宙本质,围绕“抢域名”这件事,主角蔡文胜是如何将域名抢注成功率从十万分之一变成50%以上?他到底是怎么做到及如何思考的。

背景:fm365.com注册于1999年10月21日,因忘记续费,到2003年10月21日过期,当时这个网站是联想重金打造的门户网站流量非常可观,当时可能有10万人要想抢注这个域名。

想抢注域名的人都知道域名释放时间是在2003年10月21日,但很多人没有做好基本的调研与了解,不同域名服务商释放时间不一样,有些是次日0点,有些是30天,所以当时大部分人都不知道这个具体域名掉落时间,实际上这个域名掉落时间是在70天之后。

那么知道了域名掉落的具体日期, 也不可能一整天都去注册抢注, 还需要知道具体时间才能抢注成功,而事实上当时这个域名在美国一个域名商手上,所以掉落时间是在美国的中午12点,对应中国是凌晨3点,在那个时间点域名才完全掉落。

那么问题来了,知道了最后具体掉落日期和时间,怎样才能脱颖而出,成为那个唯一一个能把域名抢到的人?

蔡文胜做了以下4件事:

第一件,首先注册域名上所有信息、 名字、邮箱等字段事先填好 ,这个过程大概需要5秒钟, 然后直接按f5就可以了,只要1秒不到,就能提交注册信息。

第二件,蔡文胜当时查了一下这个网络请求到底是怎么走的,发现这个请求是先从厦门连到上海,上海连到美国,请求的路径非常长,当时在2003年网速还是非常的慢,所以蔡文胜索性租了一台上海的服务器,直接从上海连到美国,这样至少在中国理论上是最快的。

第三件,节省注册资料字节长度,把88888@qq.com改成 1@1.com,因为这信息回头也可以修改,压缩后比完整的信息要少几百个字节,这样加快提交速度,又提高成功率。

第四件,当时据说抢注这个域名的人有10万人,蔡文胜预估有大概前面3件事能淘汰掉90%的人,还和剩余10%的人进行竞争,所以还是不能保证能够注册并抢注成功。最后蔡文胜搞了一个自动点击脚本,每秒提交1000次。最终蔡文胜从10万人里面脱颖而出,成为唯一一个抢到域名的人。

回归到抢域名这件事的本质上,把域名开放时间设为T0,提交信息到域名服务器的时间设为T1,使T1-T0的时间最短就能抢注成功。

看完上面的故事,回归产品人如何训练/培养自己的本质思维。

01 摆脱原有思维惯性

每个人都有一定思维惯性,看到事物会下意识的做出一些反应。

在《思考,快与慢》书中的知识叫“快系统”,人会本能直觉迅速做出一些判断和反应,这套系统好处是大脑反应非常快,功耗低还”省电“。

所以我们一旦意识到自己在用过往或他人、竞争对手等经验时先打住,不是说不能用,而先思考这些“经验”对现在是否真正能用上。

每个人都有自己对主观意识,特别是产品经理这个岗位主观意识真的太强了。在数据报表或调研结果上看到一批数据会带上自己的主观想法来解释这一批数据原因。

摆脱原有的思维惯性应该启动大脑的“慢系统”,慢系统需要调动我们的逻辑思维等能力,一旦启动逻辑思维能力周期很长,启动很慢很费力,所以我们日常那么多事情处理的时候,没有什么时间去切换慢系统,所以会造成前面所说的应激反应。

当然我们也非常难做到每次都使用“慢系统”来解决问题,大脑处理不过来,头发也坚持不住,但我们可以锻炼出好的思维方式,让自己思考时不轻易的跑到原有的思维惯性去。

02 成为“问题少年”

蔡文胜在抢注FM365这事上就是不断追问自己,“我还能不能更快一点?”、“我怎样才能比别人更快抢到!”、“如何将请求路径变短?”、“怎样才能提升请求速度?” 从解决问题的路径上,根据目标一层一层的不断的对自己发问,最终这些问题都会迎刃而解。

有问题请教别人也是突破思维惯性的好方法,抛开对错,观点过滤,交流时可以认真听但不要照着做,和老板给你提需求是一个道理。问题方和解决方看到的视角都是不一样的,利于思维开阔。

03 在实践中获得反馈

“实践”指的洞察已发生的事物做出自我思考的问题和想法、比如在“产品分析”环节重点研究下对方可能接下来会做些什么事,预估做了会产生哪些结果?当前的业务形态为什么会这样设计?

总之产品方法论有时候并没有那么重要,最重要的不是学习别人的方法论,而是通过自己的本质思考,不断总结出自己的方法论,有意识的去训练自己的思维习惯,养成思维模型,这对产品经理才是重要的事情。

文章来源:人人都是产品经理

复杂问题该用理性决策还是感性决策?

雪涛

一、明知识、默知识与暗知识的四象限图

AI被热捧那么久,王维嘉博士的《暗知识》是第一本把它讲明白的中文科普书。

这本书第一个知识框架,就是下面这张4象限图:

思考方式的革命(一)复杂问题该用理性决策还是感性决策?

(该图来自:王维嘉的《暗知识》)

该图将知识按“是否可表达”、“是否可感受”的两个维度分为四类:

  • 可表达的“明知识”(包括可感受的牛顿定律和不可感受的量子力学)
  • 不可表达但能感受到的“默知识”
  • 而“暗知识”则是:不可表达、又没法感受到。

具体来说,暗知识是机器发现的,人类无法感受也无法表达的知识。

就像围棋,人类2000年来保留的棋谱大概有3000万个(8位数),但围棋上棋子的摆放方法的可能性有2的361次方个(108位数),中间何止相差万亿倍。人类对围棋的认知,就是基于3000万这个8位数范围的认知。与机器相比,相差10的100次方。这部分机器能掌握而人不能的,就是暗知识。

这是本书让人惊叹的第一个点,通过设立一个新的二维坐标模型,就能够找到人类以往概念上的盲区!其次,王博士选的词汇也是超一流的,“暗”和“默”两个字都很有神采。

虽然是“科普书”,但书里还是不得不讲到人类的“神经网络”、计算机的“机器学习”、“卷积”等复杂概念。

我用自己的语言,以“识别一只猫”为例,为大家简单讲述一下AI吧:

(1)识别猫与计算“1+2=?”不同,前者是“默知识”—— 无法用准确的语言描述出来。在计算机历史上,通过“尖尖的耳朵”、“长尾巴”、“圆眼睛”等信息来识别猫的程序都失败了。

(2)我们闭上眼睛想想,如何把一只猫与一只豹子的照片区别开,需要补充很多语言描述。把一只猫与一只狗区别开,又需要补充一些描述,其实人是不能把“识别一只猫”这件事情用语言明确说清楚的 —— 既然人说不清,传统计算机程序就做不到。但人,哪怕是三岁的孩子都能区别猫和狗,背后是什么原理呢?

(3)后来科学家通过研究人类大脑的神经网络,发现大脑是通过分层判断,最终在神经元中留下“历史痕迹”的逻辑链条的。这是很有趣的生物学现象,一个神经元受到的刺激(生物电击)越多,得到的营养就越多、就会成长得越强大。而每次判断在每层神经元中留下的痕迹,就会强化今后整个人脑神经网络的判断能力。

(4)计算机科学家根据对人类大脑神经网络的认识,开发了计算机“神经网络”。这个网络不但可以识别“猫”,而且识别猫的过程也同样无法输出成为人能认识的“文字描述”。

(5)这些识别算法就沉淀在“神经网络”中(表现为数据及数据关系),无法被人类直接掌握,人只能通过安装了神经网络的计算机获得这个能力。

(6)不知大家注意到没有,为了让计算机解决这个“默知识”的问题,我们最终是用了“暗知识”来解决。

(7)这类“暗知识”,能够在计算机之间快速复制,但无法在人和人之间复制,人和人之间能传递的只能是控制AI计算机的方法。

暗知识大体说完,我再回到与我们的思考方式相关度更高的“默知识”。

二、《思考,快与慢》的“系统1”

《思考,快与慢》这本书大约是我2013年读到的,我认为这是那一年我读到最好的书。好就好在研究老对象(人类行为与注意力)的过程中,用了新思考框架,并建立了有说服力的体系。

几年来,这本书被我放在电脑显示器下面,意喻为“抬高了我的视野”。当然,最初是为抬高了显示器,起到保护颈椎的作用。

思考方式的革命(一)复杂问题该用理性决策还是感性决策?

书里是这样定义人的两种思维模式的:

  • 系统1 —— 其运行是无意识且快速的,不怎么费脑力,没有感觉,完全处于自主控制的状态。例如会骑自行车的人,他在骑车时是不需要主动意识指挥手如何转动车把的,系统1会接管这些动作。
  • 系统2 —— 将注意力转移到需要费脑力的大脑活动上来。例如:大家可以回忆一下自己第一次骑自行车的场景,当时是需要非常专注地控制双手和双脚的,所以往往手忙脚乱。我记得我如果稍不能控制,双手是会放掉车把,抱住旁边的足球门柱的不知各位刚学自行车时,是否也是如此?

当系统2学习掌握了重复使用的套路后,大脑会将重复工作转给系统1。

我高中时,经常因为简单的数学加减乘除四则混合运算错误,导致考试得不到高分。我训练自己做了大量专项练习,后来不仅计算过程不出错,而且感觉当时是把简单的四则运算从“系统2”挪到“系统1”了。考试时,手上做着乘法竖式,脑子里考虑是否有更好的解题思路。

从另一个角度看,大脑的重复套路工作从“系统2”转给“系统1”,还有一个更大的好处 —— 降低能力消耗。

系统1反应很快,对能量的消耗远低于系统2。我查了《人类简史》、《文明是副产品》等书籍,看到这样的资料:晚期智人的大脑占体重的1/20,但耗能、耗氧量却达到全身的1/5。在工业革命前的5万年里,智人供养这样一个大脑是极其不容易的,所以我推断:

  • 第一,大脑不会有大比例未开发区域,因为咱们的大脑结构在5万年前成熟时(今天人的脑容量与5万年前差别不大),人体根本没有多余的营养可以供它浪费。
  • 第二,从机制上,大脑会尽量把一些套路工作从系统2转给系统1,以期降低脑力消耗。

系统1毕竟简化了判断过程,是否会造成很多误判呢?我相信是的,但因为能量的限制,人类当时应该是找到了中间最优解。

我认为:《思考,快与慢》的“系统1”,学习的其实就是前一节说的“默知识”。

还是以骑自行车为例,咱们可以教新手一些保持自行车平衡的要领,但一个新手学会骑车的过程,是实践重于理论的。最后形成的知识,就是无法说清的“默知识”,这个默知识保存在我们每个人的“系统1”当中。

当然,系统1与系统2的关系还有很多层次,并对人类社会产生了深远影响。

例如:遇到紧急情况时(“快撞到行人了”),系统2会从系统1接管人体控制权,多费一点脑力控制好自行车的方向,避免造成交通事故。

毕竟我的读者都是toB企业同事,我还是讲一个书中与咱们业务有关的故事。作者丹尼尔·卡尼曼是诺贝尔经济学奖获得者,21岁时(1955年)曾经在以色列军队里负责设计士兵面试流程。这之前,面试官完全根据感觉打分,结果筛选出来的新兵合格率很低。卡尼曼做了一套设计,听起来和我在《SaaS创业路线图(六):如何扩张团队?》中的做法类似,就是要求面试官严格按框架打分。

思考方式的革命(一)复杂问题该用理性决策还是感性决策?

思考方式的革命(一)复杂问题该用理性决策还是感性决策?

(上图为我系列文章(六)中提供的打分表)

卡尼曼不是他的面试官们的上级,面试官们不喜欢做“打分机器人”。卡尼曼的让步是,同意面试官根据标准格式打分后,最后“闭上眼睛给士兵打个总分”。

最后的结果是,新的测评方法大幅提高了有效率。45年后卡尼曼回到该部队,发现他的面试方法还在延用。

而我的面试表最后也有这样一行:“自己是否愿意带领此人去完成一个困难的任务?”其实这是一个非常感性的问题,与表格其它部分(记录工作年限、记录回答情况等)非常不同。

我观察,这就是在很多领域中,决策复杂问题的一个优选方法:

  1. 把抽象问题具象化:先用理性框架(“明知识”)、从多个角度用数字化的方法分项打分;
  2. 再把具象问题抽象化:从内心出发,我是否要用这个人?(使用了“默知识”:更感性,但往往更准确)

这个过程的好处是:

  1. 过程可操作性好,让决策者全面思考,不会漏项;
  2. 利用决策者的抽象判断能力(“默知识”),更高纬度地做出判断,不会因为打分表的设计缺陷造成决策错误。

我们企业决策中,如果死板地使用调查前设计的“打分表”,往往会错过发展机会。因为环境在剧烈变化,调查前很难做出完美的打分表。而“默知识”会让我们熟悉业务的决策者更准确地做出判断。

三、内隐学习和外显学习

上面说了很多“默知识”的例子,具体怎么学习和使用“默知识”呢?最近“得到APP”的精英日课正好也推出了一篇文章“内隐学习和外显学习”。

简而言之,外显学习就是学习“明知识”的过程,掌握历史知识、化学公式……

内隐学习,则是学习“默知识”的过程,学到的是个“感”。例如:英语的语感。

1993年高考时,记得我的英语成绩大约是140分(满分150)。因为不考口语,这全都是英语语法和单词,大多是“明知识”。

但我工作后能在外企说流利的英文,全有赖于大学时在华中理工(现在的华中科技大学)有一个教“外贸英语”的廖老师。他逼着我们每人整篇整篇地背诵外贸英语,上课经常现场考对话,当时那个厌恶哪……没想到坚持了一个学期,死记硬背了几百句常用对话后,英语“语感”就形成了。大脑中可以用英文思考问题,我是一生受用。

“精英日课”引用的一个调查研究还有个有趣的结论:外显学习明知识,注意力越集中越好;但集中注意力反而会妨碍内隐学习。

为什么?因为“默知识”是没有明确规则的,越努力找规律越学不会,不如放松一些,让头脑直接沉浸在直观信息中,这样更容易领悟那个“感”。

在企业经营中,我们经常需要新的创意:如何设计一个摆脱俗套的新激励方式?如何做营销上的创新?如何设计一个全新的内容?这时候,让注意力分散些,看看不相关的书籍、讨论一些别的话题,可能灵感会来的更快。

就像我写这篇文章,目的与路线图系列是一样的,还是想帮助大家提升经营管理能力。但如果不引入更多关于思考方式、关于人类发展史的文章,就会跳不出日常操作的层面,不能给大家带来新的空气。

四、小结

这篇文字是“思考方式革命”的第一篇。我讲的不是明知识、也不是默知识,我讲的是一些新的思考方法

(1)如何通过增添新的维度,让你对研究对象(无论是客户群、团队或产品服务)增加新的评估方式?操作工具就是最前面的四象限图。

(2)设计新体系时,用词要精准。王维嘉博士用一个“暗”字,一个“默”字,把体系讲的很清楚。“名不正言不顺”,这是我经常说的道理。一个事儿的“名字”选错了,要费很多口舌解释,到头来没听到解释的人看了还是会误解。

(3)计算机AI算法是基于人类的“神经网络”模型的。企业管理中,一个体系的设计、一个测算模型的建立,都要基于“自然”的业务规则,基于人性的需求进行考量。我不是讲抽象的“道”,我说的是可以操作的规则。

(4)例如:人的大脑将重复套路工作交给系统1,就是符合降低消耗的规则的。而“能量的限制”就是工业革命前的20万年里控制人类发展的主要因素。

(5)我们做企业,也是同样有很多限制,财务上有利润要求、有任何时点现金流不得低于安全线的要求。这属于“明知识”。

(6)在不能用“明知识”直接通过计算做出决策的复杂情况下,基于“感觉”的判断实际上更准确。所以专业知识重要,但业务背景更重要。

(7)但如果只靠“感觉”决策,也很危险。文中举了一个新兵打分的例子。最佳方法是:让决策者先结构化地全面多维度打分,然后再“感性”地做出最终判断。

(8)注意力分散些,有利于创新。所以需要新点子时,要给团队成员新环境、新场景和一些新时间。

(9)默知识这么重要,如何得到?要反复练习,不专注(忘掉规则)地学习。

品牌年轻化=品牌年轻人化?

雪涛

当下消费市场,年轻人是绝对的主力人群。对于品牌来讲,抓住年轻人就是抓住了市场,于是品牌们纷纷开始“年轻化”。但是在这条路上,一不小心,可能就会陷入“坑”中。本文笔者对品牌年轻化进行分析解读,总结了自己的看法,供大家学习参考。

互联网打破了渠道与媒介的壁垒,加速了整个社会消费观念、品味、需求的变迁。无论是消费观念还是购买能力,显然当下的年轻人是绝对的主力人群。

对于品牌而言,就好像牧羊一般,草在哪儿,羊群就在哪儿,不追草的羊不是已经饿死,就是在饿死的路上。

于是品牌年轻化好似成为了一切品牌问题的解药,不幸的是,这些品牌在年轻化的道路,都走到了相似的逼仄中,年轻化仅仅达到了“形”的贴近,却夭折在了“神”的部分。

那品牌年轻化到底该如何做呢?

木兰姐认为,在回答这个问题之前,我们需要先弄清楚一点:

品牌年轻化≠品牌年轻人化

与人一样,品牌也有自己的生命周期,会经历诞生-成长-成熟-老化的过程。但与人不同的是,品牌生命周期并不单纯以年龄来划分,而是与市场环境、经济环境、消费者行为绑定在一起。

但很多品牌往往容易陷进一个误区:认为品牌年轻化就是年轻人化,于是先给年轻人贴几个标签,然后再把这些标签贴在自己身上,试图收获年轻人的认同,混进他们的圈子,用看似时尚、热门、流行的元素将自己打扮成“年轻人”,但往往最后结果却是不被年轻人买单的无效沟通。

举个例子:

KFC前段时间的形象风波就是大型的翻车现场,让消费者者觉得品牌对“年轻”有误解。

KFC为了更贴合年轻消费者对颜值的要求,完全翻转了大家对爷爷慈祥微胖的印象,以更时尚的高颜值形象走入消费者眼帘。

但这个形象横空出现,只给消费者带来了短暂的视觉冲击,并没有让其产生情感上的认同,甚至是吓到了部分消费者,很多人直呼不买账。

△图片截取自网络

所幸这只是KFC品牌年轻化的一次尝试,并没有真正投入市场,也没有给品牌带来太多的影响。

从KFC的案例中我们可以得到什么样的警醒呢:或许品牌用表面的装嫩的方式能够获得一时关注,但混入年轻人的圈子,走进他们的内心却有些难度。

就像1000个读者就有1000个哈姆雷特一样,1000个消费者可能会有1000种需求或喜好,品牌无法对这个群体“一刀切”,也没有一个品牌能做到被所有年轻人追捧。

要知道,这一代年轻人并不是很多品牌自以为所谓的 “狂拽炸酷吊炸天”这么简单,品牌需要做的是真正洞察年轻人的生活态度,先在价值观上找到和年轻人真正的契合点,强调 “我”,而不是追随 “他”。

那正解如何呢?

一、为品牌灌注新鲜活力

就像物理学中的杠杆支点一样,支点找得准不准,直接影响其他要素的确定。对企业而言,突破品牌桎梏,精准地找到品牌年轻化的支点,才是赢得消费群体的王道。

而这个“品牌年轻化”的支点,木兰姐认为应该是为品牌灌注新鲜活力,延长或恢复品牌的“青春期”,让品牌可以一直活跃在时代主力消费人群的面前,不至于被消费者和市场遗忘。

无疑,旺旺是其中的佼佼者者。

旺旺在年轻化的道路上摸索出了一条康庄大道,除了主打情怀回忆杀,还不断尝试将品牌时尚化,以此来满足年轻人的潮流需求,比如六一携手奈雪的茶推出宝藏奶茶;与自然堂联合,打造自然堂x旺旺定制款气垫BB霜组合装,以及联名款服装等,一系列令人意外又惊喜的跨界合作,无疑赚足了眼球。

这一波国民经典IP与原创潮牌的跨界合作,不仅意味着旺旺已经洞察到现如今年轻一代的喜好,更代表了旺旺作为一个国民老品牌,有着高度的包容性,在打破以往成就、固化的品牌形象后,以有活力、年轻化、时尚潮流的品牌范儿,不断刷新品牌的高曝光度,以及年轻人对品牌的认可度。

可以说,旺旺在尝试年轻化营销的同时,也能看到其要做年轻化内容、年轻化产品、年轻化品牌的决心。

还有我们的国民老品牌百雀羚,不管是提到广告,还是产品,百雀羚都是美妆界永远绕不开的话题,而百雀羚能在消费者心中留下如此重要的认知,都离不开其一直以来的努力和创新。

从三生花系列到现如今的故宫美什件,从《一九三一》到今天的《见微知著》、《多了一点》,通过消费者喜欢的方式,为品牌注入新鲜的血液,让经典老品牌显得“年轻力”十足,成功激活了消费群体,并在品牌年轻化的形象和销售转化量上都实现了质的突破。

可见,只有为品牌注入与时代相符的新内涵,才能积极契合消费族群的变迁,才是品牌永葆年轻的护城河。

二、传递年起人认同的品牌价值观

提到这一点之前,我们先来看一个2018年最佳汽车营销广告案例,来自奥迪。

在这支广告里,奥迪没有流于表面的年轻元素,而是全程展现了一位滑雪飞人,观众跟着他脚下的双板划过几乎地球上所有的地貌:山地,森林,沙漠,草原,火山,长城,海洋…

而整个片子中,奥迪车全程没有入境,只在影片结尾,蓝色海洋的背景里出现奥迪的广告语:“All Conditions Are Perfect Conditions.(所有场景,都是完美场景)”。

但就是这支充满“挑战、无畏、前进等精神”的广告大片最后赢得戛纳社会化营销金奖,引起热议,深受年轻观众的喜爱。

这说明了什么?品牌年轻化,不应拘泥于品牌面貌的年轻,更多的是品牌内核的年轻

再举个极端的案例:

年过123岁的锐步(Reebok)签下80岁“高龄青年”王顺德为品牌代言人。这个加在一起超过200岁的“超高龄组合”,如果纯粹按年纪来说,绝对称不上“年轻”,而如果单从代言人王顺德的外形上硬要找一点年轻元素的话,可能也就能是那一头狂野白发中的“狂野”了。

为什么会选中王顺德?锐步看中了王顺德身上年轻的态度——坚持、自信、突破极限,向消费者传递出“任何年纪,都可以活出自己的样子,突破极限,打破年龄的疆界”的心态。

而这跟当代年轻人释放个性,崇尚平等,追求自由,积极进取,享受生活,不喜欢权威,不喜欢说教的价值观是一致的,锐步升华了代言人背后的品牌精神。

所以木兰姐认为,如果你正在为品牌年轻化发愁,不妨从品牌的核心精神和态度入手,形成年轻的品牌价值观,去发现目标消费群的价值需求,找到一个能在你们之间产生共鸣的态度,让他们对品牌产生认同。

三、帮用户发声彰显自我

此外,90后及00后的自我意识是全面觉醒的,与以往的群体不同,他们天生具有强烈的表达欲及掌控欲,这也进一步催化品牌要用“陪伴心态”去与年轻人相处,真正懂他们,帮他们发声,彰显自我……最终成为他们心里“陪在他们身边的人”。

比如说江小白的文案,其实不少是用户自己写的文案,然后通过筛选量产出来。再比如有时间火爆的《我的说明书》H5、DIY类H5,引发了同类H5作品的爆发,背后都是用户的自我价值表达。

还有今年五四青年节百度APP通过创意互动手绘形式,站在年轻人的角度,说出了他们的心声,彰显年轻人的才华和态度,也是狠狠地刷了一波存在感。

我们从不拒绝新事物

青年人,就要站在时代与潮流的风口浪尖

甭管哪年,在爱国这个原则性问题上

我们的脾气还是有点大

在国家最需要我们的时候

青年人逆风而行,救民于水火之中

这就像安装了八个情感按键,撬动用户心中的共鸣开关,最终完成内容与用户的深度沟通,让用户认同品牌价值;更重要的是设计出文案,让用户表达自我,从而在用户群中分享传播品牌价值。

由此可见,年轻化不是品牌的一厢情愿,而是品牌和消费者的合谋:“看见世界,找到自己”。

结语

最后,木兰姐想说,年轻化的“套路”不可能一成不变,无须刻意贴合年轻人时下的热点,抓住深的洞察获得年轻人共鸣,才是品牌年轻化的最好方式。

文章来源:人人都是产品经理

区分「取消」与「关闭」的设计差异

雪涛

区分取消与关闭,可以很大程度上避免丢失用户已操作的内容。在关闭视图之前保存用户的更改,使用文本标签而不是「X」图标,并在破坏性操作之前提供确认对话框。

让人迷惑的「X」图标

很久以前,「X」这个符号是用在地图上,标记「宝藏的藏身地」。但在今天的数字化界面中,「X」符号不再用来标记位置,而是被用来取消进程,或者关闭某个临时页面/弹框。但是如何确定「X」代表的是「取消」 还是「关闭」?有的时候可以确定,有时却模糊不清难以界定。

其实,主要的问题在于「X」图标缺少了文本标签。当同一个图标在不同的界面,却代表不同的含义,该图标的可用性就会受到影响,因为用户判断不了到底是什么含义。

为什么要区分「取消」与「关闭」

当用户单击/点击「X」按钮来关闭模态弹框或视图时,系统会完全取消该过程并清空之前所有操作,这让人沮丧,甚至抓狂。因为用户通常认为「X」图标表示取消或者关闭,所以区分这两种可能性对于交互的成功至关重要。

在某些情况下,区分取消 or 关闭并不重要。当一个弹窗占据你的大部分屏幕时,点击「X」按钮(尽可能快地),既可以关闭该模态,也可以取消它可能触发的任何进程。

但是,如果页面中包含正在运行的计时器,正在播放的音频,正在选择多个选项标签,或其他类型未保存的内容,那就很有必要说明「X」图标所代表的意义。因为用户可能打算让计时器或音频继续运行,或者希望立刻应用这些选好的选项标签,或保存正在进行的工作,同时希望关闭该视图继续其他操作。

例如:丝芙兰在结账过程中,使用模态窗口来展示用户可以添加到购物车的免费商品。在以下示例中,单击「 ADD(添加)」按钮选择商品后, 该按钮直接被变成了「 Remove(移除)」,看起来似乎商品已经被添加到购物车中了。但是,实际上当用户单击右上角的「X」图标后,该商品并不在购物车中。他需要再重复这个步骤,最后点击「Done(完成)」按钮,商品才会被加入购物车。

Sephora:单击右上角的「X」会取消选择这些试用商品整个过程。用户必须先单击「ADD」,再单击「Done」才能将商品添加到购物车。

如何避免丢失用户正在操作的内容

要避免丢失用户正在操作的内容,首先需要确定用户的意图,是取消还是关闭,并提供明确的选项。有以下几种方法:

  • 主动要求用户确认他们的意图;
  • 使用明确的文本标签而不是模糊图标;
  • 显示两个不同的按钮:「X」图标表示关闭视图(可以自动保存页面内容/操作),而「取消」则代表放弃该过程。

1. 要求确认

如果用户在已经执行操作的模态弹框或页面视图中,点击「X」图标,app 则可以在关闭视图之前,直接询问用户是否应用该操作,来确认其意图。此解决方案非常适合会破坏用户工作的破坏性取消操作。例如,过滤器视图可能会被意外关闭,并且关闭会导致用户丢失其选定的选项。

这个问题在移动端界面上很常见,因为过滤器视图占用了很大的屏幕空间,这使用户很难或不能判断是否已经应用了那些选择。为了防止这种潜在的错误,在关闭过滤器视图之前,跟用户确认是否要应用这些选择并关闭视图,抑或是清除这些选择。例如:下图中,当用户选择后,点击「X」图标时,Lowes 会出现如下确认弹框。

左 :点击「X」图标或返回箭头,所有的选项都会被取消,并将用户带回上一个页面。右:点击「X」后,出现一个确认对话框,确认用户是应用还是取消筛选,然后再返回结果列表页。

同样,当用户关闭正在进行的课程时,语言学习应用Duolingo 会显示一个确认对话框,课程进行中不能中途离开,除非确认「退出」。至少,该 APP 向用户传达了这一限制,同时他们也可以选择「取消」来继续课程。点击「X」按钮将结束当前课程。为了防止出错,结束前会出现一个确认对话框。

缺点:

  • 虽然确认对话框在避免「X」图标有歧义方面很有效,但它却添加了额外的步骤;
  • 用户在按下「X」图标之前还是不知道它到底做了什么,代表什么意思,因此他们可能会对这个操作感到疑惑。

2. 使用文本标签

不要完全依赖对话框来让用户确认模糊的「X」图标,而是使用明确的文本标签。文本可以消除歧义,并清楚地传达将发生的操作:取消与关闭。

Yelp 的筛选页面在屏幕顶部提供了标有「Cancel(取消)」和「Reset(重制)」的按钮,在底部提供了一个大大的「Apply(应用)」按钮。类似地,Etsy 中的 Filters 视图提供了「Clear(清除)」和「Done(完成)」两个按钮。

注意:Etsy 使用「Done」而不是「Apply」,因为过滤器一经选择就可以被应用,而这里是关于开关切换与否的建议。

(左)Yelp:Cancel、Reset 和 Apply 这三个文本标签既直接又清晰,这样用户就不太可能不小心关闭视图而丢失他们过滤器中的选择。(右)Etsy:Clear 为用户取消提供了一种清晰的方式,而点击 Done 则返回到「产品列表」页,其中的选择已经应用。

3. 关闭并保存

如果必须使用「X」图标而不是文本标签(比如为了以节省空间,或者正在遵循团队的设计语言),请谨慎使用,并在用户完成前保存操作/内容。另外,可以提供一个单独的「取消」按钮,让用户在进程之外有一个紧急出口,并消除「X」在两种含义之间的歧义。

例如:Gmail 会自动保存在非模态窗口中填写的邮件信息到草稿(Drafts)。这样的好处是,用户在需要折叠或关闭该窗口时,仍然保存原来的内容以便于下次继续编辑。将鼠标悬停在消息窗口右上角的「X」图标上时,会显示一段提示:Save & Close(保存到草稿并关闭)。此外,点击窗口右下角的「垃圾桶」图标可以删除该邮件,这个图标离顶部的「保存和关闭」选项很远,可以防止用户误点。

Gmail:Hover 透露,「X」图标是用于关闭窗口而不是删除草稿,它允许用户保存并关闭消息窗口而不会丢失刚刚正在编辑的邮件。

对于长进程或倾向于在后台运行的进程(如计时器),默认自动保存也是一种很好的解决方案。

例如,Glow Baby 中,后台运行喂食或睡眠计时器时,用户还可以浏览 APP 的其他区域。因为这些计时器一般会运行很长一段时间。此功能还能让用户在 APP 中做其他的任务操作,例如记录之前换尿布的时间、浏览文章、逛论坛等。点击计时器视图中的「X」图标也只是关闭窗口并不会取消正在运行的计时器。

Glow Baby:(左)点击运行计时器视图中的「X」图标,在不停止计时器的情况下取消视图,从而允许用户继续使用 APP 记录其他类型的事件、参与社区讨论、阅读文章等。(中)运行计时器的状态显示在屏幕顶部的状态栏中。(右)在计时器暂停时点击「X」图标,弹出「放弃」或「取消」按钮以确认用户的真正意图。

请注意:在关闭前保存中间工作或维护正在进行的过程是主动的,但有时可能会与用户的意图相反。如果用户打算通过单击「X」按钮取消其选择,那自动应用这些选择可能会令人困惑和沮丧。

这就是为什么还必须有一个单独的「取消」按钮,给用户一个出口,而不是强迫他们必须关闭时自动保存。

结论

虽然「X」图标会造成模棱两可,而且经常导致可用性问题,但它不太可能马上从所有接口中消失。设计人员应该注意「X」图标的多重含义,消除「关闭」和「取消」之间的歧义,并提供确认对话框或自动保存等保护性措施,避免丢失任何用户正在操作的内容。

若存在疑问,请记住:先保存,再退出。

小思考

为什么手机验证码登录微信/淘宝时,验证码输入错误,二者都是用的模态对话框提示用户,而不是用 Toast 呢?

  • 微信和淘宝的用户群体都很庞大,几乎横跨所有年龄层。Toast 出现又自动消失的交互体验,用户会感到不可控,尤其是对大龄、老龄的用户不够友好。
  • 也有悖于 iOS 人机交互指南中提到的「用户控制」这一原则,我想这也是 iOS 设计语言没有 Toast 这种控件的原因之一吧。
  • 而模态对话框虽然干扰性较强,但用户可以随时控制,在使用过程中是用户掌握主导权。

补充:Toast 这一控件,原是 Android 系统的控件。但自 Android 5.0 推出原质化设计后,Toast 就被弱化,而是将 Snackbar 作为官方推荐的控件。如今在 Material Design 中更是找不到 Toast 的踪影。主要原因还是 Snackbar 在交互友好性方面比 Toast 要好,例如:支持手势交互、支持与 CoordinatorLayout 联动等。

跨平台设计 :平台选择

雪涛

在本篇开始之前,我们稍作回顾。目前已经完成的两个系列包括:「iOS 13 设计新特性」,涉及深色模式、SF Symbols、卡片面板及情境菜单等话题,错过的朋友不妨回看,毕竟新系统将会在近两日正式推送。在「基础设计原理」当中,演讲人通过一场夏威夷之旅带领我们了解了一系列重要的设计原理,包括一致性、可供性、心智模型、渐进呈现等等,深入浅出,老少咸宜,强烈推荐。

△ Mike Stern 老师的「基础设计原理」

而本期开始的新话题则聚焦于如何面向 Apple 生态体系中的多种设备进行设计,包括如何选择平台,如何针对不同的平台权衡功能与外观风格,如何构建生态体验等等;演讲者是 Apple 的设计师 Cas Lemmens。

跨平台设计 – 平台选择

在 Apple,我们非常自豪于我们所创造的一系列设备平台。在创造和升级这些平台的过程中,我们都会以提升人们的日常生活品质为目标,并力图在人与设备之间构建富有意义的关联。这关联未必仅存在于单一平台当中;你所使用的 Apple 设备越多,便越发能体会到整个生态带来的依存关系。

你可能会戴着 Apple Watch 晨跑,可能会在 MacBook 或是 iMac 上完成一天的工作;下班后,你可能会借助 iPhone 的一系列功能来使用公共交通,或是在你的车里使用 CarPlay;回到家,你可能会通过 Apple TV 看剧或电影;睡前,你可能还会在 iPad 上读书。

无论你正在使用何种设备,Apple 的平台生态都可以识别你、理解你,并帮助到你。

面向这样的生态体系进行设计,你必须对其中的每一个平台都有着深刻的理解。对于 Apple 的设计师而言,这样的挑战已经变得司空见惯。我们必须谨慎思考每一个 app 可能适合的平台类型,以及如何使其针对不同的平台进行相应的调整。

Apple 开发的 app 当中,有些是面向全平台的,例如「照片」或「音乐」。

而有些则仅存在于特定的平台当中,例如「备忘录」、「邮件」等等。

有些服务可以在你拥有多种设备的情况下带来最优体验,例如 ApplePay;另外一些则必须基于多台设备同时运行,例如 FaceTime。

今天,我要与各位分享的,便是 Apple 的设计师在进行跨平台设计时所采用的典型流程。希望这些经验可以帮助各位更加且目标明确地将你的产品和服务推向 Apple 生态圈当中的更多平台。

我们首先会从「平台选择」开始,即了解每一个平台的情境特质与能力特征,并以此为基础选择最恰当的目标平台。

然后是「平台适配」,即基于目标平台的设备特性,对我们希望实现的功能进行权衡与管理。

接下来是「风格协调」,即在品牌风格与平台规范之间寻求平衡,对 app 的视觉外观及操作体验进行定义。

然后是「平台连接」,即探索如何在不同的设备平台之间实现功能的连续性,打造轻松、无缝的使用体验。

最后,我们还会尝试「平台扩展」,即探索如何同时基于多平台实现最优的综合生态体验。

以上便是跨平台设计的主要流程。接下来,我们将对这五个步骤逐一进行了解。

平台选择

所谓「平台选择」,即回答「我要面向哪个平台进行设计」这个问题。

或许你还没有上线过任何 app,目前正在考虑以哪个平台作为首发;或许你已经在一两个平台上发布过 app,正在考虑接下来应该进行怎样的扩展。

在选择平台时,有两个最为关键的概念需要我们重点思考:

  • 情境:特定平台最为适用的时间、地点及其他环境要素。
  • 能力:特定平台最具差异性的功能特征。

对于「情境」的理解至关重要,因为当情境发生变化时,人们通常会切换他们所使用的设备,以不同的方式完成不同的任务。

举个例子。譬如你正在办公室里工作,或是在学校上着课;这些都是高度聚焦和稳定的情境。当你离开这些场所,乘上了公交车或地铁,你便进入了高度动态和移动化的情境。这两类情境之间的差异非常明显,我们通常会从 Mac 切换至 iPhone 或 Watch,因为后两者本就是面向移动化情境进行设计的。

而对于「能力」的理解则可以帮助你掌握并充分利用特定平台的独特功能。

接下来,让我们从「情境」与「能力」这两个方面,对 Apple 生态体系当中的一些典型平台进行分析。

平台分析

首先是 iPhone,因为这可能是我们多数人最为熟悉的平台了。

从情境的角度来看,iPhone 始终保持开机,始终与我们相随,因此它是高度移动化的;同时,iPhone 也是高度私人化的设备,我们不会轻易与他人共享使用;此外,iPhone 通常被用于高频而短时的互动,我们每次使用不会超过几分钟。

iPhone 所具有的能力可以有效地支持其情境特质。「始终开机,常伴于身」的特性要求 iPhone 必须具备良好的环境感知能力,其内置的陀螺仪、加速计等传感器可以始终在背景进程当中处理环境相关的信息,即便是在我们没有使用 iPhone 的时候;iPhone 的 Touch ID(及 Face ID 等机制)则会为我们提供私人化的保护;其高清晰度的触屏则能确保我们在短时间的互动过程中获得轻松与愉悦的体验。

与 iPhone 类似,Watch 也具备「始终开机,常伴于身」的特性,且同样是高度私人化的。但 Watch 具有更强的即刻性,所面向的是更为短暂的互动,譬如你只需一瞥便可以从表盘上获取与当下情境最为相关的信息;而提示信息在你注视稍久时还会进一步提供详细信息。

Watch 所具备的能力与其私人化的情境特质息息相关。Watch 可以追踪你的运动状态、地理位置及心率;其触觉反馈可以通过轻触手腕来提醒你查看信息;而表盘也是高度定制化的,你可以让最为需要的信息始终呈现在表盘之上,便于一瞥之间快速获取。

而 iPad 则具有较为复杂的情境特质,既可以被用于稳定的环境,同时也支持移动化场景。你可以用 iPad 完成一些而聚焦的任务,也可以将其作为放松型设备来享受影视或游戏体验。而所有这些互动过程都比 iPhone 或 Watch 更加持久。

从能力的角度,iPad 的大屏正是对这些情境特质的有效支持。充足的屏幕尺寸可以帮助你完成高精度的操作,环境光传感器可以使其良好适应于日夜不同的光照条件;高保真扬声器和高精度触屏可以为影音或游戏带来更具沉浸感的视听体验;若是配合 Apple Pencil,iPad 还能帮助你完成更加、更具创意性的工作。

再来看 Mac。其情境特质具有高度的专业性,你可以进行非常而聚焦的工作,譬如设计和开发 app;MacBook 可以被作为共享设备来使用,但它同时也是个人化的,因为多数使用者都拥有独立的个人帐户;我们通常会长时间使用 MacBook 或 iMac,譬如每天都会有几个小时的互动时间。

在能力方面,为了支持高度专业化的任务,Mac 具备着非常高的性能表现;键盘鼠标可以帮助你进行而复杂的操作;多任务能力允许你以自己所需的方式进行工作;而多帐户体系则能使 Mac 适用于更多样的工作场景。

最后来看 Apple TV。这是生态当中最具共享性的平台,我们通常会与家人或朋友一起观看;TV 最具稳定性,始终与电视机绑定在一起,不会四处移动;TV 是完完全全的放松型设备,我们用它来享受影音或游戏,每次使用时长通常在三十分钟到几个小时之间。

配以高清显示屏,TV 的画质将会鲜活得呼之欲出;TV 的遥控器轻便易用,你可以轻松地将其传递给朋友和家人;TV 可以与 HomeKit 良好配合,使其高度稳定的特性得以在「家庭」这个场景中充分地发挥;其界面设计特别面向 10 码左右的距离进行优化,使你可以轻松地窝在沙发里享受娱乐体验。

通过以上分析,你便能理解,为何了解每个平台的「情境」与「能力」对于你的目标平台选择来说是如此重要的事了。

「情境」是平台的立命之本,而「能力」则决定了其独特性。

对于你的 app 来说也是如此。你需要问自己两个关键问题:我的 app 可以在怎样的情境里体现产品价值?要实现产品价值,需要哪些特定的技术能力作为支持?

平台选择练习

在 Apple 内部,每当需要为 app 选择目标平台时,我们都会反复进行一项简单的练习。现在我来为各位进行演示。

首先让我们以「健身记录」 app 为例。

想想看「健身记录」的产品特性,你会发现它首先必须具备移动性。它需要追踪你全天的运动行为,以便进行的数据统计。因此它需要设备平台具备「始终开机,常伴于身」的特质,即高度的移动性。

同时,「健身记录」还必须是私人化的。它应该能且只能追踪你个人的数据。

接下来,我们要通过象限图来建立情境特质与平台之间的映射关系。其中横轴代表「移动性」,从左到右递减;一系列 Apple 设备平台按照各自的特质分布在轴线上,譬如 Watch 最具移动性,而 TV 最具稳定性。

而纵轴代表「私人性」,从上到下递减。其中 Watch 最具私人性,TV 则最具共享性。

对于「健身记录」而言,由于要同时具备高度的移动性与私人性,因此在象限图当中会大致位于左上方的位置。这便解释了为什么它会出现在 Watch 和 iPhone 当中,而非其他平台。

接下来我们以 GarageBand 为例。

GarageBand 涉及到的人机互动是高度精准型的,因为人们需要非常准确地操作音频内容,使它们出现在正确的时间和地点。

此外,GarageBand 必须良好地支持多任务,因为人们往往会将多种音频器材和乐器连接进来同时进行演奏。

我们通过象限图来建立映射关系。其中横轴代表交互的性,左端为粗放型,最具代表性的平台是 Watch,因为其屏幕较小,而人们的手指相对粗大,难以完成具有高精度要求的操作;右端为精准型,代表平台为 MacBook 或 iMac,因为键鼠操作具备最高的度。

纵轴则代表「多任务能力」,从上到下递减。在 Mac 上,我们可以轻松地进行多任务操作;而对于 Watch,你每次只能完成一项任务。

GarageBand 需要同时具备高度的交互能力,以及良好的多任务能力,因此在象限图当中会大致位于右侧偏上的位置,所对应的即是 Mac、iPad 和 iPhone。

这两个例子都非常简单,各自仅涉及到两方面的情境特质。在实际当中,我们通常需要将更多、更复杂的特质因素考虑进去;最终,我们希望能够为 app 找到最适合其生存的平台。

以上便是跨平台设计流程中的第一步,「平台选择」,即综合考量不同设备的情境特质及能力特征,进而为 app 选择最为适合的平台。

日历

链接

blogger

蓝蓝 http://www.lanlanwork.com

存档