《微信小程序七日谈》系列文章:

  1. 第一天:人生若只如初见
  2. 第二天:你可能要抛弃原来的响应式开发思维
  3. 第三天:玩转Page组件的生命周期
  4. 第四天:页面路径最多五层?导航可以这么玩
  5. 第五天:你可能要在登录功能上花费大力气
  6. 第六天:小程序devtool隐藏的秘密;
  7. 第七天:不要捡了芝麻丢了西瓜

本系列的文章并非初学教程,而是笔者在具体开发过程中遇到的问题以及部分解决方案。

微信小程序自公布以来就被捧上了天,新闻一波接一波。一部分声音来自前端界,把小程序当成前端历史地位提升的一次革新;一部分声音来自app开发界,把小程序当成失业的助推器(摊手)。本文的目的不是讨论小程序的是或非,只是记录一下笔者在开发小程序过程中一些收获和感想。

有消息称第一批微信小程序在12月中下旬发布,在那之前,需要将已完成的小程序向腾讯提交审核。58到家看准了这次推广的机会,制定了小程序开发计划。笔者是主要开发者之一。

闲话少说,进入正题。

小程序号称使用前端技术开发接近native体验的webapp,微信提供了许多js和native交互的bridge API,同时将html/css进行改造,分别对应wxml和wxss。初见之时,看上去就是换个名字而已嘛,都是熟悉的技术,项目分分钟开发完成哈哈。然后就兴致勃勃的开始折腾,然后就...

小程序官方文档相当“简洁”,以示例代码的形式很形象地说明了各模块的开发模式。但是示例代码以及文字描述并未将其中的细节完全暴露出来,上手开发后才发现很多坑。

wxss

wxss乍看上去就是css,名字相似,语法相似。但写起代码来真是痛苦的很,下面一一列出目前笔者遇到的问题。

1> 不支持级联选择器

css选择器可以支持自上而下一层层的级联选择,比如:

.parent .child{
color: #000;
}

前端开发者对此非常熟悉。但是wxss并不支持上述语法,如果使用class作为匹配选择器,只能写一层,如下:

.parent{}
.child{
color: #000;
}

这种模式令开发者在为class命名上必须不能重复,限制了自由度。

注意:目前最新版的小程序已经支持级联选择器。

2> 选择器支持非常有限

目前官方给出的wxss支持选择器只有以下几种:

其中的element是wxml支持的标签元素,并非所有html标签。

3> 不支持引用本地图片资源

比如我们需要使用本地的sprites图片:

.dj__icon {
background-image; url("./assets/icons.sprites.png");
}

如果在wxss中编写以上代码并不会报错,但是也不会有任何理想的效果。官方给出的答复是:

所以如果我们需要使用自定义的图标UI的话,目前只能先将sprites图片上传到自己的服务器或者base64编译后再写入wxss中。

wxml

wxml的语法与vue.js有点相似,支持数据绑定以及部分模板逻辑。笔者目前在wxml开发中总结以下几点注意事项:

**1> 使用wxml模板语法时只能使用部分js逻辑判断 **

或者也可以理解为只能使用以下几种逻辑:

  • 引用变量;
  • 二元操作符;
  • 三元操作符。

由于wxml使用双花括号{{}}作为数据绑定标识,所以被{{}}包裹的逻辑语句不能出现花括号{},否则会报语法错误。比如:

<view>{{ Object.assign({},data,{isTrue: false})}}</view>

2> event handler的参数event不支持访问DOM

小程序中不支持任何访问DOM的语法,因为它并不是在浏览器环境下运行,所以documentwindow等浏览器暴露的API均不能访问。事件响应函数接受的event参数的完整结构如下:

{
"type":"tap",
"timeStamp":895,
"target": {
"id": "tapTest",
"dataset": {
"hi":"WeChat"
}
},
"currentTarget": {
"id": "tapTest",
"dataset": {
"hi":"WeChat"
}
},
"detail": {
"x":53,
"y":14
},
"touches":[{
"identifier":0,
"pageX":53,
"pageY":14,
"clientX":53,
"clientY":14
}],
"changedTouches":[{
"identifier":0,
"pageX":53,
"pageY":14,
"clientX":53,
"clientY":14
}]
}

所以如果想使用常规浏览器环境下,通过event.target获取DOM是不可行的。只能通过操作数据来修改UI。

3> 使用剩余参数语法向模板传递对象格式的data

wxml支持模板引用以便开发通用组件,比如项目中存在item.wxml

<!-- item.wxml -->
<template name="item">
<text>{{text}}</text>
</template>

index.wxml 中引用了 item.wxml,就可以使用item模板:

<import src="item.wxml"/>
<template is="item" data="{{text: 'forbar'}}"/>

其中的data是向item.wxml传递的参数。如果要循环一个列表数据,列表中每个元素都是key-value格式且对应一个item的话,需要使用以下格式:

<import src="item.wxml"/>
<template is="item" wx:for="{{list}}" wx:for-item="item" data="{{..item}}"/>

上述代码将列表的每个元素整体传递给item.wxml,使用 data="{{..item}}"语法。当然,你也可以在data中添加其他数据,比如 data="{{..item, text:'forbar'}}"

3> 可将事件响应函数名称通过data传递给组件模板

组件对引用它的模板来说就是一个黑盒,外部不应该干涉组件的内部逻辑。如果想要组件响应某些操作并反馈外部定义的响应函数,可以将外部已定义的响应函数名称传给组件。

我们将上文的代码改造一下演示这个问题。比如item.wxml暴露了tap响应API:

<!-- item.wxml -->
<template name="item">
<text bindtap="{{tapHandler}}">{{text}}</text>
</template>

index.wxml中引入item组件并传递了tapHandler:

<import src="item.wxml"/>
<template is="item" data="{{text: 'forbar', tapHandler: 'indexTapHandler'}}"/>

其中indexTapHandlerindex.wxml对应的js中声明的响应函数:

Page({
indexTapHandler(e){
alert('trigger index tap event');
}
});

这样就完成了组件事件响应的定制。

3> 可变数组数据渲染务必使用wx:key

渲染列表数据时,如果列表中的数据是动态的(比如点击之后修改列表中某个元素的值),那么在渲染UI时务必将渲染的模板加上wx:key。请看以下代码:

<import src="item.wxml"/>
<template is="item" wx:for="{{list}}" wx:for-item="item" wx:for-index="idx" wx:key="item-{{idx}}" data="{{..item}}"/>

上述代码使用列表的index作为wx:key的值,保证每个元素对应template的唯一性。

wx:key的取值还可以是保留字*this,官方给出的定义如下:

保留关键字 *this 代表在 for 循环中的 item 本身,这种表示需要 item 本身是一个唯一的字符串或者数字。

根据以上的解释,如果item本身是动态不唯一的,是不能使用*this作为wx:key取值的,否则会出现非常诡异的情况。

总结

第一天的开发感想就是:小程序并不像第一眼看上去那么美好,不能把小程序简单地理解为html+css+js。本文暂时不讨论小程序背后的运行原理,单纯出开发层面看,wxss相当于极度缩减版的css;wxml是mustache的简化版。至于js,后续笔者会将遇到的问题和经验写出来,以供参考。

《微信小程序七日谈》- 第一天:人生若只如初见的更多相关文章

  1. 《微信小程序七日谈》- 第四天:页面路径最多五层?导航可以这么玩

    <微信小程序七日谈>系列文章: 第一天:人生若只如初见: 第二天:你可能要抛弃原来的响应式开发思维: 第三天:玩转Page组件的生命周期: 第四天:页面路径最多五层?导航可以这么玩 微信小 ...

  2. 《微信小程序七日谈》- 第三天:玩转Page组件的生命周期

    <微信小程序七日谈>系列文章: 第一天:人生若只如初见: 第二天:你可能要抛弃原来的响应式开发思维: 第三天:玩转Page组件的生命周期: 第四天:页面路径最多五层?导航可以这么玩 前两篇 ...

  3. 《微信小程序七日谈》- 第二天:你可能要抛弃原来的响应式开发思维

    <微信小程序七日谈>系列文章: 第一天:人生若只如初见: 第二天:你可能要抛弃原来的响应式开发思维: 第三天:玩转Page组件的生命周期: 第四天:页面路径最多五层?导航可以这么玩 上篇文 ...

  4. 《微信小程序七日谈》- 第五天:你可能要在登录功能上花费大力气

    <微信小程序七日谈>系列文章: 第一天:人生若只如初见: 第二天:你可能要抛弃原来的响应式开发思维: 第三天:玩转Page组件的生命周期: 第四天:页面路径最多五层?导航可以这么玩: 第五 ...

  5. 《微信小程序七日谈》- 第六天:小程序devtool隐藏的秘密

    <微信小程序七日谈>系列文章: 第一天:人生若只如初见: 第二天:你可能要抛弃原来的响应式开发思维: 第三天:玩转Page组件的生命周期: 第四天:页面路径最多五层?导航可以这么玩: 第五 ...

  6. 《微信小程序七日谈》- 第七天:不要捡了芝麻丢了西瓜

    <微信小程序七日谈>系列文章: 第一天:人生若只如初见: 第二天:你可能要抛弃原来的响应式开发思维: 第三天:玩转Page组件的生命周期: 第四天:页面路径最多五层?导航可以这么玩: 第五 ...

  7. 微信小程序开发-第一弹

    前言:       本篇文章为大家详细介绍微信小程序开发第一篇,后续步骤会逐步更新,欢迎大家关注. 第一步  注册        1.1 打开网址 https://mp.weixin.qq.com/  ...

  8. 使用wepy开发微信小程序商城第一篇:项目初始化

    使用wepy开发微信小程序商城 第一篇:项目初始化 前言: wepy小程序项目初始化的操作,官方文档看了好几遍,感觉写得不是很清楚. 这篇写得挺好的:小程序开发之wepy 1.初始化项目 (1)全局安 ...

  9. 微信小程序自学第一课:工程目录结构与.json文件配置

    注册成为开发者 地址: https://mp.weixin.qq.com/cgi-bin/wx 开发者工具下载地址 https://mp.weixin.qq.com/debug/wxadoc/dev/ ...

随机推荐

  1. 解决真机调试时Eclipse DDMS上打不开/data目录的问题

    一般真机调试时DDMS里面的File Explorer是不能打开/data 目录的,不过也很容易解决. 1.首先手机要root.这个很简单,网上一大堆资料和软件. 2.仅仅root之后还不行,下载一个 ...

  2. jinkins在windows上的安装 配置C#编译

    首先jinkins在windows上的安装就不说,安装只需要下载相应安装包就可以了,后有些时候经常需要修改端口号.修改如下: 然后重启jenkins服务 首次运行界面 个人建议插件按需安装. 建立一个 ...

  3. Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法

    一.开篇 这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能.所以在出来数据库方言的时候基 ...

  4. 国内市场上 Android 手机屏幕分辨率的比例情况如何?

    http://www.zhihu.com/question/19587205 根据友盟发布的<友盟国内Android数据报告>,前六名分别是: 800×480,32.4% 480×320, ...

  5. Django 源码小剖: Django ORM 查询管理器

    ORM 查询管理器 对于 ORM 定义: 对象关系映射, Object Relational Mapping, ORM, 是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换.从 ...

  6. Java基础集锦——利用Collections.sort方法对list排序

    要想对List进行排序,可以让实体对象实现Comparable接口,重写compareTo方法即可实现按某一属性排序,但是这种写法很单一,只能按照固定的一个属性排序,没变法变化.通过下面这种方法,可以 ...

  7. GCC 编译使用动态链接库 LD

    可以把当前路径加入 /etc/ld.so.conf中然后运行ldconfig,或者以当前路径为参数运行ldconfig 2.把当前路径加入环境变量LD_LIBRARY_PATH中3. 如果你觉得不会引 ...

  8. 在 sublime text 3 中添加 Emmet (ZenCoding)

    安装 Emmet 插件: 启动 Sublime Text 3,选择 Preferences>Package Control,点选 Package Control:Install Package: ...

  9. CLR via C# 提纲

    第I部分 CLR基础第1章 CLR的执行模型 31.1 将源代码编译成托管模块 31.2 将托管模块合并成程序集 61.3 加载公共语言运行时 81.4 执行程序集的代码 101.4.1 IL和验证 ...

  10. javascript中apply()方法解析-简单易懂!

    今天看到了js的call与apply的异同,想着整理一下知识点,发现了一篇好文章,分享过来给大家,写的非常好! 参考: http://www.cnblogs.com/delin/archive/201 ...