前端笔记之微信小程序(一)初识微信小程序&WXSS与CSS|WXML与HTML的差异&像素和DPR
一、小程序概述
2017 年 1 月 9 日小程序正式上线,腾讯开放了个人开发者开发小程序,小程序从此就开始火爆,这一年,小程序狂揽 4 亿用户、1.7 亿的日常活跃,上线 58 万个。这是一个巨大的机会,对于企业宣传,拉新用户存在变革性的影响。
小程序的本质是:轻应用,就是不用安装就能使用的手机app。
“跳一跳”养成了大家下拉寻找常用小程序的习惯。
小程序对开发者而言也是非常友好的。
微信就是一个“虚拟机”,小程序使用javascript编程,小程序将javascript翻译为机器能够识别的java、oc等语言,能操作硬件,比如蜂鸣器、陀螺仪、相册、闪关灯、摄像头。
小程序屏蔽了手机操作系统之间的差异,我们写ios的小程序、安卓的小程序是不需要考虑系统的差异的。
二、小程序开发账号注册
一个人最多只能有5个小程序项目,只能有5个小程序appid,公司账户可以有20个小程序项目。
去自己的邮箱点击激活右键的超级链接:
然后在打开的页面选择个人开发者,需要让你填写身份证号码和用户真实姓名,这里为了隐私就不截图了。
三、获得appid下载使用开发者工具
登录
3.1 添加小程序信息
3.2 添加开发者
可以有15个人为我们的小程序进行测试。
最高管理员有所有的权限:
添加了一些同学当做体验者权限:
3.3 获得appid
即可看到appid,备份好。
3.4 开发者工具
微信官方的开发者工具,集项目创建、开发、调试于一身。
下载地址:
安装完毕之后,使用:
勾选「建立普通快速启动模板」后,会为项目生成一份hello world代码,这样可以方便我们了解小程序框架的代码目录结构。你也可以对比看看不勾选时建立的空项目是如何的。
微信小程序开发工具集成度很高:
实时调试热更新
脚手架起步
预览自动打包
控制台有网络请求和console,集成了chrome浏览器的功能
由于开发条件的限制,不可能对所有尺寸手机的屏幕进行测试,但往往很多bug出现在屏幕适配的问题上,所以这些提供了很多屏幕尺寸进行测试。
四、小程序程序开发初步
4.1 认识默认的文件夹结构
当创建“默认普通快速启动模板”之后,项目会自动创建了一些文件。把这样的能够帮我们起步的工具叫做“脚手架”。react,有脚手架react-cli。vue有脚手架vue-cli,还有第三方脚手架,比如yeoman。
零散文件:
app.js |
微信小程序本质上javascript开发,程序都是.js结尾的。 app.js这个文件是整个小程序的第一个入口文件。写法必须是app({})。 app函数是小程序内置的,每个项目必须有且只能有一个,必须出现在app.js中。大括号中描述这个app的一些生命周期和全局数据。 |
app.json |
小程序当前项目的“程序配置”。可以配置小程序有哪些页面,标题栏,tab栏等内容。 |
app.wxss |
小程序的全局的样式表,小程序使用wxss而不是css,基本上和css差不多。这个样式表是所有页面都能够看见的样式。 |
project.config.json 项目配置文件 |
通常大家在使用一个工具的时候,都会针对各自喜好做一些个性化配置,例如界面颜色、编译配置等,当你换另外一台电脑重新安装工具时,还要重新配置。 project.config.json文件就是为了减少开发者重复配置开发工具而产生的,通过json数据格式,每个小程序项目都在配置文件里定义了开发者习惯的配置参数,无论开发环境如何变更,只要载入同一个项目的代码包,开发者工具就通过project.config.json自动恢复开发项目的个性化配置,其中会包括编辑器的颜色、编辑设置、代码上传时自动压缩等等一系列选项。 关于其他配置项细节可以参考文档「开发者工具的配置」 。 事实上这个文件不需要手动更改,可以在菜单中可视化面板进行更改。
|
page.json页面配置文件 |
作为页面的个性化配置,page.json里只能定义app.json中window 相关的配置项,这部份比较简单,可以直接参考文档「小程序的配置 page.json」,这里不作赘述。 |
删除app.js文件大括号中的默认配置:
app({ });
看一下pages文件夹,文件夹中的子文件夹就是小程序的一个个页面。一个页面就是一个文件夹。
每个页面文件夹中,有四个文件,都是同名文件。
.js |
页面的程序逻辑 |
.json |
页面的配置 |
.wxml |
页面的结构,类似于html |
.wxss |
页面的样式表 |
将index.wxml的页面删除干净:
<view class="container"> <view>你好,我是小程序</view> </view>
将index.js文件删干净:
page({ });
这里page函数是内置的函数,表示创建一个页面。大括号中的内容是页面的一些生命周期、数据。
删除logs文件页面,和utils文件夹,此时项目非常干净:
4.2 app.json全局配置
每个小程序都是由多个页面组成的,但在这些页面之上,存在被所有页面共用的内容,比如标题颜色,网络超时设置等,这些被统称为「全局配置」,而app.json文件里保存的就是这些配置内容。
「全局配置」包含5个部份,包括 :
pages 「页面路径」:用于指定小程序里所有页面对应的目录路径,只有加入到这个配置项里,页面才会生效
window「窗口表现」:用于指定小程序窗口的外观表现,比如上面提到的标题颜色、背景颜色等等
tabbar「底部tab」:小程序允放进开发者设置底部tab进行页面切换,这个配置项就是用于定义底部tab按钮样式。
networktimeout「网络请求超时」:在开发小程序的开发过程中,不可避免会出现网络请求失败的情况,如果没有设置一个网络超时时间,在出现错误的时候,小程序就会一直等待请求响应数据,如果有了超时时间,在超过设置的时间没有收到数据时,我们可以为用户输出异常反馈信息,并引导用户后续可以尝试的操作,提高程序代码的可用性
debug「调试模式」:开启调试模式时,调试信息会输出到控制台里,包括页面路由,数据更新,事件触发等,可以帮助开发者快速定位常见问题。
关于其他配置项细节可以参考文档「小程序的配置 app.json」 。
手册:
4.2.1 pages配置
接受一个数组,每一项都是字符串,来指定小程序由哪些页面组成。每一项代表对应页面的【路径+文件名】信息,数组的第一项代表小程序的初始页面。小程序中新增/减少页面,都需要对 pages 数组进行修改。
文件名不需要写文件后缀,因为框架会自动去寻找路径下 .json, .js, .wxml, .wxss 四个文件进行整合。
4.2.2 window配置
写程序就两个东西:api、算法,api不用背,算法忘不掉。
{ "pages": [ "pages/index/index", "pages/haha/haha" ], "window": { "backgroundtextstyle": "light", "navigationbarbackgroundcolor": "#2bb", "navigationbartitletext": "小灰灰的家", "navigationbartextstyle": "white", "backgroundcolor" : "#eee" } }
4.2.3 tabbar配置
tabbar的属性:
其中list属性数组项的属性:
更改之后的完整的app.json文件:
{ "pages":[ "pages/index/index", "pages/meishi/meishi", "pages/lvyou/lvyou" ], "window":{ "backgroundtextstyle":"light", "navigationbarbackgroundcolor": "#2bb", "navigationbartitletext": "wechat", "navigationbartextstyle":"black" }, "tabbar": { "color": "#eee", "selectedcolor": "#2bb", "backgroundcolor": "#fff", "list": [ { "text": "首页", "pagepath": "pages/index/index", "iconpath": "images/i1_a.png", "selectediconpath" : "images/i1_b.png" }, { "text": "美食", "pagepath": "pages/meishi/meishi", "iconpath": "images/i2_a.png", "selectediconpath": "images/i2_b.png" }, { "text": "旅游", "pagepath": "pages/lvyou/lvyou", "iconpath": "images/i3_a.png", "selectediconpath": "images/i3_b.png" } ] } }
4.3小程序开发语言
小程序采用 wxml + wxss + js 三种开发语言组合,其和网页编程采用的 html + css + js 类似,wxml 用来描述当前这个页面的结构,wxss 用来描述页面的样式,js 用来处理这个页面和用户的交互。
4.3.1 wxml
wxml(wexin markup language)和 html 类似,也有标签和属性,但针对小程序平台做了些优化。
相较 html,小程序的标签显得更加简洁,比如 div、section、header等块级标签统一为view、p、span、b 等文案类标签统一为text,同时新增很多实用标签,比如 picker 滚动选择器、map 地图、web-view 网页容器等。
可以简单理解为,小程序所有的标签都是原生组件。
4.3.2 wxss
wxss(wexin style sheets)是微信定义的一套样式语言,其具有 css 大部分特性,同时为了更适合开发微信小程序,wxss 对 css 进行了扩充以及修改。
小程序使用 rpx(responsive pixel)作为尺寸单位。屏幕宽度固定为 750rpx,设置了 rpx 单位的元素可以根据屏幕宽度进行自适应,所以设计稿统一以 750px 输出(iphone 6 标准)。
小程序没有 html 、body标签,如果想要设置页面的样式,可以直接使用 page 选择器:
page{ background: #ffffff; }
4.3.3 javascript
小程序中javascript没有 window、document 等变量,大部分浏览器中全局方法会被禁用,比如 alert。但也有部分被支持,比如 settimeout、encodeuricomponent等,具体可以在开发者工具中尝试使用,官方文档并没有详细的介绍。
五、wxss与css的开发差异
5.1选择器
小程序官网上只列出6种可支持的选择器,实际上可支持的选择器很多。通过图表,我们可以对比wxss与css选择器的差异:
选择器 |
wxss官方公布可用 |
目前wxss版本实际可用 |
css版本可用 |
.class |
o |
o |
css1 |
#id |
o |
o |
css1 |
* |
x |
x |
css2 |
element |
o |
o |
css1 |
element,element |
o |
o |
css1 |
element element |
x |
o |
css1 |
element>element |
x |
x |
css2 |
element+element |
x |
x |
css2 |
element1~element2 |
x |
x |
css3 |
[attribute] |
x |
x |
css2 |
[attribute=value] |
x |
x |
css2 |
[attribute-=value] |
x |
x |
css2 |
[attribute\=value] |
x |
x |
css2 |
:link |
x |
x |
css1 |
:visit |
x |
x |
css1 |
:active |
o |
o |
css1 |
:hover |
x |
x |
css1 |
:focus |
x |
o |
css2 |
:first-letter |
x |
o |
css1 |
:first-line |
x |
o |
css1 |
:first-child |
x |
o |
css2 |
:last-child |
x |
o |
css3 |
:before |
o |
o |
css2 |
:after |
o |
o |
css2 |
:lang |
x |
x |
css2 |
:first-of-type |
x |
o |
css3 |
:last-of-type |
x |
o |
css3 |
:only-of-type |
x |
o |
css3 |
:only-child |
x |
o |
css3 |
:nth-child(n) |
x |
x |
css3 |
:nth-last-child(n) |
x |
x |
css3 |
:nth-of-type(n) |
x |
x |
css3 |
:nth-last-of-type(n) |
x |
x |
css3 |
:root |
x |
o |
css3 |
:empty |
x |
x |
css3 |
:target |
x |
x |
css3 |
:enabled |
x |
x |
css3 |
:disabled |
x |
x |
css3 |
:checked |
x |
x |
css3 |
:not(selected) |
x |
x |
css3 |
::selection |
x |
x |
css3 |
注:表格中的可用性是经过测试得出,小程序升级迭代可能发生变化。
5.2适配
rpx,即responsive pixel,是微信小程序团队推出的弹性单位。它规定屏幕宽度为750rpx,可以根据屏幕宽度进行自适应。
rpx最大的优势在于,宽度为750px的设计稿不再需要进行任何转换即可完成适配。750px的设计稿上,量出来是多少px,就是多少rpx。举个例子,iphone6的屏幕宽度为375px,共有750个物理像素,也就是1px有2个物理像素,则750rpx=375px=750物理像素,即:1rpx=0.5px=1物理像素。
如果设计稿尺寸为640px,那么1px=640/750rpx,。所以小程序的视觉设计稿应该尽量使用750px。
另外,微信小程序也支持rem尺寸单位,rem和rpx的换算关系:
rem: 规定屏幕宽度为20rem;
在宽度为750px的设计稿中,1rem = (750/20)rpx = 37.5px;
在宽度为640px的设计稿中,1rem = (640/20)rpx = 32px。
rpx实际上就是系统级的rem(把页面按比例分割750份,1rpx=window.innerwidth/750),或者scale伸缩布局的width=750。也就是说,微信小程序的rpx帮大家把rem中设置根元素字体尺寸这步省了,或者减少了scale伸缩布局不能开启gpu raster的问题。
5.3样式级联
表格中提到的“element element”,是一种常见的级联方式。
<!-- wxml-->
上面一段代码中,我们让图片具2像素,色值为#f00的实线边框,该怎么写样式呢?
首先来看级联写法:
view image{ border:2px solid #f00 }
很明显,这样的写法非常低效。更高效的写法应该为:
.demo_img_1{ border:2px solid #f00 }
在wxss中,虽然现在还能使用级联写法,但从提高wxss性能的角度上看,建议大家尽量不适用级联。微信小程序团队推荐使用bem,即block(块)、element(元素)、modifier(修饰符),是有yandex团队提出的cssclass命名方法。
六、wxml与html
归根结底,小程序的页面与h5网页,一样是运行在客户端webview组件中的,而这些页面也同样经过脚本引擎和渲染引擎处理。那为什么不能直接沿用网页的html+css+javascript的组合呢?wxml与html的差异主要体现在哪些地方?
6.1小程序沙盒模型
随着前端开发技术的发展,h5页面的能力越来越大,我们既可以利用indexeddb建立浏览器本地数据库,也可以通过webrtc进行网络间点对点实时通信,甚至于利用filereader和blob等对本地文件进行读取和修改等操作。另一方面,小程序在设计上,也需要为开发者提供许多微信独有的api,比如获取用户微信昵称,调用微信支付接口等等。如果这些api与现有的前端能力相结合,开发者的能力将被极大扩展,更可能超过微信保护用户的可控范围。为了在“保护用户数据”和“对开发者开放能力”之间找到平衡,自然有必要把这两者放在自己力所能及的「沙盒模型」中实现。而这个沙盒,也就是我们的小程序框架,我们使用wxml+wxss+javascript构建的小程序,都是运行在这个沙盒模型中。
6.2组件化
传统的网页开发,是使用html进行页面构建的,开发者经常会用到div、span、ul/li等标签进行页面布局,这些基础标签通过互相结合并与css定义的样式搭配,从而实现许多功能组件,比如用户确认窗口、日历选择器、滑动广告板等等。在小程序中,开发者同样也会用到标签,但这些标签,已经过微信的一层封装,以组件的形式提供给开发者使用,每个组件都会实现自己特有的功能,提高了开发效率,而布局一般是采用view组件来实现。「组件化」使wxml标签更具语义,通过名称就可以知道组件的具体功能。
6.3数据绑定
wxml还有一个特点与html有所不同,就是「数据绑定」。传统的html需要通过javascript对dom结点进行操作,才能动态改变页面内容。而在wxml里,数据可以跟页面结构进行绑定,javascript只对数据进行操作,而这些数据的修改,最终会反馈给绑定数据的页面结构并动态更新。这种机制类似于vue.js的声明式渲染,实现了页面和数据的分离。
6.4逻辑控制
在wxml里,我们还可以通过特定的语法对结构进行逻辑控制,包括条件控制和循环控制,使页面开发更加灵活。而html只能依赖于javascript生成或删除结构,开发人员不只要关心数据,还要关心对页面结构的操作,数据和展示往往耦合在一起,增加管理代码的成本。
七、像素和dpr
在web开发的过程中,经常会提到「像素」这个词,那么,像素到底是什么?移动端的像素与桌面端是否有区别?同样大小的手机屏幕,为什么有的像素高,有的像素低?下面让我们通过资料阅读找到这些问题的答案吧。
7.1像素的定义
「像素」是图像显示的基本单位,译自英文「pixel」,一个像素就是屏幕上能够显示一种特定颜色的最小区域。如下图右侧图片中,每一小格子代表一像素:
当设备尺寸相同,但像素变得更密集时,屏幕能显示的画面过渡更细致,图像看起来就更清晰明快。由此定义了「屏幕像素密度ppi(pixel per inch)」,用于代表屏幕上每英寸可以显示的像素点的数量:
7.2像素的分类
像素实际上分为两种:
1.物理像素:又称设备像素(device pixels),指设备屏幕的物理像素,一个屏幕里的物理像素数量是固定的。
2. 逻辑像素:又称css像素(css pixels),是为web开发而创造的抽象概念,用于在css和javascript中以「px」描述位置、大小和间距的单位尺寸。
由于不同的设备屏幕,特别是移动端手机屏幕尺寸千差万别,物理像素也不一而同,在web开发过程中都是使用逻辑像素,物理像素很少会被用到。
随着移动设备屏幕技术的发展,手机的ppi(屏幕像素密度)越来越高。一个典型的例子就是,从iphone4开始,苹果公司推出了retina视网膜屏幕。之所以叫做视网膜屏幕,是因为屏幕的ppi太高,人的视网膜无法分辨出屏幕上的像素点。iphone4的ppi提高了一倍,但屏幕尺寸却没有变化,这意味着同样大小的屏幕上,像素多了一倍。
像素的增加对于同样大小的网页图像,在旧手机里全屏展示,在新手机里却只需要一半的屏幕就显示出来了,剩下的另一半屏幕将成为空白,这降低了web用户的体验。如何适配不同的手机屏幕,成为web开发者需要关心的问题。
7.3 dpr
设备像素比dpr(devicepixelratio),是指默认屏幕内容无缩放时,物理像素和逻辑像素的比值:
dpr = 物理像素 / 逻辑像素
在javascript里可以通过window.devicepixelratio获取到用户设备的dpr值。
7.4屏幕适配方案
了解了dpr的概念之后,我们就可以通过规则,将逻辑像素进行相应的转换,满足不同屏幕的显示需要,具体规则如下:
当dpr为1时,使用1(1×1)个物理像素显示1个逻辑像素;
当dpr为2时,使用4(2×2)个物理像素显示1个逻辑像素;
当dpr为3时,使用9(3×3)个物理像素显示1个逻辑像素。
图示如下:
对应到web开发中,就是需要根据不同的dpr缩放网页内容,计算公式为:
图片缩放尺寸 = 图片逻辑像素 x dpr
具体以iphone6为例,其屏幕宽度的物理像素共750个,逻辑像素是375px,所以dpr = 750 / 375 = 2,为了适配iphone6,应该使用2倍大小的图片进行展示。
小程序为开发者提供了更方便的像素单位「rpx(responsive pixel)」实现屏幕适配,在后续的小程序课程里我们再详细讲解其使用方法。
7.5自定义屏幕尺寸
如何知道自己手机屏幕尺寸?
1、通过手机购买网站查询手机屏幕的「物理像素」(分辨率);
2、使用微信的示例小程序获取手机屏幕的逻辑像素:
微信扫码进入 – 底部「接口」按钮 – 「设备」选项 - 「获取手机系统信息」选项 - 「获取手机系统信息」按钮 – 「屏幕宽度」和「屏幕高度」。
计算dpr后在下图所示入口进行尺寸设置。