微信小程序,一个有局限的类似 React Native 轮子!

PXYJod 8年前
   <p>先抛出结论:微信小程序就是一个类似RN的轮子,可以快速开发,有一定的适用场景,但是也有其局限性。</p>    <p>本文针对微信小程序的示例代码进行分析,告诉大家:</p>    <p>微信小程序到底提供了什么?</p>    <p>开发微信小程序方便么?</p>    <p>微信小程序具体适用场景?</p>    <p>最后还自作主张的说了点对于微信小程序的个人观点。</p>    <h2><strong>微信小程序都提供了什么?</strong></h2>    <p>微信小程序主要为我们提供了两部分东西:底层API 和 组件,不仅如此,微信小程序还引入新的文件格式。</p>    <p><strong>引入了新的文件格式</strong></p>    <p>微信小程序并不是传统意义的H5页面,微信定义了新的文件格式,然后对这些文件做编译解析,所以微信小程序是原生应用!是基于微信的原生应用!微信正式尝试做一个OS!</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/43150512b08231e7f5bd7461765376d8.png"></p>    <p>微信小程序组件</p>    <p>上图是一个wx-action-sheet组件,文件应用了新的后缀。</p>    <p>其中wxml功能和HTML类似,wxss功能和CSS类似,JS包含组件逻辑。这点是不是和RN/weex很像?</p>    <p><strong>微信提供了一套基础组件库</strong></p>    <p>微信为微信小程序提供了一套基础组件库,可以满足开发的基础开发需求,从而实现简单的快速开发,至于这些基础组件支持多大程度的自定义,以及能否满足实际项目的需求,留给后续开发者去体验吧。</p>    <p>基础组件库主要分为四类:</p>    <p>控件(controller) 主要包括:</p>    <p>action-sheet / button / searchbar / modal / navigator / drawer</p>    <p>表单(form) 主要包括:</p>    <p>checkbox / radio / form , selector / switch / slider / input / label / picker</p>    <p>媒体(media) 主要包括:</p>    <p>image / audio / video</p>    <p>视图(view) 主要包括:</p>    <p>progress / toast / scroll-view / text / view / mask / icon / spinner / swiper / slide-tab</p>    <p>恩,这些组件不用介绍大家也都知道大概是什么功能了,几乎是每个UI组件库都必备的。以后大家应该都要基于这个组件库去开发具体的产品,和RN/weex不同的是,WX应该只能基于微信提供的组件进行个性化封装了,而不能基于系统组件进行个性化封装,原因很简单,因为微信就是一个“系统”。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/3d17cec9d056995b61d2c5434cafd31d.png"></p>    <p>我们挑一个稍微复杂的组件示例来分析分析:</p>    <pre>  <code class="language-javascript">// 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></code></pre>    <p>是的,所有的标签都是自定义标签,进一步正式了微信小程序应该是原生应用,组件使用很简单,所以适合快速开发。</p>    <pre>  <code class="language-javascript">// 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      })    }  })</code></pre>    <p>也很清晰,通过this.setData来设置属性,实现action-sheet的显示与隐藏切换,React的感觉,连API都很像。</p>    <pre>  <code class="language-javascript">// wx-picker.wxss  .picker{      padding: 13px;      background-color: #FFFFFF;  }</code></pre>    <p>可以重新设置微信小程序的组件样式,和CSS很相似,轻量简洁。</p>    <p><strong>底层API</strong></p>    <p>没有提供底层API的基础组件库都是流氓库,有了底层API才能开发真正的原生应用,才能做更多丰富的功能。</p>    <p>其中底层API包括:</p>    <p>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</p>    <p>从名字也能看出大概,提供了比较完整的API,能够开发更丰富的功能和程序。</p>    <p>我们仍然挑一个稍微复杂点的API使用示例来分析分析:</p>    <pre>  <code class="language-javascript">// 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></code></pre>    <p>简单清晰wxml,居然让选择图片并预览实现起来这么简单。并且可以通过简单的template语法来引入其他wxml文件。</p>    <pre>  <code class="language-javascript">// 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      })    }  })</code></pre>    <p>因为微信对这个API已经封装得很好了,所以使用起来只需要传入几个参数,绑定一下回调函数即可。</p>    <pre>  <code class="language-javascript">// 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;  }</code></pre>    <p>同样,样式通过类似CSS的语法,从上面的rpx单位可以看出,这不是真正的CSS,我猜测是CSS的子集,类似RN。</p>    <h2><strong>开发微信小程序方便么?</strong></h2>    <p>微信小程序的开发目录结构</p>    <p>WX的开发目录结构也很清晰简单。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/e713eefb709f1ec355dd777d1b7820f6.png"></p>    <p style="text-align:center">WX目录结构</p>    <p>入口文件就是最外层的 app.js , app.json , app.wxss 。</p>    <p>app.js 提供了入口文件的一些初始化和绑定。</p>    <p>app.json 提供了项目的结构和一些项目配置,微信之所以采用app.json的模式声明项目需要加载的页面和组件,应该是为了方便实现云端编译打包然后下发到微信吧。</p>    <p>app.wxss 就是样式啦。</p>    <p>page目录 放你需要实现具体功能的页面。</p>    <p>util 存放项目需要用到的一些工具函数。</p>    <p><strong>微信小程序的部署流程</strong></p>    <p>微信小程序采用的基于微信的是原生开发,安装和使用应该都要很轻量,所以微信采用云端编译打包的方式,将编译后的文件发送到微信上,然后微信内置的解析器会解析这个文件并渲染。</p>    <p>简而言之,微信小程序的开发体验还算流畅,代码可读性也很高,也不需要做太多新的知识储备,但是有硬伤,后文会分析。</p>    <h2><strong>微信小程序适合你吗?</strong></h2>    <p>这一块就不细讲了,毕竟不是我擅长的,借用网上的分析,用两张图片告诉你微信小程序的适用场景。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/940a37b269dc241738e540466472e11b.png"></p>    <p>行业区分</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/4bce25a44140e95d0275d24cdcbeb9ec.png"></p>    <p>微信小程序适合什么</p>    <p>所以,微信小程序更适合用来做低频但重要的服务,比如酒店订阅,火车票/机票订阅,招聘,理财等。</p>    <h2><strong>总结点什么?</strong></h2>    <p>每次的总结都是为了更快的结束写文章的“枯燥”过程,也为了让大家更快的看到文章。</p>    <p>以下代表个人观点,仅供参考,也欢迎讨论。</p>    <p><strong>从产品层面来说,值得一试!</strong></p>    <ol>     <li>微信提供了不错的底层API以及还算丰富的组件库,让小程序可以快速开发并且拥有原生体验,相对之前的公众号/服务号,体验更好。</li>     <li>微信流量很大,对于部分中小产品来说,是一次机会。</li>     <li>一些不需要用户留存,但又是刚需的产品也许很适合,比如订票,用户打开页面,简单选择,然后微信支付,感觉还挺爽的。</li>    </ol>    <p><strong>从技术栈来说,我不喜欢!</strong></p>    <ol>     <li>微信小程序是基于微信生态的,而这个生态目前太不成熟。</li>     <li>只能在微信中运行,多半支持在浏览器或者其他地方运行,也就是说,并没有减少产品的开发成本,反倒是多了一个开发流水线。</li>     <li>新的语法糖,开发调试环境也不友好,开发者会有阵痛期。</li>    </ol>    <p>YY一下,如果微信小程序的技术栈是RN而不是造一个轮子,那感觉才爽!!</p>    <p> </p>    <p>来自:http://www.jianshu.com/p/060c6f3dd4e8</p>    <p> </p>