《微信小程序七日谈》系列文章:javascript
本系列的文章并不是初学教程,而是笔者在具体开发过程当中遇到的问题以及部分解决方案。css
微信小程序自公布以来就被捧上了天,新闻一波接一波。一部分声音来自前端界,把小程序当成前端历史地位提高的一次革新;一部分声音来自app开发界,把小程序当成失业的助推器(摊手)。本文的目的不是讨论小程序的是或非,只是记录一下笔者在开发小程序过程当中一些收获和感想。html
有消息称第一批微信小程序在12月中下旬发布,在那以前,须要将已完成的小程序向腾讯提交审核。58到家看准了此次推广的机会,制定了小程序开发计划。笔者是主要开发者之一。前端
闲话少说,进入正题。vue
小程序号称使用前端技术开发接近native体验的webapp,微信提供了许多js和native交互的bridge API,同时将html/css进行改造,分别对应wxml和wxss。初见之时,看上去就是换个名字而已嘛,都是熟悉的技术,项目分分钟开发完成哈哈。而后就兴致勃勃的开始折腾,而后就...java
小程序官方文档至关“简洁”,以示例代码的形式很形象地说明了各模块的开发模式。可是示例代码以及文字描述并未将其中的细节彻底暴露出来,上手开发后才发现不少坑。web
wxss乍看上去就是css,名字类似,语法类似。但写起代码来真是痛苦的很,下面一一列出目前笔者遇到的问题。json
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的语法与vue.js有点类似,支持数据绑定以及部分模板逻辑。笔者目前在wxml开发中总结如下几点注意事项:
1> 使用wxml模板语法时只能使用部分js逻辑判断
或者也能够理解为只能使用如下几种逻辑:
因为wxml使用双花括号{{}}
做为数据绑定标识,因此被{{}}
包裹的逻辑语句不能出现花括号{}
,不然会报语法错误。好比:
<view>{{ Object.assign({},data,{isTrue: false})}}</view>
2> event handler的参数event
不支持访问DOM
小程序中不支持任何访问DOM的语法,由于它并非在浏览器环境下运行,因此document
、window
等浏览器暴露的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'}}"/>
其中indexTapHandler
是index.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,后续笔者会将遇到的问题和经验写出来,以供参考。