「大众点评点餐」小程序开发经验 02:视图

文 | 何延希

何延希,美团点评工程师,4 年 web 开发经验,现在是美团点评点餐团队的一员。

上一期,知晓程序(微信号 zxcx0101)与大家分享了「大众点评点餐」小程序团队带来的小程序技术分析。

本期,我们想要和大家分享下大众点评点餐小程序中,有关 View 视图层的一些开发经验。

本文部分示例来自于「大众点评点餐」小程序的菜单页面。

页面代码结构为:

我们将要说的小程序的 View 视图层,是由 WXML(menu.html)与 WXSS(menu.less)两大部分组成,由组件——也就是视图的最小单元——进行展示。

视图层将逻辑层的数据(menu.jsmenu.json)反应为视图,同时将视图层中定义的事件发送给逻辑层。

WXML

WXML(WeiXin Markup Language)与 HTML 对应,用于描述页面的结构,可以类比 React 的 JSX。项目中 menu.html 使用 WXML 语法,一个页面的顶层是 page 节点。

在 WXML 中获取逻辑层定义的数据后,我们通过一系列自己的语法和逻辑展示出这些数据。

结构上,组件是视图层的最小单元。我们可以通过以下方式,进行动态渲染。

1. 数据绑定

数据绑定是最简单的使用数据方式。采用 Mustache 语法的变量替换,用双大括号将变量名包起来,包括组件的属性也可以使用变量。

小程序还支持 ES 6 规范的扩展运算符 ... 和解构赋值。

2. 逻辑运算

双大括号中,可进行一些简单运算操作,包括四则运算、三目运算、逻辑判断、字符串拼接等。

3. 条件渲染

与通常将渲染内容写在 ifelse 判断条件中不同,小程序的条件渲染,要求将条件直接写在相应组件的 wx:ifwx:else 属性中。

如果渲染组件为多个,可将多个组件放在组件内,渲染条件置于 <block> 组件的 wx:ifwx:else 属性中。此时的组件,只充当容器作用,页面中不会渲染。

我们来看条件渲染实际应用的例子:

用上 <block> 的实例:

4. 列表渲染

列表渲染,是将元素进行遍历,并利用 wx:for 属性值进行循环渲染。

与此相关的还有以下几个属性:

  • wx:key:遍历元素的唯一的标识符,主要用于数据动态变化时,DOM 的更新机制。数据不变,则可无视。
  • wx:for-item:遍历元素的变量名,默认值为 item。
  • wx:for-index:遍历元素下标的变量名,默认 index。

以上属性的值都可以用字符串,但值中不要使用 - 等符号。例如 dish-item,在使用时,小程序会将 {{dish-item}} 中的 - 解析成减号,造成取值失败。

在这里,我们利用测试数据举个例子:

以上代码结构上分为两层:

  • 第一层 block 循环遍历 testData 数组,每个遍历值变量名为 mainitem
  • 第二层 view 循环遍历 mainitem 数组,每个遍历值变量名为 subitem,展示第一层 index、第二层 idname 属性。

展示结果:

循环遍历时,除官方说明的数组类型可以循环遍历外,对象类型也可通过 wx:for 进行属性遍历。此时 for-index 为属性的 key 值。

例如,在上面例子中,将 testData 换成对象类型:

结果为:

5. 模板 & 引用

小程序中的模板,概念类似于 React 中的组件(components)。

我们可以在模板中定义代码片段,然后在不同的地方进行调用,减少重复的代码量。

如何定义一个模板呢?我们使用 name 属性,作为模板的名字,然后在 <template/> 内定义模板代码片段就可以了

定义后的使用方式有 2 种:

  • 使用 include 方式,将目标文件除了 <template/> 部分外的整个代码引入。这样的操作,相当于是将整个文件里的代码拷贝到 include 位置,所以无法传入参数。
  • 使用 import 方式,引入定义的文件,然后通过 <template/> 组件的 is 属性,声明需要的使用的模板,然后将模板所需要的 data 传入。这样的模板拥有自己的作用域,只能使用 data 传入的数据。

需要注意的几个地方:

  • 小程序只会 import 目标文件中定义的 <template/>,不能引用目标文件中引用的 <template/>
  • 小程序的模板中,只能单向使用传入的数据,不像 React 可以利用 props 让父子组件进行传值。

我们以单个菜品组件为例,看看如何在小程序中使用模板:

6. 绑定事件

事件名称为字符串,会默认传入 event 参数,无法定制其他参数。

我们一般将所需参数通过 data- 属性,绑定至组件,再通过 e.currentTarget.dataset 获取。例如这样:

WXSS

WXSS(WeiXin Style Sheet)与 CSS 对应,用于描述页面的样式。

定义在 app.less 中的样式为全局样式,可作用于每一个页面。

在页面里的样式文件中定义的样式为局部样式,只作用在对应的页面,并会覆盖 app.less 中相同的选择器。例如,代码结构中 menu.less 能且只能作用于 menu.html

1. 支持的特性

WXSS 支持内联样式和选择器两种特性。

小程序组件的 style 可以接收动态的样式,会在运行时会进行解析。但请尽量避免将静态的样式写进 style 中,以免影响渲染速度。

WXSS 支持选择器。对于常用的选择器,小程序目前支持以下这些:

目前不支持的选择器有:

此外,还有几个需要注意的地方:

  • 如之前提到,页面的顶层是节点,所以想要修改作用于整个页面的样式、顶层节点样式,请使用 page 选择器。
  • 小程序目前不支持 Media Query。

2. 扩展的特性

在 CSS 的基础上,WXSS 还扩展了几个特性。

首先是尺寸单位 RPX。这是小程序自创的单位,可以根据屏幕宽度进行自适应。

RPX 将所有手机的屏幕宽度规定为 750 rpx。例如,在 屏幕宽度为 375 px 的 iPhone 6 上,换算出来 1 rpx = 0.5 px = 1 物理像素。

我们建议设计师在开发微信小程序时,可以用 iPhone 6 作为视觉稿的标准。

另外,由于数值较小时渲染时会存在四舍五入的情况,在较小屏幕上差距会很大,所以要求精确而较小的视图内容需避免使用此单位。

例如,下图所示菜品的减号操作图标的高度,iPhone 6 下是 2 px,iPhone 4s 下直接渲染成了1 px(实际比例值为 1.7 px)。

而加号按钮图标高度,在 iPhone 6 下是 11 px,iPhone 4s 下,就渲染成了 9 px(实际比例值为 9.48 px)。

这样的差距,就会让小程序在两台手机上,看起来不那么协调了。

关注微信号 zxcx0101,在后台回复「rpx」,一篇文章带你看懂 RPX。

此外,在小程序中使用 @import 语句,可以导入外联样式表

具体的使用方式是:在 @import 后,写上需要导入的外联样式表的相对路径,用 ; 符号表示语句结束。

组件

如前面 WXML 部分中所述,组件是视图层的基本组成单元

它与 HTML 中的标签类似,基于 Web Component 标准,属性和内容的使用方法也和 HTML 标签类似。

组件名称和属性名称,都必须使用小写。

1. 组件列表

2. 原生组件

如上统计,inputtextareavideomapcanvas 均为系统原生组件。

原生组件相对来说性能和用户交互方面会有所提升。

以部分机型 input 元素 fixed 时唤起键盘被遮挡的问题举例,在某魅族机型上 HTML 5 页面中,父元素 fixed 的输入框会被遮挡:

在同一机型中,小程序里的输入框就不会被遮挡。

3. 组件属性

小程序的组件中,支持以下的数据类型:

  • Boolean:布尔值
  • Number:数字
  • String:字符
  • Array:数组
  • Object:对象
  • EventHandler:事件处理函数名,事件绑定属性(如 bindtap
  • Any:任意属性(不是很明白是什么意思)

所有组件都有的共同属性:

  • id:组件的唯一标识
  • class:组件的样式类,和在 WXSS 中定义的类选择器对应
  • style:内联样式
  • hidden:组件隐藏或显示
  • data-*:自定义属性,可传入自定义数据。逻辑层事件处理函数中,可通过 e.currentTarget.dataset 获取。
  • bindcatch:都是事件绑定,差别在于:bind 不会阻止事件向上冒泡,catch 可以阻止事件向上冒泡。

此外,各个组件都有自定义的特殊属性,如 <icon> 组件的 size 属性。你可以在官方文档中查阅每个组件的不同属性。

兼容性

根据官方文档的说明:

  • 在 iOS 上,小程序的 JavaScript 代码是运行在JavaScriptCore 中,是由 WKWebView 进行渲染,可用环境有 iOS 8、iOS 9、iOS 10。
  • 在 Android 上,小程序的 JavaScript 代码通过 X5 JSCore 解析,由 X5 基于Mobile Chrome 37 内核进行渲染;
  • 在开发工具上,小程序的 JavaScript 代码运行在 NW.js,由 Chrome WebView 进行渲染。

由于内核渲染表现不一致,在开发过程中,存在于 X5 浏览器和各类机型或系统的兼容性问题,一部分会在小程序中存在。

性能优化

前端常用的模板方案一般有 2 种:

  • 将模板编译成 JS 函数代码,通过字符串拼接的方式生成渲染的 DOM 节点。例如:Mustache / tpl(点评内部开发使用),数据更改时,会将 DOM 节点全部更新。
  • 字符串 parse 和 compile 后拼接渲染外,有自己的 DOM 节点更新机制。例如:Vue.js / React等,数据更改时通过 DOM Diff 算法更新 DOM 节点。

当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件。框架会确保他们被重新排序,而不是重新创建。

这样做,我们可以确保组件保持自身的状态,并且提高列表渲染时的效率。

小程序对组件的渲染方式我们不得而知,只能对开发中碰到的一些问题来推测。

结合小程序对列表渲染 wx:key 的解释,可知小程序的模板渲染属于第二种,数据更新时会根据 key 进行渲染优化

但小程序官方未提供相关接口或性能调试工具,所以项目中我们只能自己尝试不同方案然后对比渲染速度。

以菜单页面为例,商户菜品数量多者成百上千,优化后的效果对比还是比较明显。

由以上的描述,我们可以得出以下的优化建议:

  • 在菜单页面,将菜品数据扁平化为一层,并合理利用 key 值。
  • 设计组件结构时采用精简的组件结构,减少渲染时的数据遍历和组件嵌套深度带来的性能消耗。
  • 将数据变动的组件与数据不变的组件进行拆分,减少数据更改带来的组件更新量,如将加减按钮和菜品信息分离。
  • 使用动态加载等方式减小首屏渲染数据量,提升用户体验。

原文地址:https://juejin.im/post/58affbff2f301e006cfc5b46

本文由知晓程序授权转载,关注微信号 zxcx0101,在微信后台回复「点餐」,获取「大众点评点餐」小程序全套开发经验。

原文发布于微信公众号 - 知晓程序(zxcx0101)

原文发表时间:2017-03-16

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏编程思想之路

Android6.0源码分析之View(一)

目前对于view还处于学习阶段,本来打算学习结束之后再写一篇进行总结,但是发现自己自制力太差,学习效率太低,所以在此,边学边写博客,不仅督促自己完成对view的...

1758
来自专栏DannyHoo的专栏

问题——持续更新

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010105969/article/details/...

672
来自专栏从零开始学 Web 前端

从零开始学 Web 之 Vue.js(一)Vue.js概述,基本结构,指令,事件修饰符,样式

在这里我会从 Web 前端零基础开始,一步步学习 Web 相关的知识点,期间也会分享一些好玩的项目。现在就让我们一起进入 Web 前端学习的冒险之旅吧!

682
来自专栏互联网杂技

h5新功能data-*,好好利用,还能做数据双向绑定

标题是data-,但是这里主要讲伪元素,看明白就知道了 1、jQuery Selectors 获取伪元素的属性值 虽然JS里没有可以直接操作伪元素的选择符,然而...

2654
来自专栏老马寒门IT

03-Vue入门系列之Vue列表渲染及条件渲染实战

3.1. 条件渲染 有时候我们要根据数据的情况,决定标签是否进行显示或者有其他动作。最常见的就是,表格渲染的时候,如果表格没有数据,就显示无数据。如果有数据就显...

2168
来自专栏IMWeb前端团队

react diff 原理

本文作者:IMWeb 王少飞 原文出处:IMWeb社区 未经同意,禁止转载 React diff 作为Virtual DOM的加速器,其算法上的改进优...

1956
来自专栏前端侠2.0

dragenter 和 dragleave 原

今天在做一个文件上传的功能!其它主要功能都很容易实现,最后却卡在一个地方: 我希望文件拖到指定的区域后,该区域能加亮,背景变色一下,离开后恢复。DOM结构类似于...

554
来自专栏IMWeb前端团队

react组件性能优化探索实践

React本身就非常关注性能,其提供的虚拟DOM搭配上Diff算法,实现对DOM操作最小粒度的改变也是非常的高效。然而其组件渲染机制,也决定了在对组件进行更新时...

2167
来自专栏葡萄城控件技术团队

Mobile First! Wijmo 5 之 架构

本文就开发者关心的话题之一架构,展开叙述。 ? Wijmo 5是一组JavaScript控件,但是不要与Widgets混淆。在此前开发Wijmo的时候,我们能够...

20010
来自专栏大数据钻研

HTML5学习笔记(一)

1.什么是 HTML5? HTML5 将成为 HTML、XHTML 以及 HTML DOM 的新标准。 HTML 的上一个版本诞生于 1999 年。自从那以后,...

3285

扫码关注云+社区