微信开发案例

2017-08-24 14:06:03 qq_23489303 阅读数 8446

微信公众号开发实例

文档下载地址:
https://github.com/duangYiXia/WX-DEMO
下微信公众号开发实例01.docx


本文档主要以天气查询为功能的微信公众号应用开发为例,详细地描述了微信公众号应用开发的环境搭建,开发过程,以及其它相关的知识。
1.简介
微信,是当下智能手机几乎必装的即时通讯服务软件。全球注册人数数亿,截止2016年12月,微信月活跃用户数高达8.89亿。如此巨大的月活跃用户数,自然蕴含了巨大的商机。2012年8月20日,腾讯公司在微信中加入了微信公众号的功能。此功能主要面向个人、政府、媒体、企业等机构推出了合作推广业务。大家使用微信公众号将自己的品牌推广给数亿的微信用户,减少了宣传成本,提高了品牌知名度,打造了更具影响力的品牌形象。

“再小的个体,也有自己的品牌”,这是微信公众号网站上的广告词。现如今大量的用户加入了微信公众号应用的开发之中,给微信用户提供了各种各样的服务,如微网站,微商城,微KTV,微政务,微酒店,微汽车,微旅游,微餐饮,微调查,微会员,微喜帖,微团购,微房产,微教育,微菜单,微门店,微物业,微酒吧,微餐饮,微花店,微美容,微婚庆,微生活,微相册,LBS,智能客服等等功能。
1.1 基础知识
1. 微信公众平台与微信公众号的关系
微信公众平台是腾讯公司为了让用户申请和管理微信公众号而推出的一个WEB平台。而微信公众号的所有操作管理都需要在微信公众平台下进行。所有用户都需要在腾讯公司统一提供的微信公众平台下操作。URL地址:
https://mp.weixin.qq.com

  1. 微信公众号与微信的区别
    微信公众号的服务对象是微信,是以微信为载体,简单来说,没有微信,就用不了微信公众号提供的功能。微信公众号需要利用微信公众号平台来开发,可能需要用到WEB服务器。而微信只需要下载微信app到手机安装即可使用。

  2. 微信公众号与微博的区别
    微信公众号更具有私密性,达到率更高,侧重于客户管理,且具有即搜即用的特点。微薄更侧重于传播和公开。微博的信息过多,发表的微博可能被淹没在海量消息中而不会被粉丝看到。

  3. 微信公众号的分类
    微信公众号目前有三种类型:

企业号
微信为企业客户提供的移动应用入口、简化管理流程,提升组织协同动作效率;帮助企业建立员工、上下游供应链与企业IT系统间的连接。
适用人群:媒体、企业、政府或其它组织。

服务号
服务号开发的接口比较多,主要针对于企业、以服务功能型为主的账户,功能强大,但不需要过多推送内容,以服务为主,给企业和组织提供更强大的业务服务与用户管理能力,帮助企业快速实现全新的公众号服务平台,如招商信用卡、南方航空。很多企业也会选择服务号与订阅号同时建立来满足不同的服务需求。
适用人群:媒体、企业、政府或其它组织。

订阅号
主要用于推广。多是一些媒体、自媒体、公司市场、品牌、宣传使用,为媒体和个人提供一种新的信息传播方式,构建与读者之间更好的沟通和管理模式。订阅号还分个人订阅号和企业组织类的订阅号,个人号无法认证,请申请企业类的账号,才能获得更多权限和排名的优化。
适用人群:媒体、企业、政府或其它组织。

三种账号的区别:


5. 微信公众号的申请准备资料

“企业”类型
包括:企业、分支机构、企业相关品牌、产品与服务、以及招聘、客服等类型的公众号。

“媒体”类型
包括:报纸、杂志、电视、电台、通讯社、其他媒体等类型的公众号。

“政府”类型
包括:国内外、各级、各类政府机构、事业单位、具有行政职能的社会组织等类型的公众号。
目前主要覆盖公安机构、党团机构、司法机构、交通机构、旅游机构、工商税务机构、市政机构、涉外机构等。

“其他组织”类型
包括:不属于企业、政府、媒体、个人的机构类型的公众号。

“个人”类型
包括:由自然人注册、认证、运营的公众帐号。

  1. 微信公众平台的测试号
    申请微信公众号,还是比较麻烦,并且微信公众号的名称一旦注册就不能修改。开发微信公众号应用时,开发者可能也没有想好微信公众号的名称,另外也不知道微信公众号平台是否能提供自己需要的功能。

目前微信公众号平台提供测试号,这个不需要申请正式的微信公众号,就可以直接体验和测试微信公众号平台支持的所有高级API接口。
申请地址:
https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
注意:
使用测试号时,对微信公众平台提供接口的调用次数是有限制的。
具体参见文档:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433744592

2.开发准备
2.1 业务流程
从用户访问微信公众号,直到看见微信公众号的反馈消息过程中,到底经历了那些步骤:

从上面的业务流程中,可以看到微信公众号应用开发至少需要这些东西:

1、 微信公众号,微信关注了微信公众号以后,我们才有发送消息的入口。
2、 WEB服务器,用于部署WEB应用,WEB应用为微信公众号提供了各种服务。
3、 通信协议,即微信公众号平台与WEB应用之间的通信协议及其内容,了解这些知识才能正确处理来自微信公众号平台发来的请求消息,并且回复合适的响应消息回去。
2.2 微信公众号
微信公众号,需要到腾讯公司统一提供的微信公众号平台去申请。由于申请微信公众号还是有一些麻烦,开发微信公众号最方便快捷的方式,还是去微信公众号平台上申请测试号。

下面是申请微信公众测试号的过程:


1. 打开浏览器,输入网址:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

  1. 点击网页中的“登录”按钮,出现一个二维码:

  2. 在手机上登录你的微信,然后使用微信中的“扫一扫”功能,扫描上面网页中的二维码。手机上会出现以下界面:

  3. 在手机上点击“确认登录”按钮,返回电脑网页,网页将会变成:

  4. 网页中会提供测试号的账号名称,appID和appsecret,以及二维码等信息。到这里,就完成了微信公众测试号的申请工作。

说明:
每一个微信公众测试号都有唯一的标识,通常是以gh_xxxxxxxxxxxx命名,由微信公众号平台自动产生。

appID和appsecret是测试号的重要信息,也是由微信公众号平台自动产生,用于调用微信公众号平台高级接口时作验证使用。

微信公众测试号二微码,也是由微信公众号平台自动产生,用于微信扫一扫加关注时使用。当扫描这个二微码加关注以后,就有了一个微信公众号的信息输入口。

此时的微信公众测试号并不能马上使用,还需要填写“接口配置信息”中的两项:
. URL
需要填写你的WEB应用服务的URL地址,这个地址必须在公网上被微信公众号平台访问到。根据微信公众号平台的规定,你的WEB应用应该部署在带域名并且开放80端口的公网服务器上。如果正式运营微信公众号时,所使用到的域名还需要ICP备案。

. Token
令牌,是你自己任意输入的信息,用于WEB应用接收微信公众号消息时作消息源验证使用。简单来说,就是用于验证WEB应用接收到的消息是否来自微信公众号平台。微信公众号平台转发消息给WEB应用时,会带上这个Token。

目前我们还没有WEB服务器,WEB应用也没有部署上去,这里的URL地址自然也无法确定。Token暂时也不急着填写。接下来,我们先设置WEB服务器,部署WEB应用。

2.3 WEB服务器
WEB应用赋予了微信公众号具有的所有功能。WEB应用部署在WEB服务器上。由于微信公众号平台的规定,WEB服务器需要公网域名并且开放80端口的访问。申请域名,申请主机,对于一般开发者而言,门槛还是比较高,即便在互联网上能找到免费的公网域名和主机资源,对于开发工作,也是相当不方便。因为软件开发,修改的工作是再平常不过的事情,每一次的修改都需要上传到公网服务器上作验证,想想也是头疼的事情。

开发者通常习惯使用本地环境做开发和测试。有这样的需求,自然也就有相应的解决方案:使用内网穿透技术。即向公网上的一个地址发送请求,可以转发到内网服务器上并返回响应消息。实现这种技术的软件很多,如nat123、花生壳、ngrok等等。

其中ngrok被使用的最多,ngrok是一个反向代理,可以在公共的端点和本地运行的WEB服务器之间建立一个安全的通通。可惜国外的ngrok.com由于各种原因被微信公众号平台封杀。还好,国内使用ngrok技术的一些站点还能使用。其中ngrok.cc是一个不错的选择,至少目前还提供免费的服务。

使用ngrok.cc的服务,需要到ngrok.cc网站上去申请账号,并且下载相应的软件。

下面是申请账号的过程:

1、 打开浏览器,输入网址:https://www.ngrok.cc/


2、 点击“注册”或者“立即注册”按钮

3、 填写“电子邮箱”,“用户名”,“密码”和“验证码”,点击“注册”按钮

4、 如果没有意外,会提示注册成功,之后自动转入登陆界面


5、 输入注册时“邮箱”和“密码”,点击“登陆”按钮,进入ngrok后台管理页面

6、 点击左侧栏菜单“隧道管理”-“开通隧道”,如下所示:

7、 网页右侧有“香港免费服务器”的选项,点击下面的“立刻购买”按钮,页面如下

8、 我们使用ngrok.cc站点将微信公众号消息转发到内网,只需要填写“隧道名称”,“前置域名”和“本地端口”即可。隧道协议默认http,不要填写“http验证用户名”和“http验证密码”字段。
说明:
“隧道名称”,可以任意输入,如“微信公众号测试”

“前置域名”,是你指定的域名前缀,如testserver1,那么你的域名全称就是testserver1.ngrok.cc,这里不需要输入ngrok.cc,只需要输入你想要域名的前缀。

“本地端口”,这个是指你想将消息转发的哪一台机器和哪一个端口,通常填写“127.0.0.1:8080”。

当这些字段填写后,那么这个隧道的工作内容,就是将发送到testserver1.ngrok.cc的消息,转发到本地服务器127.0.0.1的8080端口。

9、 填写好信息后,点击页面下面的“确定添加”按钮,就可完成账号的申请,点击左侧菜单“隧道管理”-“隧道管理”,可以看到你申请的账号信息,如下图

其中,有隧道id很重要,在使用软件连接到ngrok.cc站点时需要使用到,用于作隧道合法性验证。

10、 使用浏览器,再次打开网站https://www.ngrok.cc的主页,在网页下面选择本地服务器对应操作系统版本的ngrok软件。支持Linux 32bit/64bit/arm,Mac OSX 32bit/64bit,Window 32bit/64bit等。这里选择Window 64bit版本的ngrok软件即可。

11、 解压缩ngrok软件包,运行里面的程序“Sunny-Ngrok启动工具.bat”,如下图:

12、 现在输入步骤9中的隧道id,回车确认,ngrok客户端软件就开始连接ngrok.cc站点服务器,如果没有意外,连接成功以后的样子,应该是这样的:

从截图中可以看出,ngrok软件初始化完成,http://testserver1.ngrok.cc -> 127.0.0.1:8080,这个正是当初在ngrok.cc站点申请隧道的工作内容。

13、 隧道已经建立完成。我们可以作一个简单的测试。在本地Window服务器上启动一个TOMCAT服务,服务地址:127.0.0.1:8080。

14、 打开浏览器,输入网站:http://testserver1.ngrok.cc,浏览器应该可以显示一些内容了,如下图:


15、 同时查看ngrok客户端软件,也有一些信息提示,如下图:

16、 自此,我们就完成了WEB服务器的设置。

总结一下上面的内容,我们使用本地启动了TOMCAT服务的Window机器,做为微信公众号应用的WEB服务器,并且利用ngrok.cc站点提供ngrok技术,实现了公网地址上的请求转发到内网服务器上面。

有了WEB服务器,自然要部署WEB应用,因为涉及到WEB应用与微信公众号平台之间的通讯,因此需要先了解下一节“通讯协议”。
2.4 通信协议
这里所说的通讯协议,特指微信公众号平台与WEB应用程序之间的通讯协议。

微信公众号平台与WEB应用程序之间使用HTTP协议。因此,开发微信公众号应用能使用的开发语言就相当广泛了,如Java、Python、PHP等等。只要能同时支持HTTP GET和HTTP POST方法的开发语言,都可以用于微信公众号应用的开发。

HTTP GET方法,主要用于验证消息是否来自微信服务器。

HTTP POST方法,主要用于接收来自微信服务器提交过来的信息,如:文本、图片、地理位置、链接以及事件等。

下面是具体的协议内容:

1、 HTTP GET
应该还记得前面申请微信公众测试号时,有一个地方需要填写URL和Token。

当时我们并没有填入任何信息,主要因为当时服务地址并没有确定。

现在假设服务URL已经确定,如: http://testserver1.ngrok.cc/testserver/wx,并且Token指定为testserver,点击上面的“提交”按钮,网页会提示“配置失败”。即使服务URL:http://testserver1.ngrok.cc/testserver/wx真实存在,提交仍然会提示“配置失败”。这是为什么呢?

这是因为微信公众号平台的规定,强制WEB应用对微信公众平台的消息作消息源验证。

当上面页面点“提交”按钮时,微信公众号平台会发出HTTP GET请求:http://testserver1.ngrok.cc/testserver/wx?signature=xxx&timestamp=xxx&nonce=xxx&echostr=xxx,即在你输入的URL后面携带上下面4个参数:

开发者需要通过signature对请求进行校验,下面是校验方法:

若确认此次HTTP GET请求来自微信服务器,原样返回echostr参数内容,则接入微信公众号平台成功,否则接入失败。

由于我们并没有WEB应用正确处理微信公众号平台发来的验证消息,所以才会提示“配置失败”。


解决的办法如下:
使用Eclipse创建一个WEB工程testserver,然后编写一个wx的servlet,在void doGet()方法中,解析出echostr,直接返回,就可以通过消息源验证。

2、 HTTP POST
HTTP POST,主要用于微信公众号平台向WEB应用程序发送文本,图片,地理位置,链接以及事件通知消息。

POST的URL,即是你在微信公众号平台填写的URL,如:
http://testserver1.ngrok.cc/testserver/wx
POST的请求消息的内容和返回消息的内容都使用XML格式,下面是具体的说明:

.文本请求消息举例说明:

2019-07-21 21:33:00 AndyWei147 阅读数 753

        微信公众号,我们都很熟悉。但是如何开一个属于自己的一个微信公众号,其实很简单。这边文章就给一个简单的例子。需要准备的环境:

1、域名,用于微信公众号访问我们的服务器,如没有域名,建议使用花生壳进行内网穿透来访问我们的项目(具体使用方法,不在这里讨论)

2、需要申请一个微信公众号:https://mp.weixin.qq.com/

3、需要一个Javaweb项目

      万事俱备后,开始生路。

     第一步,对微信公众号的一些配置:

     登录微信公众平台,找到如图所示

  填写如下的信息,url是我们项目的URL,token是我们自己定义的

此时,我们点提交会报错,是因为我们还没有校验,当我们点提交之后,会通过get方式发送一些校验的数据到我们的项目。然后我们需要进行校验

第二步,数据的检验,检验方式是SHA1算法,具体如下代码

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException
	{
		System.out.println("进入get方法");
		String str = request.getQueryString();
		String echostr = check(str);
		OutputStream out = response.getOutputStream();
		if(str != null)
		{
			try
			{
				out.write(echostr.getBytes());
			}finally{
				out.close();
			}			
		}		
	}
private String check(String text)
	{
		
		//解析发过来的参数:
		//signature=2e334555ebb6e43ec2c975d6ad54f642d7c95252&echostr=9019000808531292887&timestamp=1563681495&nonce=1882518168
		/*
		 * 微信公众号会通过get请求发送如上的参数,然后我们验证是否是微信公众号的请求,
		 * timestamp  nonce  tokone 我们将这三个连起来进行加密,加密前要对他们进行按字母排序,
		 * 其中tokone是我们自己写的
		 * 如果密文匹配,我们返回echostr的值,此时微信公众化那边就认为匹配成功
		 */
		String[] content =  text.split("&");
		String signature = content[0].split("=")[1];
		String echostr = content[1].split("=")[1];
		String timestamp = content[2].split("=")[1];
		String nonce = content[3].split("=")[1];
		String token = "hello2019";//这个自己定义,单要与页面上的一致
		
		String[] arr = {token , timestamp , nonce};
		Arrays.sort(arr);//根据字符的顺序排序
		//排序后将三个字符串连起来
		String checkCode = arr[0] + arr[1] + arr[2];//将排序后字符串连接起来		
		MessageDigest md;
		try
		{
			//进行SHA1加密
			md = MessageDigest.getInstance("SHA1");
			md.update(checkCode.getBytes());
			byte[] code = md.digest();
			//将加密后的字节数组转成十六 进制字符串
		    String ss = Hex.encodeHexString(code);
		    if(ss.endsWith(signature))//判断两个密文是否一致
		    {
		    	return echostr;
		    }
		} catch (NoSuchAlgorithmException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

校验通过之后,我点提交按钮就会提示校验成功。

第三步,处理文本信息。当我们检验成功之后,我们在公众号好发一条消息,微信公众号会通post方式以xml格式发送到我的项目,然后我们就对数据进行解析,具体各种字段的含义可以参考微信公众号的开发文档https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1472017492_58YV5

下面是我自己的处理方法,首先写一个工具类,用来xml与map之间的转换,其中用到dom4j的jar包,代码如下:

package my;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

public class TextUtils
{
	/**
	 * 读取字符串
	 * @param input
	 * @return
	 * @throws IOException 
	 */
	public static String readAsText(InputStream input , String charSet) throws IOException
	{
		ByteArrayOutputStream cache = new ByteArrayOutputStream();
		byte[] buf = new byte[1024];
		int count = -1;
		while(true)
		{
			int n = input.read(buf);
			if(n == 0)
			{
				try
				{
					Thread.sleep(3000);
					count++;
				} catch (InterruptedException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}								
				if(count < 3)
				{
					continue;
				}
				
				else
				{
					break;
				}
		
				
			}
			if(n < 0)
			{
				break;
			}
			cache.write(buf, 0, n);
		}
		return cache.toString(charSet);
	}
	/**
	 * 默认编码格式是UTF-8
	 * @param input
	 * @return
	 * @throws IOException
	 */
	public static String readAsText(InputStream input) throws IOException
	{
		return readAsText(input , "UTF-8");
	}
	/**
	 * 将xml格式转成map
	 * @return
	 * @throws DocumentException 
	 */
	public static Map<String , String> xml2Map(InputStream input) throws DocumentException
	{
		Map<String , String> map = new HashMap<String , String>();
		SAXReader xmlReader = new SAXReader();
		Document x_doc = xmlReader.read(input);
	    Element x_root = x_doc.getRootElement();
		List<Element> list = x_root.elements();
		for(Element e : list)
		{
			String name = e.getName();
			String value = e.getTextTrim();
			map.put(name, value);
		}
		return map;
	}
	/**
	 * 
	 * @param map
	 * @return
	 * @throws IOException 
	 */
	public static String map2Xml(Map<String , String> map) throws IOException
	{
		//创建一个空的Document
		Document x_doc = DocumentHelper.createDocument();
		//添加跟元素
		Element x_root = x_doc.addElement("xml");
		Iterator<java.util.Map.Entry<String, String>> entries = map.entrySet().iterator();
		while(entries.hasNext())
		{
			Entry<String, String> entry = entries.next();
			String key = entry.getKey();
			Object value = entry.getValue();
			x_root.addElement(key).addCDATA((String) value);
		}
		OutputStream out = new ByteArrayOutputStream();
		OutputFormat format = OutputFormat.createPrettyPrint();
		format.setEncoding("UTF-8"); 
		format.setSuppressDeclaration(true);
		format.setIndent(true);
		format.setNewlines(true);
		XMLWriter xmlWriter = new XMLWriter(out,format);
		xmlWriter.write(x_doc);
		xmlWriter.close();		
		return out.toString();
		
	}

}

消息的接收与回复:

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException
	{
		System.out.println("用户发出信息");
		InputStream input = request.getInputStream();
		try
		{
			//将用户发过来的信息转成map
			Map<String , String> map = TextUtils.xml2Map(input);
			//获取消息内容
			String content = (String) map.get("Content");
			//构造返回的信息
			Map<String , String> reply = new HashMap();
			reply.put("ToUserName", map.get("FromUserName"));
			reply.put("FromUserName", map.get("ToUserName"));
			reply.put("CreateTime", String.valueOf(System.currentTimeMillis()));
			reply.put("MsgType", "text");
			reply.put("Content", "欢迎");
			String str = TextUtils.map2Xml(reply);//将回复的信息转成xml格式的
			//将信息发出去
			OutputStream out = response.getOutputStream();
			out.write(str.getBytes());
			out.close();
		} catch (DocumentException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		
	}

此例子只给出了文本信息的处理,其实对其他类型信息的处理也是大同小异,就不在累赘。具体的消息每个字段代表的含义可参考微信公众开发平台的开发文档。最后也提供源码:链接:https://pan.baidu.com/s/1dkRzEJqrn_MyVvz0RL2WAw 
提取码:ssdv 
有不足之处,希望多多提出宝贵意见。

2017-07-07 10:08:00 weixin_33810302 阅读数 21
    上次是调通了“消息来自微信请求”一个请求验证接口。
    今天下午,正式进军微信开发。完毕了3个案例的demo。測试通过。



    上次。提到读了5本书。4本PHP描写叙述的,一本Java描写叙述的。个人专注Java开发7年了。更倾向于用Java,当然PHP也要马上着手深入学习了。今天好几个PHP的外包项目,感觉太麻烦,都拒绝了。

   Java的书,柳峰写的那本就非常好,至少能够用Good描写叙述,Perfect的话。要看是否还有很多其它更优秀Java语言相关的微信书籍。

   那本书的源代码,网上都有。下载下来之后,所有看懂。

了解一点微信的背景知识,对于懂Java的人来说,非常easy。

   我主要是做了一些重构工作
1.对反复代码进行整理简化。
2.又一次组织代码结构。重命名类、方法、变量。
3.字符串,用枚举类表示。


   很多其它工作。忘了。



  3个案例
1.创建菜单。3个菜单,用过微信的都懂,有button类、链接类、复合类型3种菜单button。
2.站点导航。点击OSChina这个菜单,回复用户一个消息“OSChina,顶天立地的开源站点”。
3. 消息类型,比方用户发送文本消息,就回复“这是一个文本消息”。图片、地理位置等相似。

 账号与调试
1.自己的订阅号XiaoLeiFansUnion,没有通过认证。能够调用的接口非常少。
  想通过认证。必须是企业貌似。眼下银行对公账号还没下来。所以不方便去申请那个服务号等认证。
2.測试号。


  申请一个測试号,关注这个測试号,能够看到实际的效果。
  微信官方提供了一些供开发人员使用的工具,比方检查提供的接口是否正常。
3.server部署測试。


  要搞个对外的域名才好使,使用自己的coderspace.cn,结果被阿里云万网拦截了,由于没有备案。


 仅仅好用我伟大的FansUnion.cn这个账号。


 讲到这。之前在帝都备案的4个域名就有价值了。

 很多其它精彩内容。敬请关注 FansUnion博客(http://fansunion.cn)、九天鸟官方博客(暂时网址为http://blog.fansunion.cn)、QQ空间(http://user.qzone.qq.com/240370818)

2016-10-31 23:25:21 qq137722697 阅读数 144132

微信小程序入门教程+案例demo

尊重原创,转载请注明出处:原文查看惊喜更多 http://blog.csdn.net/qq137722697


首先摆在好姿态,——微信小程序开发也就那么回事。你只需要一点点css(真的只要一点点)的基础就可以了。

认清微信小程序开发

其实,我觉得小程序就是将微信官方提供20+个基础组件(目前有26个)进行排列组合,然后加上一些css样式,对用户的操作进行反馈(调微信官方提供的60+个api)。26个基础组件+60个开放api=半天就搞定了吧?(认真跟着下面的教程走半天足够了)

怎么学?

1、开发工具你得有吧?

这里是最新版下载链接(传送门)—>微信web开发者工具最新版下载地址

目前微信小程序开发工具已经不需要破解都可以了,你只要使用手机端微信扫一扫登录开发工具,在创建应用的时候选择为无APPID就可以开发了。
这里写图片描述

2、开发文档得有吧?

很多人可能觉得看视频要习惯点(CSDN学院的微信小程序实战视频),但是本人建议学新东西不要看视频,入门最好的方式就是看官方文档(还有什么谁比官方自己更懂自己的东西呢!),下面是官网地址:

微信小程序官方文档(传送门)

当然这里推荐看W3CSchool整理的文档,思路相对比较清晰。(再来个传送门

3、基础会了,再来点实战

学完一样东西,最好的方式就是将这个东西付诸于实践,下面进入实战《微信小程序之百思不得其姐(简版)》,如果你能全程跟着做出来,那么你就已经入门成功了。

先看效果图

这里写图片描述

说明这个项目的IDEA是借鉴了这位大哥的,感谢这位大哥

再来看看项目截图
这里写图片描述

具体的代码这里我不就贴了,我把整个项目打包直接下下来就可以用(点我下载DEMO)。

我使用到的图标都是从阿里巴巴的iconfont下载的(之前不知道的简直就是非常大的福利哦,你用了就知道)。

4、项目还不够?

如果你觉得上面的实战还不够激发你的潜能,那么下面给出几个我在学习过程中找的IDEA,希望对你有帮助。

1)、计算器
https://github.com/dunizb/wxapp-sCalc

2)、豆瓣图书
http://www.jianshu.com/p/c35084200470

3)、移动商城
https://github.com/liuxuanqiang/wechat-weapp-mall

4)、天气
http://swiftcafe.io/2016/10/03/wx-weather-app/

5)、空气质量查询
http://blog.csdn.net/yulianlin/article/details/52692066

6)、github客户端
https://blog.zhengxiaowai.cc/post/weapp-demo.html

7)、知乎日报
http://www.apkbus.com/forum.php?mod=viewthread&tid=268626&extra=page%3D1%26filter%3Dsortid%26sortid%3D12


最后

感谢上面提到demo的作者们,共同进步……

2017-11-29 19:42:01 chinaaaaaaaaaaa 阅读数 9608

摘要: WXSS实现了CSS布局相关的大部分规范,但在一些细节上有差异,甚至同样的语法在小程序调试工具和微信中的表现也存在差异。本章主要讲述CSS布局相关的一些基本知识,包括经典的盒子模型、浮动定位、绝对定位以及近几年提出的Flex布局。

原文:https://yq.aliyun.com/articles/90454

本节书摘来自华章出版社《微信小程序:开发入门及案例详解》一 书中的第3章,第3.1节,作者李骏 边思,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

第3章 布局

WXSS实现了CSS布局相关的大部分规范,但在一些细节上有差异,甚至同样的语法在小程序调试工具和微信中的表现也存在差异。本章主要讲述CSS布局相关的一些基本知识,包括经典的盒子模型、浮动定位、绝对定位以及近几年提出的Flex布局。这些基本知识在WXSS也是通用的。对于其他一些特性,开发者可在开发过程中尝试,如果大家想对CSS有更深的了解可以参考网络资料或《CSS权威指南》。这里再次提醒大家,在代码编写过程中一定要开启开发者工具中的这个功能:“开启上传代码时样式文件自动补全”,否则在学习本章Flex布局时会存在不同终端兼容性问题。

3.1 基本知识

3.1.1 盒子模型

盒子模型是CSS布局的基础,CSS假定每个元素都会生成一个或多个矩形框,每个元素框中心都有一个内容区(content),这个内容区周围有内边距(padding)、边框(border)和外边距(margin),这些项默认宽度为0,这个矩形框就是常说的盒子模型,如图3-1所示。
简单来说,HTML中每一个元素就是一个盒子,同理,在小程序中每一个组件就是个盒子,元素的宽度、高度就是内容区域宽度、高度,不包含内边距、边框和外边距,我们可以通过元素width、height、padding、border、margin属性控制盒子样式。盒子模型根据浏览器具体实现可分为W3C的标准盒子模型和IE盒子模型,这两种盒子模型在宽度和高度的计算上不一致,IE盒子模型的宽度和高度是包含内边距和边框的,我们这里讲述的主要是W3C的盒子模型,WXSS完全遵守W3C盒子模型规范。

771801decd46ac31247ab81e7dae3c14c7bcbd60

CSS中的布局都是基于盒子模型,不同类型元素对盒子模型的处理也是不同的,块级元素的处理就和行内元素不同,浮动元素和定位元素的处理也是不相同的,接下来我们逐一讨论这些差异。

3.1.2 块级元素

元素按显示方式主要可以分为块级元素和行内元素,元素的显示方式是由display属性控制的,块级元素会默认占一行高度,一般一行内只有一个块级元素(浮动后除外),当再添加新的块级元素时,新元素会自动换行显示。块级元素一般作为容器出现,用于组织结构。一些元素默认就是块级元素,如小程序中的组件,而一些则默认是行内元素,我们可以通过修改元素display属性为block,将一个元素强制设置为块级元素。一个块级元素的元素框与其父元素的width相同,块级元素的width + marginLeft + marginRight + paddingLeft + paddingRight刚好等于父级元素内容区宽度,显示时默认撑满父元素内容区。块级元素高度由其子元素决定,父级元素高度会随内容元素变化而变化。块级元素特点总结如下:
总是在新行上开始。
宽度默认为width + marginLeft + marginRight + paddingLeft + paddingRight刚好等于父级元素内容区宽度,除非设定一个新宽度,这里需要注意,当设置块级元素宽度为100%时,如果当前块级元素存在padding、margin会导致块级元素溢出父元素。
盒子模型高度默认由内容决定。
盒子模型中高度、宽度及外边距和内边距都可控制。
可以容纳行内元素和其他块级元素。
示例:
<view/>组件默认是块级元素,下面我们使用<view/>为大家演示块级元素的特性,如图3-2所示。

f448cd5adc7da1c4f01cfbfac9b498844c93f5e5

代码如下:

<!-- 每个块级元素占领一行 -->
<view style="border:solid 1px;">第一个块级元素</view>

<!-- 默认情况下块级元素的元素框和父级元素的width相同,刚好撑满内容区 -->
<view style="border:solid 10px; margin : 10px; padding :10px;">第二个块级元素
</view>

<!-- 即使宽度不足,仍会占领一行让其余元素换行 -->
<view style="border:solid 1px; width : 200px;">第三个块级元素</view>
其他信息

<!-- 父级元素高度随内容决定 内容为块级元素-->
<view style="margin-top:10px; border:solid 1px;">
    <view style="height : 100px;">块级元素</view>
</view>

<!-- 父级元素高度随内容决定 内容为文本流情况 -->
<view style="margin-top:10px; border:solid 1px;">
    文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本文本
</view>

块级元素还有很多特性,比如水平格式化、垂直格式化等,我们不在这里一一列举,大家可以查阅相关资料。

3.1.3 行内元素

除了块级元素,最常见的就是行内元素了,通过设置display属性为inline可以将一个元素设置为行内元素,小程序中<text/>就是一个行内组件。行内元素没有块级元素那么简单直接,块级元素只是生成框,通常不允许其他内容与这些框并存,行内元素特点总结如下:
和其他非块级元素都在一行上。
盒子模型中高度、宽度、上下margin、上下padding设置均无效,只能设置左右margin和左右padding。
宽度就是文字或图片的宽度,不可改变。
行内元素宽度、高度都不能直接设置。
行内元素只能容纳文本或其他行内元素,在行内元素中放置块级元素会引起不必要的混乱。
如图3-3中的示例,大家可以对比本例中块级元素和行内元素的区别,我们设置了行内元素的margin,布局时上下margin都被忽略了。本例中我们将上下padding设置为0,大家可以尝试设置为其他值,这时会发现上下padding会生效,但是不会影响布局,本例中行内元素换行是因为上面的块级元素强制占位一行。

85de1105f28b232cdc02f8d60210041242cb3ff3

本例的代码如下:

<!-- 块级元素 -->
<view style="border:solid 1px #999; color : #999;">我是块级元素我是块级元素我是块级元素我是块级元素我是块级元素</view>

<!-- 通过修改display属性的行内元素 -->
前面的文字<view style="border:solid 1px; margin:10px; padding : 0 10px; display: inline;">我是块级元素我是块级元素我是块级元素我是块级元素我是块级元素</view>后面的文字

3.1.4 行内块元素

行内块元素是块级元素和行内元素的混合物,当display属性为inline-block时,元素就被设置为一个行内块元素,行内块元素可以设置宽、高、内边距和外边距,可以简单认为行内块元素是把块级元素以行的形式展现,保留了块级元素对宽、高、内边距、外边距的设置,它就像一张图一样放在一个文本行中,如图3-4所示。

6e59e0f292347448b99d2b72ced93590a71aff4d

代码如下:

<!-- 行内块元素宽度撑满父级宽度情况 -->
前面的文字<view style="border:solid 1px; margin:10px; padding : 10px; display:inline-block;">我是块级元素我是块级元素我是块级元素我是块级元素我是块级元素</view>后面的文字

<!-- 行内块元素宽度不足父级宽度情况 -->
前面的文字<view style="border:solid 1px; margin: 10px; padding : 10px; display: inline-block;">我是行内块元素</view>后面的文字后面的文字后面的文字