技术开发者怎么看微信小程序?值得一试,但……
作者 | 齐修
微信小程序就是一个类似 RN(React Native)的轮子,可以快速开发,有一定的适用场景,但是也有其局限性。
注:该结论是基于微信小程序的示例代码做的解读,可能存在谬误。
早先,看到很多「权威人士」说小程序是 Hybrid 模式。一度怀疑自己之前判断的准确性,担心误导别人,所以额外备注可能存在谬误。
目前来看,这篇文章的判断比大部分博客文章的判断都准确。
简单总结下观点:
- 微信小程序是原生应用,是 React Native 和 Weex 类似的模式。
- 微信小程序的生态除了官方提供的组件和 API,几乎没有其他的组件。所以部分看上去「复杂」的功能,开发起来真的很复杂。
- 微信小程序只能在微信中运行。
- 由于微信的限制,微信小程序的应用场景极度有限。
大家想知道微信小程序能干什么?对比服务号就知道了。比如订票、航旅信息、ToDo List、天气日历、星座、理财、实时点菜系统等,核心是低频但重要的需求。
而且,微信不允许分享(导流),不允许链接(导流或广告),所以想要靠微信朋友圈爆发的小机灵被彻底被浇灭了,媒体也不适合微信小程序。
此外,不得不吐槽一下微信和微信小程序:
1. 微信小程序的官方文档写得不完善,很多方面没有覆盖
- 如何定义一个组件。
- 无法使用 LESS 或者 SASS 之类的预编译。
- WXML 没得到主流编辑器的支持,导致开发速度偏慢。
2. 微信小程序的开发工具极不稳定
- 和 Shadowsocks 等 VPN 冲突。
- 经常无故卡死。
- 开发工具和真机表现偶尔会有差异。
- 有时候代码无故不生效,需要重启才行。
- 没有类似 HMR 的机制导致经常刷新。
- 调试工具不好用等等。
3. 微信小程序的生态和问答社区几乎为零
微信的生态为零,导致部分功能开发起来吃力,比如解析富文本。
微信的问答社区就更差了,遇到问题全靠猜,实在找不到办法就重启。
4. 微信小程序的应用场景太受限
这个和微信的一贯保守风格很像,或许以后会慢慢放开,慢慢期待吧。
以上观点是站在一个普通开发者的角度,对微信小程序的看法。相反,从微信角度出发,某些限制和规范的确很有必要。
希望大家客观对待微信小程序。
而本文主要针对微信小程序的示例代码进行分析,想告诉大家以下几件事:
- 微信小程序到底提供了什么?
- 开发微信小程序方便么?
- 微信小程序的具体适用场景?
最后,还自作主张地说了点对于微信小程序的个人观点。
微信小程序都提供了什么?
微信小程序主要为我们提供了两部分东西:底层 API 、组件。
不仅如此,微信小程序还引入新的文件格式。
1. 引入了新的文件格式
微信小程序并不是传统意义的 HTML 5 页面,微信定义了新的文件格式,然后对这些文件做编译解析。
所以,微信小程序是原生应用!是基于微信的原生应用!微信正式尝试做一个 OS(操作系统)!
微信小程序组件
上图是一个 wx-action-sheet 组件,文件应用了新的后缀。
其中,WXML 功能和 HTML 类似,WXSS 功能和 CSS 类似,JS 包含组件逻辑。这点是不是和 RN/Weex 很像?
2. 微信提供了一套基础组件库
微信为微信小程序提供了一套基础组件库,可以满足开发的基础开发需求,从而实现简单的快速开发。
至于这些基础组件支持多大程度的自定义,以及能否满足实际项目的需求,就留给后续开发者去体验吧。
基础组件库主要分为四类:
- 控件(controller)主要包括:
action-sheet
/button
/searchbar
/modal
/navigator
/drawer
- 表单(form)主要包括:
checkbox
/radio
/form
/selector
/switch
/slider
/input
/label
/picker
- 媒体(media)主要包括:
image
/audio
/video
- 视图(view)主要包括:
progress
/toast
/scroll-view
/text
/view
/mask
/icon
/spinner
/swiper
/slide-tab
嗯,不用介绍大家也都知道这些组件大概是什么功能了,几乎是每个 UI 组件库都必备的。
以后大家应该都基于这个组件库去开发具体的产品。
和 RN/Weex 不同的是,微信小程序多半只能基于微信提供的组件进行个性化封装,而不能基于系统组件进行个性化封装。
原因很简单,因为微信就是一个「系统」。
微信是一个「系统」
我们挑一个稍微复杂的 picker 组件示例来分析分析:
// wx-picker.wxml 文件
<view class="page">
<view class="page__hd">
<text class="page__title">picker</text>
<text class="page__desc">选择器</text>
</view>
<view class="page__bd">
<view class="section">
<view class="section__title">地区选择器</view>
<picker bindchange="bindPickerChange"
value="{{index}}"
range="{{array}}">
<view class="picker">
当前选择:{{array[index]}}
</view>
</picker>
</view>
<view class="section">
<view class="section__title">日期选择器</view>
<picker mode="date"
value="{{date}}"
start="2015-09-01"
end="2017-09-01"
bindchange="bindDateChange">
<view class="picker">
当前选择: {{date}}
</view>
</picker>
</view>
</view>
</view>
是的,所有的标签都是自定义标签,进一步佐证了微信小程序是原生应用。组件使用很简单,所以很适合快速开发。
// wx-picker.js 文件 Page({ data: { array:["中国","美国","巴西","日本"], index:0, date:"2016-09-01" }, bindPickerChange: function(e) { console.log('picker 发送选择改变,携带值为', e.detail.value) this.setData({ index: e.detail.value }) }, bindDateChange:function(e){ this.setData({ date:e.detail.value }) }, bindTimeChange:function(e){ this.setData({ time:e.detail.time }) } })
也很清晰,通过 this.setData
来设置属性,实现 action-sheet
的显示与隐藏切换。React 的感觉,连 API 都很像。
// wx-picker.wxss .picker{ padding: 13px; background-color: #FFFFFF; }
可以重新设置微信小程序的组件样式,和 CSS 很相似,轻量简洁。
3. 底层 API
没有提供底层 API 的基础组件库都是流氓库,有了底层 API 才能开发真正的原生应用,才能做更多丰富的功能。
其中底层 API 包括:
animation
/ backgronud-audio
/ canvas
/ download-file
/ file
/ get-location
/ get-network-type
/ get-system-info
/ get-user-info
/ image
/ login
/ navigation-bar-loading
/ navigator
/ on-accelerometer-change
/ on-compass-change
/ open-location
/ pull-down-refresh
/ request
/ request-payment
/ set-navigation-bar-title
/ storage
/ upload-file
/ voice
/ web-socket
从名字也能看出个大概,小程序提供了比较完整的 API,能够开发更丰富的功能和程序。
我们仍然挑一个稍微复杂点的、图片相关的 API 使用示例来分析分析:
// image.wxml 文件
<import src="../common/header.wxml" />
<import src="../common/footer.wxml" />
<view class="container">
<template is="header"
data="{{title: 'choose/previewImage'}}"/>
<view class="page-body">
<view class="page-body-wrapper">
<form bindsubmit="openLocation">
<view class="page-body-form">
<picker range="{{sourceType}}"
bindchange="sourceTypeChange"
value="{{sourceTypeIndex}}">
<view class="page-body-form-picker">
<view class="page-body-form-picker-key">
图片来源
</view>
<view class="page-body-form-picker-value">
{{sourceType[sourceTypeIndex]}}
</view>
</view>
</picker>
<picker range="{{sizeType}}"
bindchange="sizeTypeChange"
value="{{sizeTypeIndex}}">
<view class="page-body-form-picker">
<view class="page-body-form-picker-key">
图片质量
</view>
<view class="page-body-form-picker-value">
{{sizeType[sizeTypeIndex]}}
</view>
</view>
</picker>
<picker range="{{count}}"
bindchange="countChange"
value="{{countIndex}}">
<view class="page-body-form-picker"
style="border-bottom: none;">
<view class="page-body-form-picker-key">
数量限制
</view>
<view class="page-body-form-picker-value">
{{count[countIndex]}}
</view>
</view>
</picker>
</view>
<view class="images-wrapper">
<text class="images-text">请选择图片</text>
<view class="images-list">
<block wx:for-items="{{imageList}}"
wx:for-item="image">
<image src="{{image}}"
class="images-image"
data-src="{{image}}"
bindtap="previewImage"></image>
</block>
<image src="/image/plus.png"
class="images-image images-image-plus"
bindtap="chooseImage"></image>
</view>
</view>
</form>
</view>
</view>
<template is="footer" />
</view>
简单清晰 WXML,居然让选择图片及及预览实现起来这么简单。并且,可以通过简单的 template
语法来引入其他 WXML 文件。
// image.js 文件 var sourceType = [ ['camera'], ['album'], ['camera', 'album'] ] var sizeType = [ ['compressed'], ['original'], ['compressed', 'original'] ] Page({ data: { sourceTypeIndex: 0, sourceType: ['拍照', '相册', '拍照或相册'], sizeTypeIndex: 0, sizeType: ['压缩', '原图', '压缩或原图'], countIndex: 0, count: [1, 2, 3, 4, 5, 6, 7, 8, 9] }, sourceTypeChange: function (e) { this.setData({ sourceTypeIndex: e.detail.value }) }, sizeTypeChange: function (e) { this.setData({ sizeTypeIndex: e.detail.value }) }, countChange: function (e) { this.setData({ countIndex: e.detail.value }) }, chooseImage: function () { var that = this wx.chooseImage({ sourceType: sourceType[this.data.sourceTypeIndex], sizeType: sizeType[this.data.sizeTypeIndex], count: this.data.count[this.data.countIndex], success: function (res) { console.log(res) that.setData({ imageList: res.tempFilePaths }) } }) }, previewImage: function (e) { var current = e.target.dataset.src wx.previewImage({ current: current, urls: this.data.imageList }) } })
因为微信对这个 API 已经封装得很好了,所以使用起来只需要传入几个参数,绑定一下回调函数即可。
// image.css 文件 .images-wrapper { padding: 20rpx; background-color: #fff; margin-top: 20rpx; } .images-wrapper-text { font-size: 28rpx; } .images-list { display: flex; margin-top: 20rpx; flex-wrap: wrap; } .images-image { width: 150rpx; height: 150rpx; margin: 10rpx; } .images-image-plus { border: 1px solid #999; }
同样,样式表语法近似 CSS,从上面的 rpx 单位可以看出,这不是真正的 CSS,我猜测是 CSS 的子集,类似 RN。
开发微信小程序方便么?
1. 微信小程序的开发目录结构
WX 的开发目录结构也很清晰简单。
WX 目录结构
入口文件就是最外层的 app.jsapp.json
,app.wxss
。
app.js
提供了入口文件的一些初始化和绑定。app.json
提供了项目的结构和一些项目配置,微信之所以采用 app.json 的模式,声明项目需要加载的页面和组件,应该是为了方便实现云端编译打包然后下发到微信吧。app.wxss
就是样式啦。page
目录放你需要实现具体功能的页面。util
存放项目需要用到的一些工具函数。
// app.json { "pages": [ "page/component/component-pages/wx-picker/wx-picker", "page/API/image/image" ], "window": { "navigationBarTextStyle": "black", "navigationBarTitleText": "小程序演示", "navigationBarBackgroundColor": "#fbf9fe", "backgroundColor": "#fbf9fe" }, "tabBar": { "color": "#dddddd", "selectedColor": "#3cc51f", "borderStyle": "black", "backgroundColor": "#ffffff", "list": [{ "pagePath": "page/component/index", "iconPath": "image/wechat.png", "selectedIconPath": "image/wechatHL.png", "text": "组件" }, { "pagePath": "page/API/index/index", "iconPath": "image/wechat.png", "selectedIconPath": "image/wechatHL.png", "text": "接口" }] }, "networkTimeout": { "request": 10000, "connectSocket": 10000, "uploadFile": 10000, "downloadFile": 10000 }, "debug": true }
2. 微信小程序的部署流程
微信小程序的整个开发与使用流程都在微信的体系中,所以安装和使用应该都很轻量。
微信采用云端编译打包的方式,将编译后的文件发送到微信上,接着,微信内置的解析器会解析并渲染这个文件。
简而言之,微信小程序的开发体验还算流畅,代码可读性也很高,也不需要做太多新的知识储备,但是有硬伤,后文会分析。
微信小程序适合你吗?
这一块就不细讲了,毕竟不是我擅长的,借用三节课的分析,用两张图片告诉你微信小程序的适用场景。
行业区分
微信小程序适合什么
所以,微信小程序更适合用来做低频高需的服务,比如酒店订阅,火车票/机票订阅,招聘,理财等。
总结点什么?
以下代表个人观点,仅供参考,也欢迎讨论。
从产品层面来说,值得一试!
- 微信提供了不错的底层 API 以及还算丰富的组件库,让小程序可以快速开发并且拥有原生体验,相对之前的公众号/服务号,体验更好;
- 微信流量很大,对于部分中小产品来说,是一次机会;
- 一些低频高需产品也许很适合,比如订票,用户打开页面,简单选择,然后微信支付,感觉还挺爽的。
从技术栈来说,我不喜欢!
- 微信小程序是基于微信生态的,而这个生态目前太不成熟;
- 只能在微信中运行,多半不支持在浏览器或者其他地方运行,也就是说,并没有减少产品的开发成本,反倒是多了一个开发流水线;
- 新的语法糖,开发调试环境也不友好,开发者会有阵痛期。
意淫一下,如果微信小程序的技术栈是 RN 而不是造一个轮子,那感觉才爽。
原文地址:微信小程序,一个有局限的类似 React Native 轮子!
本文由知晓程序授权转载,关注微信号 zxcx0101,回复「电商」获得电商类小程序的开发实战指南。
快速关注知晓程序↓↓↓
知晓程序 ( 微信号 zxcx0101)是爱范儿旗下专注于小程序生态的公众号。我们提供最全面、新鲜的小程序资讯 ( 消息、观点、指南、活动)和服务,在这里你能了解到关于小程序的一切。