小程序学习笔记之代码构成与框架结构
导言
小程序的项目代码文件大致分为JSON配置文件、WXML模板文件、WXSS样式文件、JS脚本逻辑文件。
小程序的框架MINA的核心是一个响应的数据绑定系统,也体现了MVVM的开发模式。小程序并不是“正宗”的MVVM,它是单向绑定的。
代码构成
项目目录
官方提供的quickstart例子的项目目录如下
wx_quickstart
├── app.js
├── app.json
├── app.wxss
├── pages
│ ├── index
│ │ ├── index.js
│ │ ├── index.wxml
│ │ └── index.wxss
│ └── logs
│ ├── logs.js
│ ├── logs.json
│ ├── logs.wxml
│ └── logs.wxss
├── project.config.json
└── utils
└── util.js
可以看到,文件大致分为这4种
- .json 后缀的 JSON 配置文件
- .wxml 后缀的 WXML 模板文件
- .wxss 后缀的 WXSS 样式文件
- .js 后缀的 JS 脚本逻辑文件
app.json
以下是一个包含了所有配置选项的app.json。
配置了页面文件的路径、窗口表现、设置网络超时时间、设置多tab等。
1 | { |
wxml
wxml (WeiXin Markup Language)是框架设计的一套标签语言,结合基础组件、事件系统,可以构建出页面的结构。它的作用和html
一样,都是负责页面的结构。
基础组件包括:视图容器、基础内容、表单组件、导航、媒体组件、地图、画布、开放能力等。详细可以看官方文档的组件介绍。
wxml的能力主要有以下几点:
- 数据绑定
使用 Mustache 语法(双大括号)将变量包起来,可以在双大括号内进行简单的运算,如三元运算等 - 列表渲染
在组件上使用wx:for
控制属性绑定一个数组,即可使用数组中各项的数据重复渲染该组件。 - 条件渲染
在框架中,使用wx:if
来判断是否需要渲染该代码块 - 模板
wxml提供模板(template),可以在模板中定义代码片段,然后在不同的地方调用。 - 事件
wxml的冒泡事件有:touchstart
、tap
、longpress
、transitionend
、touchforcechange
等,触摸类事件支持捕获阶段。
可以在组件中绑定一个事件处理函数,事件绑定的写法以 key、value 的形式。key是bind
则是普通的事件绑定,如bindtap
或bind:tap
;catch
事件绑定可以阻止冒泡事件向上冒泡;capture-bind
在捕获阶段监听事件;capture-catch
则中断捕获阶段和取消冒泡阶段。
wxss
wxss (WeiXin Style Sheets)是一套样式语言,用于描述WXML
的组件样式。它的作用和css
一样,都是负责页面的样式。
与css
相比,wxss的特性有
尺寸单位
rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx (iphone6) 。即,以750rpx为基准,对于不同大小的屏幕放大或缩小。因此,设计师可以用 iPhone6 作为视觉稿的标准。
样式导入
使用@import语句可以导入外联样式表。选择器
比起css
,只支持部分选择器,包括.class
、#id
、element
、element, element
、::after
、::before
全局样式与局部样式
定义在 app.wxss 中的样式为全局样式,作用于每一个页面。在 page 的 wxss 文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 app.wxss 中相同的选择器。本地资源无法通过 css 获取
因此,在设置background-image
属性时,可以使用网络图片,或者 base64,或者使用标签代替;在设置 @font-face
的src
属性时,需要把字体文件转换成base64,可以到https://transfonter.org/转换。
js
需要注意的一点是:小程序的js运行环境是JsCore,不是浏览器,不能使用window与document对象。zepto
/jquery
会使用到window对象和document对象,所以也无法使用。
JsCore(JavaScriptCore)
对JS进行解析和提供执行环境。iOS7后苹果推出,极大地方便了我们对js的操作。我们可以脱离webview直接运行我们的js。JSCore 只是实现了标准 JavaScript 语言,所以也自然就没有浏览器对象(BOM)等。微信小程序框架的native端与js端通过JsCore来相互通信。
框架结构
MINA
小程序的框架MINA的核心是一个响应的数据绑定系统,也体现了MVVM的开发模式(例如 React, Vue)的思想。
下面就是MVVM的框架结构
- View:视图
- ViewModel:与视图数据绑定;获取Model的变更,在必要时更新View
- Model:数据(与后端的沟通、AJAX请求以及对数据的处理)
小程序的框架结构如下:
渲染的过程是这样的:
- 提供了JavsScript运行环境(JsCore),由JavaScript编写的业务代码完成逻辑层的处理
- 通过数据传输接口(注册Page时的data属性及后续的setData方法调用)将逻辑层的数据传输给视图层。
- 视图层由WXML语言编写的模板通过“数据绑定”与逻辑层传输过来的数据merge成展现结果并展现
- 视图的样式控制由WXSS语言编写的样式规则进行配置
与Vue的区别
最大的区别就是,小程序并不是“正宗”的MVVM。在数据绑定上,它是单向绑定的。而vue是双向的。
如要实现一个提供一个输入框,并且把用户的输入同步显示到视图,如下图
在vue中是这样实现的:
1 | <div id="app"> |
1 | var app = new Vue({ |
在小程序中是这样实现的
1 | <view class="section"> |
1 | Page({ |
因为,微信小程序的JS逻辑层与视图层分散在两个不同的上下文环境中(JS逻辑跑在JsCore中,视图层的渲染包括模板渲染、样式应用、事件派发却都在native环境中)。所以数据对象(view-model)在两层间没有共享,并且同步通信的成本太高。
因此,微信小程序在初始化之后,再对原来的数据对象进行任何更改,都始终不会生效,需要调用setData
。以及,在事件冒泡的阻止上,微信小程序在监听时即决定是否阻止事件冒泡。